react-router 8.0.0-pre.0 → 8.0.0-pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/development/dom-export.js +1 -1
  3. package/dist/development/index-react-server-client.js +1 -1
  4. package/dist/development/index-react-server.d.ts +9 -2
  5. package/dist/development/index-react-server.js +91 -88
  6. package/dist/development/index.d.ts +1 -2
  7. package/dist/development/index.js +2 -3
  8. package/dist/development/lib/actions.js +6 -18
  9. package/dist/development/lib/components.d.ts +11 -3
  10. package/dist/development/lib/components.js +8 -2
  11. package/dist/development/lib/context.js +1 -1
  12. package/dist/development/lib/dom/dom.js +1 -1
  13. package/dist/development/lib/dom/lib.d.ts +12 -1
  14. package/dist/development/lib/dom/lib.js +18 -6
  15. package/dist/development/lib/dom/server.js +2 -2
  16. package/dist/development/lib/dom/ssr/components.d.ts +4 -2
  17. package/dist/development/lib/dom/ssr/components.js +13 -3
  18. package/dist/development/lib/dom/ssr/data.js +1 -1
  19. package/dist/development/lib/dom/ssr/entry.d.ts +1 -0
  20. package/dist/development/lib/dom/ssr/errorBoundaries.js +7 -3
  21. package/dist/development/lib/dom/ssr/fallback.js +8 -3
  22. package/dist/development/lib/dom/ssr/fog-of-war.js +12 -2
  23. package/dist/development/lib/dom/ssr/hydration.js +1 -1
  24. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  25. package/dist/development/lib/dom/ssr/links.js +1 -1
  26. package/dist/development/lib/dom/ssr/markup.js +1 -1
  27. package/dist/development/lib/dom/ssr/routeModules.js +1 -1
  28. package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
  29. package/dist/development/lib/dom/ssr/routes.js +1 -1
  30. package/dist/development/lib/dom/ssr/server.d.ts +4 -1
  31. package/dist/development/lib/dom/ssr/server.js +2 -1
  32. package/dist/development/lib/dom/ssr/single-fetch.js +2 -3
  33. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  34. package/dist/development/lib/dom-export/hydrated-router.d.ts +1 -1
  35. package/dist/development/lib/dom-export/hydrated-router.js +14 -17
  36. package/dist/development/lib/errors.js +1 -1
  37. package/dist/development/lib/hooks.js +6 -4
  38. package/dist/development/lib/href.js +1 -1
  39. package/dist/development/lib/router/history.js +3 -2
  40. package/dist/development/lib/router/instrumentation.js +1 -1
  41. package/dist/development/lib/router/links.d.ts +3 -2
  42. package/dist/development/lib/router/router.js +13 -6
  43. package/dist/development/lib/router/url.js +18 -0
  44. package/dist/development/lib/router/utils.d.ts +6 -0
  45. package/dist/development/lib/router/utils.js +27 -8
  46. package/dist/development/lib/rsc/browser.js +21 -17
  47. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  48. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  49. package/dist/development/lib/rsc/html-stream/server.js +1 -1
  50. package/dist/development/lib/rsc/route-modules.js +1 -1
  51. package/dist/development/lib/rsc/server.ssr.js +27 -11
  52. package/dist/development/lib/server-runtime/cookies.js +1 -1
  53. package/dist/development/lib/server-runtime/crypto.js +1 -1
  54. package/dist/development/lib/server-runtime/data.js +1 -1
  55. package/dist/development/lib/server-runtime/dev.js +1 -1
  56. package/dist/development/lib/server-runtime/entry.js +1 -1
  57. package/dist/development/lib/server-runtime/errors.js +2 -22
  58. package/dist/development/lib/server-runtime/headers.js +1 -1
  59. package/dist/development/lib/server-runtime/invariant.js +1 -1
  60. package/dist/development/lib/server-runtime/mode.js +1 -1
  61. package/dist/development/lib/server-runtime/routeMatching.js +1 -1
  62. package/dist/development/lib/server-runtime/routes.js +1 -1
  63. package/dist/development/lib/server-runtime/server.js +17 -23
  64. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  65. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  66. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  67. package/dist/development/lib/server-runtime/sessions.js +1 -1
  68. package/dist/development/lib/server-runtime/single-fetch.js +4 -4
  69. package/dist/development/lib/server-runtime/urls.js +2 -5
  70. package/dist/development/lib/server-runtime/warnings.js +1 -1
  71. package/dist/development/lib/types/internal.js +1 -1
  72. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  73. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +2 -1
  74. package/dist/development/vendor/turbo-stream-v2/unflatten.js +3 -2
  75. package/dist/development/vendor/turbo-stream-v2/utils.js +2 -10
  76. package/dist/production/dom-export.js +1 -1
  77. package/dist/production/index-react-server-client.js +1 -1
  78. package/dist/production/index-react-server.d.ts +9 -2
  79. package/dist/production/index-react-server.js +91 -88
  80. package/dist/production/index.d.ts +1 -2
  81. package/dist/production/index.js +2 -3
  82. package/dist/production/lib/actions.js +6 -18
  83. package/dist/production/lib/components.d.ts +11 -3
  84. package/dist/production/lib/components.js +8 -2
  85. package/dist/production/lib/context.js +1 -1
  86. package/dist/production/lib/dom/dom.js +1 -1
  87. package/dist/production/lib/dom/lib.d.ts +12 -1
  88. package/dist/production/lib/dom/lib.js +18 -6
  89. package/dist/production/lib/dom/server.js +2 -2
  90. package/dist/production/lib/dom/ssr/components.d.ts +4 -2
  91. package/dist/production/lib/dom/ssr/components.js +13 -3
  92. package/dist/production/lib/dom/ssr/data.js +1 -1
  93. package/dist/production/lib/dom/ssr/entry.d.ts +1 -0
  94. package/dist/production/lib/dom/ssr/errorBoundaries.js +7 -3
  95. package/dist/production/lib/dom/ssr/fallback.js +3 -1
  96. package/dist/production/lib/dom/ssr/fog-of-war.js +12 -2
  97. package/dist/production/lib/dom/ssr/hydration.js +1 -1
  98. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  99. package/dist/production/lib/dom/ssr/links.js +1 -1
  100. package/dist/production/lib/dom/ssr/markup.js +1 -1
  101. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  102. package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
  103. package/dist/production/lib/dom/ssr/routes.js +1 -1
  104. package/dist/production/lib/dom/ssr/server.d.ts +4 -1
  105. package/dist/production/lib/dom/ssr/server.js +2 -1
  106. package/dist/production/lib/dom/ssr/single-fetch.js +2 -3
  107. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  108. package/dist/production/lib/dom-export/hydrated-router.d.ts +1 -1
  109. package/dist/production/lib/dom-export/hydrated-router.js +14 -17
  110. package/dist/production/lib/errors.js +1 -1
  111. package/dist/production/lib/hooks.js +6 -4
  112. package/dist/production/lib/href.js +1 -1
  113. package/dist/production/lib/router/history.js +3 -2
  114. package/dist/production/lib/router/instrumentation.js +1 -1
  115. package/dist/production/lib/router/links.d.ts +3 -2
  116. package/dist/production/lib/router/router.js +13 -6
  117. package/dist/production/lib/router/url.js +18 -0
  118. package/dist/production/lib/router/utils.d.ts +6 -0
  119. package/dist/production/lib/router/utils.js +27 -8
  120. package/dist/production/lib/rsc/browser.js +21 -17
  121. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  122. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  123. package/dist/production/lib/rsc/html-stream/server.js +1 -1
  124. package/dist/production/lib/rsc/route-modules.js +1 -1
  125. package/dist/production/lib/rsc/server.ssr.js +27 -11
  126. package/dist/production/lib/server-runtime/cookies.js +1 -1
  127. package/dist/production/lib/server-runtime/crypto.js +1 -1
  128. package/dist/production/lib/server-runtime/data.js +1 -1
  129. package/dist/production/lib/server-runtime/dev.js +1 -1
  130. package/dist/production/lib/server-runtime/entry.js +1 -1
  131. package/dist/production/lib/server-runtime/errors.js +2 -22
  132. package/dist/production/lib/server-runtime/headers.js +1 -1
  133. package/dist/production/lib/server-runtime/invariant.js +1 -1
  134. package/dist/production/lib/server-runtime/mode.js +1 -1
  135. package/dist/production/lib/server-runtime/routeMatching.js +1 -1
  136. package/dist/production/lib/server-runtime/routes.js +1 -1
  137. package/dist/production/lib/server-runtime/server.js +17 -23
  138. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  139. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  140. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  141. package/dist/production/lib/server-runtime/sessions.js +1 -1
  142. package/dist/production/lib/server-runtime/single-fetch.js +4 -4
  143. package/dist/production/lib/server-runtime/urls.js +2 -5
  144. package/dist/production/lib/server-runtime/warnings.js +1 -1
  145. package/dist/production/lib/types/internal.js +1 -1
  146. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  147. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +2 -1
  148. package/dist/production/vendor/turbo-stream-v2/unflatten.js +3 -2
  149. package/dist/production/vendor/turbo-stream-v2/utils.js +2 -10
  150. package/docs/explanation/code-splitting.md +1 -1
  151. package/docs/explanation/index-query-param.md +2 -2
  152. package/docs/explanation/type-safety.md +1 -1
  153. package/docs/how-to/data-strategy.md +5 -5
  154. package/docs/how-to/error-reporting.md +10 -2
  155. package/docs/how-to/headers.md +2 -1
  156. package/docs/how-to/security.md +9 -7
  157. package/docs/start/data/installation.md +4 -0
  158. package/docs/start/data/route-object.md +20 -0
  159. package/docs/start/framework/actions.md +0 -1
  160. package/docs/start/framework/data-loading.md +1 -1
  161. package/docs/start/framework/deploying.md +4 -0
  162. package/docs/start/framework/installation.md +0 -1
  163. package/docs/upgrading/v6.md +3 -0
  164. package/package.json +2 -2
  165. package/dist/development/lib/dom/ssr/errors.d.ts +0 -7
  166. package/dist/development/lib/dom/ssr/errors.js +0 -36
  167. package/dist/production/lib/dom/ssr/errors.d.ts +0 -7
  168. package/dist/production/lib/dom/ssr/errors.js +0 -36
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,8 +8,9 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { ABSOLUTE_URL_REGEX } from "../router/url.js";
11
12
  import { createBrowserHistory, createHashHistory, createPath, invariant, warning } from "../router/history.js";
12
- import { ErrorResponseImpl, defaultMapRouteProperties, joinPaths, matchPath, parseToInfo, resolveTo, stripBasename } from "../router/utils.js";
13
+ import { ErrorResponseImpl, SUPPORTED_ERROR_TYPES, defaultMapRouteProperties, joinPaths, matchPath, parseToInfo, resolveTo, stripBasename } from "../router/utils.js";
13
14
  import { IDLE_FETCHER, createRouter } from "../router/router.js";
14
15
  import { DataRouterContext, DataRouterStateContext, FetchersContext, NavigationContext, RouteContext, ViewTransitionContext } from "../context.js";
15
16
  import { useBlocker, useHref, useLocation, useMatches, useNavigate, useNavigation, useResolvedPath, useRouteId } from "../hooks.js";
@@ -21,13 +22,17 @@ import * as React$1 from "react";
21
22
  //#region lib/dom/lib.tsx
22
23
  const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
23
24
  try {
24
- if (isBrowser) window.__reactRouterVersion = "8.0.0-pre.0";
25
+ if (isBrowser) window.__reactRouterVersion = "8.0.0-pre.1";
25
26
  } catch (e) {}
26
27
  /**
27
28
  * Create a new {@link DataRouter| data router} that manages the application
28
29
  * path via [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)
29
30
  * and [`history.replaceState`](https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState).
30
31
  *
32
+ * Data Routers should not be held in React state. You should create your router
33
+ * once outside of the React tree and pass it to {@link RouterProvider | `<RouterProvider>`}.
34
+ * You can use `patchRoutesOnNavigation` to add additional routes programmatically.
35
+ *
31
36
  * @public
32
37
  * @category Data Routers
33
38
  * @mode data
@@ -63,6 +68,10 @@ function createBrowserRouter(routes, opts) {
63
68
  * Create a new {@link DataRouter| data router} that manages the application
64
69
  * path via the URL [`hash`](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash).
65
70
  *
71
+ * Data Routers should not be held in React state. You should create your router
72
+ * once outside of the React tree and pass it to {@link RouterProvider | `<RouterProvider>`}.
73
+ * You can use `patchRoutesOnNavigation` to add additional routes programmatically.
74
+ *
66
75
  * @public
67
76
  * @category Data Routers
68
77
  * @mode data
@@ -108,7 +117,7 @@ function deserializeErrors(errors) {
108
117
  let serialized = {};
109
118
  for (let [key, val] of entries) if (val && val.__type === "RouteErrorResponse") serialized[key] = new ErrorResponseImpl(val.status, val.statusText, val.data, val.internal === true);
110
119
  else if (val && val.__type === "Error") {
111
- if (val.__subType) {
120
+ if (typeof val.__subType === "string" && SUPPORTED_ERROR_TYPES.includes(val.__subType)) {
112
121
  let ErrorConstructor = window[val.__subType];
113
122
  if (typeof ErrorConstructor === "function") try {
114
123
  let error = new ErrorConstructor(val.message);
@@ -244,7 +253,6 @@ function HistoryRouter({ basename, children, history, useTransitions }) {
244
253
  });
245
254
  }
246
255
  HistoryRouter.displayName = "unstable_HistoryRouter";
247
- const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
248
256
  /**
249
257
  * A progressively enhanced [`<a href>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a)
250
258
  * wrapper to enable navigation with client-side routing.
@@ -509,7 +517,10 @@ Form.displayName = "Form";
509
517
  * }
510
518
  * ```
511
519
  *
512
- * This component renders an inline `<script>` to prevent scroll flashing. The `nonce` prop will be passed down to the script tag to allow CSP nonce usage.
520
+ * This component renders an inline `<script>` to prevent scroll flashing. The
521
+ * `nonce` prop will be passed down to the script tag to allow CSP nonce usage.
522
+ * If not provided in Framework Mode, it will default to any
523
+ * {@link ServerRouter | `<ServerRouter nonce>`} prop.
513
524
  *
514
525
  * ```tsx
515
526
  * <ScrollRestoration nonce={cspNonce} />
@@ -554,6 +565,7 @@ function ScrollRestoration({ getKey, storageKey, ...props }) {
554
565
  sessionStorage.removeItem(storageKey);
555
566
  }
556
567
  }).toString();
568
+ if (props.nonce == null && remixContext?.nonce) props.nonce = remixContext.nonce;
557
569
  return /* @__PURE__ */ React$1.createElement("script", {
558
570
  ...props,
559
571
  suppressHydrationWarning: true,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { ABSOLUTE_URL_REGEX } from "../router/url.js";
11
12
  import { createPath, invariant, parsePath } from "../router/history.js";
12
13
  import { convertRoutesToDataRoutes, isRouteErrorResponse } from "../router/utils.js";
13
14
  import { IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION } from "../router/router.js";
@@ -296,6 +297,5 @@ function encodeLocation(to) {
296
297
  hash: encoded.hash
297
298
  };
298
299
  }
299
- const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
300
300
  //#endregion
301
301
  export { StaticRouter, StaticRouterProvider, createStaticRouter };
@@ -31,7 +31,8 @@ interface LinksProps {
31
31
  /**
32
32
  * A [`nonce`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce)
33
33
  * attribute to render on the [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)
34
- * element
34
+ * element. If not provided in Framework Mode, it will default to any
35
+ * {@link ServerRouter | `<ServerRouter nonce>`} prop.
35
36
  */
36
37
  nonce?: string | undefined;
37
38
  /**
@@ -154,7 +155,8 @@ type ScriptsProps = Omit<React$1.HTMLProps<HTMLScriptElement>, "async" | "childr
154
155
  /**
155
156
  * A [`nonce`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce)
156
157
  * attribute to render on the [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)
157
- * element
158
+ * element. If not provided in Framework Mode, it will default to any
159
+ * {@link ServerRouter | `<ServerRouter nonce>`} prop.
158
160
  */
159
161
  nonce?: string | undefined;
160
162
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -141,7 +141,7 @@ const CRITICAL_CSS_DATA_ATTRIBUTE = "data-react-router-critical-css";
141
141
  * tags
142
142
  */
143
143
  function Links({ nonce, crossOrigin }) {
144
- let { isSpaMode, manifest, routeModules, criticalCss } = useFrameworkContext();
144
+ let { isSpaMode, manifest, routeModules, criticalCss, nonce: contextNonce } = useFrameworkContext();
145
145
  let { errors, matches: routerMatches } = useDataRouterStateContext();
146
146
  let matches = getActiveMatches(routerMatches, errors, isSpaMode);
147
147
  let keyedLinks = React$1.useMemo(() => getKeyedLinksForMatches(matches, routeModules, manifest), [
@@ -149,6 +149,7 @@ function Links({ nonce, crossOrigin }) {
149
149
  routeModules,
150
150
  manifest
151
151
  ]);
152
+ if (nonce == null && contextNonce) nonce = contextNonce;
152
153
  return /* @__PURE__ */ React$1.createElement(React$1.Fragment, null, typeof criticalCss === "string" ? /* @__PURE__ */ React$1.createElement("style", {
153
154
  [CRITICAL_CSS_DATA_ATTRIBUTE]: "",
154
155
  nonce,
@@ -200,6 +201,7 @@ function Links({ nonce, crossOrigin }) {
200
201
  */
201
202
  function PrefetchPageLinks({ page, ...linkProps }) {
202
203
  let rsc = useIsRSCRouterContext();
204
+ let { nonce: contextNonce } = useFrameworkContext();
203
205
  let { router } = useDataRouterContext();
204
206
  let matches = React$1.useMemo(() => matchRoutes(router.routes, page, router.basename), [
205
207
  router.routes,
@@ -207,6 +209,10 @@ function PrefetchPageLinks({ page, ...linkProps }) {
207
209
  router.basename
208
210
  ]);
209
211
  if (!matches) return null;
212
+ if (linkProps.nonce == null && contextNonce) linkProps = {
213
+ ...linkProps,
214
+ nonce: contextNonce
215
+ };
210
216
  if (rsc) return /* @__PURE__ */ React$1.createElement(RSCPrefetchPageLinksImpl, {
211
217
  page,
212
218
  matches,
@@ -473,11 +479,15 @@ function setIsHydrated() {
473
479
  * tags
474
480
  */
475
481
  function Scripts(scriptProps) {
476
- let { manifest, serverHandoffString, isSpaMode, renderMeta, routeDiscovery, ssr } = useFrameworkContext();
482
+ let { manifest, serverHandoffString, isSpaMode, renderMeta, routeDiscovery, ssr, nonce: contextNonce } = useFrameworkContext();
477
483
  let { router, static: isStatic, staticContext } = useDataRouterContext();
478
484
  let { matches: routerMatches } = useDataRouterStateContext();
479
485
  let isRSCRouterContext = useIsRSCRouterContext();
480
486
  let enableFogOfWar = isFogOfWarEnabled(routeDiscovery, ssr);
487
+ if (scriptProps.nonce == null && contextNonce) scriptProps = {
488
+ ...scriptProps,
489
+ nonce: contextNonce
490
+ };
481
491
  if (renderMeta) renderMeta.didRenderScripts = true;
482
492
  let matches = getActiveMatches(routerMatches, null, isSpaMode);
483
493
  React$1.useEffect(() => {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -19,6 +19,7 @@ interface FrameworkContextObject {
19
19
  ssr: boolean;
20
20
  isSpaMode: boolean;
21
21
  routeDiscovery: ServerBuild["routeDiscovery"];
22
+ nonce?: string;
22
23
  serializeError?(error: Error): SerializedError;
23
24
  renderMeta?: {
24
25
  didRenderScripts?: boolean;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -45,12 +45,16 @@ var RemixErrorBoundary = class extends React$1.Component {
45
45
  * When app's don't provide a root level ErrorBoundary, we default to this.
46
46
  */
47
47
  function RemixRootDefaultErrorBoundary({ error, isOutsideRemixApp }) {
48
+ let { nonce } = useFrameworkContext();
48
49
  console.error(error);
49
- let heyDeveloper = /* @__PURE__ */ React$1.createElement("script", { dangerouslySetInnerHTML: { __html: `
50
+ let heyDeveloper = /* @__PURE__ */ React$1.createElement("script", {
51
+ nonce,
52
+ dangerouslySetInnerHTML: { __html: `
50
53
  console.log(
51
54
  "💿 Hey developer 👋. You can provide a way better UX than this when your app throws errors. Check out https://reactrouter.com/how-to/error-boundary for more information."
52
55
  );
53
- ` } });
56
+ ` }
57
+ });
54
58
  if (isRouteErrorResponse(error)) return /* @__PURE__ */ React$1.createElement(BoundaryShell, { title: "Unhandled Thrown Response!" }, /* @__PURE__ */ React$1.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), heyDeveloper);
55
59
  let errorInstance;
56
60
  if (error instanceof Error) errorInstance = error;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -9,20 +9,25 @@
9
9
  * @license MIT
10
10
  */
11
11
  import { BoundaryShell } from "./errorBoundaries.js";
12
+ import { useFrameworkContext } from "./components.js";
12
13
  import * as React$1 from "react";
13
14
  //#region lib/dom/ssr/fallback.tsx
14
15
  function RemixRootDefaultHydrateFallback() {
16
+ let { nonce } = useFrameworkContext();
15
17
  return /* @__PURE__ */ React$1.createElement(BoundaryShell, {
16
18
  title: "Loading...",
17
19
  renderScripts: true
18
- }, /* @__PURE__ */ React$1.createElement("script", { dangerouslySetInnerHTML: { __html: `
20
+ }, /* @__PURE__ */ React$1.createElement("script", {
21
+ nonce,
22
+ dangerouslySetInnerHTML: { __html: `
19
23
  console.log(
20
24
  "💿 Hey developer 👋. You can provide a way better UX than this " +
21
25
  "when your app is loading JS modules and/or running \`clientLoader\` " +
22
26
  "functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " +
23
27
  "for more information."
24
28
  );
25
- ` } }));
29
+ ` }
30
+ }));
26
31
  }
27
32
  //#endregion
28
33
  export { RemixRootDefaultHydrateFallback };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -17,6 +17,15 @@ const nextPaths = /* @__PURE__ */ new Set();
17
17
  const discoveredPathsMaxSize = 1e3;
18
18
  const discoveredPaths = /* @__PURE__ */ new Set();
19
19
  const URL_LIMIT = 7680;
20
+ function getPathsWithAncestors(paths) {
21
+ let result = /* @__PURE__ */ new Set();
22
+ paths.forEach((path) => {
23
+ if (!path.startsWith("/")) path = `/${path}`;
24
+ for (let i = 1; i < path.length; i++) if (path[i] === "/") result.add(path.slice(0, i));
25
+ result.add(path);
26
+ });
27
+ return Array.from(result);
28
+ }
20
29
  function isFogOfWarEnabled(routeDiscovery, ssr) {
21
30
  return routeDiscovery.mode === "lazy" && ssr === true;
22
31
  }
@@ -102,6 +111,7 @@ function getManifestPath(_manifestPath, basename) {
102
111
  }
103
112
  const MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
104
113
  async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) {
114
+ paths = getPathsWithAncestors(paths);
105
115
  const searchParams = new URLSearchParams();
106
116
  searchParams.set("paths", paths.sort().join(","));
107
117
  searchParams.set("version", manifest.version);
@@ -167,4 +177,4 @@ function debounce(callback, wait) {
167
177
  };
168
178
  }
169
179
  //#endregion
170
- export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, isFogOfWarEnabled, useFogOFWarDiscovery };
180
+ export { URL_LIMIT, getManifestPath, getPartialManifest, getPatchRoutesOnNavigationFunction, getPathsWithAncestors, isFogOfWarEnabled, useFogOFWarDiscovery };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -18,7 +18,10 @@ interface ServerRouterProps {
18
18
  url: string | URL;
19
19
  /**
20
20
  * An optional `nonce` for [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP)
21
- * compliance, used to allow inline scripts to run safely.
21
+ * compliance. This is applied to inline scripts rendered by React Router and
22
+ * used as the default for nonce-aware components such as {@link Links | `<Links>`},
23
+ * {@link Scripts | `<Scripts>`}, and {@link ScrollRestoration | `<ScrollRestoration>`}
24
+ * when they do not provide their own `nonce`.
22
25
  */
23
26
  nonce?: string;
24
27
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -50,6 +50,7 @@ function ServerRouter({ context, url, nonce }) {
50
50
  ssr: context.ssr,
51
51
  isSpaMode: context.isSpaMode,
52
52
  routeDiscovery: context.routeDiscovery,
53
+ nonce,
53
54
  serializeError: context.serializeError,
54
55
  renderMeta: context.renderMeta
55
56
  } }, /* @__PURE__ */ React$1.createElement(RemixErrorBoundary, { location: router.state.location }, /* @__PURE__ */ React$1.createElement(StaticRouterProvider, {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,11 +8,10 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { ErrorResponseImpl, data, isRouteErrorResponse, redirect } from "../../router/utils.js";
11
+ import { ErrorResponseImpl, SUPPORTED_ERROR_TYPES, data, isRouteErrorResponse, redirect } from "../../router/utils.js";
12
12
  import { isDataWithResponseInit, isResponse } from "../../router/router.js";
13
13
  import invariant from "./invariant.js";
14
14
  import { escapeHtml } from "./markup.js";
15
- import { SUPPORTED_ERROR_TYPES } from "../../../vendor/turbo-stream-v2/utils.js";
16
15
  import { decode } from "../../../vendor/turbo-stream-v2/turbo-stream.js";
17
16
  import { createRequestInit } from "./data.js";
18
17
  import * as React$1 from "react";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -80,7 +80,7 @@ interface HydratedRouterProps {
80
80
  * and is only present for render errors.
81
81
  *
82
82
  * ```tsx
83
- * <HydratedRouter onError=(error, info) => {
83
+ * <HydratedRouter onError={(error, info) => {
84
84
  * let { location, params, pattern, errorInfo } = info;
85
85
  * console.error(error, location, errorInfo);
86
86
  * reportToErrorService(error, location, errorInfo);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -11,7 +11,7 @@
11
11
  import { CRITICAL_CSS_DATA_ATTRIBUTE } from "../dom/ssr/components.js";
12
12
  import { RouterProvider as RouterProvider$1 } from "./dom-router-provider.js";
13
13
  import * as React$1 from "react";
14
- import { UNSAFE_FrameworkContext, UNSAFE_RemixErrorBoundary, UNSAFE_createBrowserHistory, UNSAFE_createClientRoutes, UNSAFE_createClientRoutesWithHMRRevalidationOptOut, UNSAFE_createRouter, UNSAFE_decodeViaTurboStream, UNSAFE_defaultMapRouteProperties, UNSAFE_deserializeErrors, UNSAFE_getHydrationData, UNSAFE_getPatchRoutesOnNavigationFunction, UNSAFE_getTurboStreamSingleFetchDataStrategy, UNSAFE_hydrationRouteProperties, UNSAFE_invariant, UNSAFE_useFogOFWarDiscovery } from "react-router";
14
+ import { UNSAFE_FrameworkContext, UNSAFE_RemixErrorBoundary, UNSAFE_createBrowserHistory, UNSAFE_createClientRoutes, UNSAFE_createClientRoutesWithHMRRevalidationOptOut, UNSAFE_createRouter, UNSAFE_decodeViaTurboStream, UNSAFE_defaultMapRouteProperties, UNSAFE_getHydrationData, UNSAFE_getPatchRoutesOnNavigationFunction, UNSAFE_getTurboStreamSingleFetchDataStrategy, UNSAFE_hydrationRouteProperties, UNSAFE_invariant, UNSAFE_useFogOFWarDiscovery } from "react-router";
15
15
  //#region lib/dom-export/hydrated-router.tsx
16
16
  let ssrInfo = null;
17
17
  let router = null;
@@ -57,21 +57,18 @@ function createHydratedRouter({ getContext, instrumentations }) {
57
57
  if (ssrInfo.context.isSpaMode) {
58
58
  let { loaderData } = ssrInfo.context.state;
59
59
  if (ssrInfo.manifest.routes.root?.hasLoader && loaderData && "root" in loaderData) hydrationData = { loaderData: { root: loaderData.root } };
60
- } else {
61
- hydrationData = UNSAFE_getHydrationData({
62
- state: ssrInfo.context.state,
63
- routes,
64
- getRouteInfo: (routeId) => ({
65
- clientLoader: ssrInfo.routeModules[routeId]?.clientLoader,
66
- hasLoader: ssrInfo.manifest.routes[routeId]?.hasLoader === true,
67
- hasHydrateFallback: ssrInfo.routeModules[routeId]?.HydrateFallback != null
68
- }),
69
- location: window.location,
70
- basename: window.__reactRouterContext?.basename,
71
- isSpaMode: ssrInfo.context.isSpaMode
72
- });
73
- if (hydrationData && hydrationData.errors) hydrationData.errors = UNSAFE_deserializeErrors(hydrationData.errors);
74
- }
60
+ } else hydrationData = UNSAFE_getHydrationData({
61
+ state: ssrInfo.context.state,
62
+ routes,
63
+ getRouteInfo: (routeId) => ({
64
+ clientLoader: ssrInfo.routeModules[routeId]?.clientLoader,
65
+ hasLoader: ssrInfo.manifest.routes[routeId]?.hasLoader === true,
66
+ hasHydrateFallback: ssrInfo.routeModules[routeId]?.HydrateFallback != null
67
+ }),
68
+ location: window.location,
69
+ basename: window.__reactRouterContext?.basename,
70
+ isSpaMode: ssrInfo.context.isSpaMode
71
+ });
75
72
  if (window.history.state && window.history.state.masked) window.history.replaceState({
76
73
  ...window.history.state,
77
74
  masked: void 0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { invariant, parsePath, warning } from "./router/history.js";
12
12
  import { convertRouteMatchToUiMatch, decodePath, getResolveToMatches, getRoutePattern, isBrowser, isRouteErrorResponse, joinPaths, matchPath, matchRoutes, parseToInfo, resolveTo, stripBasename } from "./router/utils.js";
13
- import { IDLE_BLOCKER } from "./router/router.js";
13
+ import { IDLE_BLOCKER, hasInvalidProtocol } from "./router/router.js";
14
14
  import { AwaitContext, DataRouterContext, DataRouterStateContext, LocationContext, NavigationContext, RSCRouterContext, RouteContext, RouteErrorContext } from "./context.js";
15
15
  import { decodeRedirectErrorDigest, decodeRouteErrorResponseDigest } from "./errors.js";
16
16
  import * as React$1 from "react";
@@ -690,7 +690,9 @@ function RSCErrorHandler({ children, error }) {
690
690
  let existingRedirect = errorRedirectHandledMap.get(error);
691
691
  if (existingRedirect) throw existingRedirect;
692
692
  let parsed = parseToInfo(redirect.location, basename);
693
- if (isBrowser && !errorRedirectHandledMap.get(error)) if (parsed.isExternal || redirect.reloadDocument) window.location.href = parsed.absoluteURL || parsed.to;
693
+ let target = parsed.absoluteURL || parsed.to;
694
+ if (hasInvalidProtocol(target)) throw new Error("Invalid redirect location");
695
+ if (isBrowser && !errorRedirectHandledMap.get(error)) if (parsed.isExternal || redirect.reloadDocument) window.location.href = target;
694
696
  else {
695
697
  const redirectPromise = Promise.resolve().then(() => window.__reactRouterDataRouter.navigate(parsed.to, { replace: redirect.replace }));
696
698
  errorRedirectHandledMap.set(error, redirectPromise);
@@ -698,7 +700,7 @@ function RSCErrorHandler({ children, error }) {
698
700
  }
699
701
  return /* @__PURE__ */ React$1.createElement("meta", {
700
702
  httpEquiv: "refresh",
701
- content: `0;url=${parsed.absoluteURL || parsed.to}`
703
+ content: `0;url=${target}`
702
704
  });
703
705
  }
704
706
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { PROTOCOL_RELATIVE_URL_REGEX } from "./url.js";
11
12
  //#region lib/router/history.ts
12
13
  /**
13
14
  * Actions represent the type of change to a location value.
@@ -364,7 +365,7 @@ function createBrowserURLImpl(windowImpl, to, isAbsolute = false) {
364
365
  invariant(base, "No window.location.(origin|href) available to create URL");
365
366
  let href = typeof to === "string" ? to : createPath(to);
366
367
  href = href.replace(/ $/, "%20");
367
- if (!isAbsolute && href.startsWith("//")) href = base + href;
368
+ if (!isAbsolute && PROTOCOL_RELATIVE_URL_REGEX.test(href)) href = base + href;
368
369
  return new URL(href, base);
369
370
  }
370
371
  //#endregion
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -100,8 +100,9 @@ interface PageLinkDescriptor extends Omit<HtmlLinkDescriptor, "href" | "rel" | "
100
100
  /**
101
101
  * A [`nonce`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce)
102
102
  * attribute to render on the [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)
103
- * element
104
- */
103
+ * element. If not provided in Framework Mode, it will default to any
104
+ * {@link ServerRouter | `<ServerRouter nonce>`} prop.
105
+ */
105
106
  nonce?: string | undefined;
106
107
  /**
107
108
  * The absolute path of the page to prefetch, e.g. `/absolute/path`.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.0.0-pre.0
2
+ * react-router v8.0.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { PROTOCOL_RELATIVE_URL_REGEX, normalizeProtocolRelativeUrl } from "./url.js";
11
12
  import { createBrowserURLImpl, createLocation, createPath, invariant, parsePath, warning } from "./history.js";
12
13
  import { ErrorResponseImpl, RouterContextProvider, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, flattenAndRankRoutes, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, matchRoutesImpl, prependBasename, removeDoubleSlashes, resolveTo, stripBasename } from "./utils.js";
13
14
  import { getRouteInstrumentationUpdates, instrumentClientSideRouter } from "./instrumentation.js";
@@ -2572,17 +2573,23 @@ const invalidProtocols = [
2572
2573
  "filesystem:",
2573
2574
  "javascript:"
2574
2575
  ];
2576
+ function hasInvalidProtocol(location) {
2577
+ try {
2578
+ return invalidProtocols.includes(new URL(location).protocol);
2579
+ } catch {
2580
+ return false;
2581
+ }
2582
+ }
2575
2583
  function normalizeRedirectLocation(location, currentUrl, basename, historyInstance) {
2576
2584
  if (isAbsoluteUrl(location)) {
2577
2585
  let normalizedLocation = location;
2578
- let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation);
2579
- if (invalidProtocols.includes(url.protocol)) throw new Error("Invalid redirect location");
2586
+ let url = PROTOCOL_RELATIVE_URL_REGEX.test(normalizedLocation) ? new URL(normalizeProtocolRelativeUrl(normalizedLocation, currentUrl.protocol)) : new URL(normalizedLocation);
2587
+ if (hasInvalidProtocol(url.toString())) throw new Error("Invalid redirect location");
2580
2588
  let isSameBasename = stripBasename(url.pathname, basename) != null;
2581
2589
  if (url.origin === currentUrl.origin && isSameBasename) return removeDoubleSlashes(url.pathname) + url.search + url.hash;
2582
2590
  }
2583
2591
  try {
2584
- let url = historyInstance.createURL(location);
2585
- if (invalidProtocols.includes(url.protocol)) throw new Error("Invalid redirect location");
2592
+ if (hasInvalidProtocol(historyInstance.createURL(location).toString())) throw new Error("Invalid redirect location");
2586
2593
  } catch (e) {}
2587
2594
  return location;
2588
2595
  }
@@ -2978,4 +2985,4 @@ function createDeferred() {
2978
2985
  };
2979
2986
  }
2980
2987
  //#endregion
2981
- export { IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, createRouter, createStaticHandler, getStaticContextFromError, invalidProtocols, isDataWithResponseInit, isMutationMethod, isRedirectResponse, isRedirectStatusCode, isResponse };
2988
+ export { IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, createRouter, createStaticHandler, getStaticContextFromError, hasInvalidProtocol, isDataWithResponseInit, isMutationMethod, isRedirectResponse, isRedirectStatusCode, isResponse };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * react-router v8.0.0-pre.1
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ //#region lib/router/url.ts
12
+ const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i;
13
+ const PROTOCOL_RELATIVE_URL_REGEX = /^[\\/]{2}/;
14
+ function normalizeProtocolRelativeUrl(url, protocol) {
15
+ return protocol + url.replace(/\\/g, "/");
16
+ }
17
+ //#endregion
18
+ export { ABSOLUTE_URL_REGEX, PROTOCOL_RELATIVE_URL_REGEX, normalizeProtocolRelativeUrl };