react-router 8.5.0 → 8.5.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 (204) hide show
  1. package/CHANGELOG.md +44 -1
  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 +50 -396
  5. package/dist/development/index-react-server.js +43 -15
  6. package/dist/development/index.js +1 -1
  7. package/dist/development/lib/actions.js +1 -1
  8. package/dist/development/lib/await.js +58 -0
  9. package/dist/development/lib/components.d.ts +41 -5
  10. package/dist/development/lib/components.js +62 -4
  11. package/dist/development/lib/context.d.ts +2 -2
  12. package/dist/development/lib/context.js +1 -1
  13. package/dist/development/lib/dom/dom.js +1 -1
  14. package/dist/development/lib/dom/lib.js +1 -1
  15. package/dist/development/lib/dom/server.js +1 -1
  16. package/dist/development/lib/dom/ssr/components.js +1 -1
  17. package/dist/development/lib/dom/ssr/data.js +1 -1
  18. package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
  19. package/dist/development/lib/dom/ssr/fallback.js +1 -1
  20. package/dist/development/lib/dom/ssr/fog-of-war.js +12 -3
  21. package/dist/development/lib/dom/ssr/hydration.js +1 -1
  22. package/dist/development/lib/dom/ssr/invariant.js +1 -1
  23. package/dist/development/lib/dom/ssr/links.js +1 -1
  24. package/dist/development/lib/dom/ssr/markup.js +1 -1
  25. package/dist/development/lib/dom/ssr/route-discovery.d.ts +2 -2
  26. package/dist/development/lib/dom/ssr/route-discovery.js +3 -3
  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.js +1 -1
  31. package/dist/development/lib/dom/ssr/single-fetch.d.ts +1 -1
  32. package/dist/development/lib/dom/ssr/single-fetch.js +7 -7
  33. package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
  34. package/dist/development/lib/dom-export/hydrated-router.js +2 -2
  35. package/dist/development/lib/errors.js +1 -1
  36. package/dist/development/lib/hooks.d.ts +0 -3
  37. package/dist/development/lib/hooks.js +5 -6
  38. package/dist/development/lib/href.js +1 -1
  39. package/dist/development/lib/router/history.js +1 -1
  40. package/dist/development/lib/router/instrumentation.js +1 -1
  41. package/dist/development/lib/router/matcher-route-pattern.js +1 -1
  42. package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
  43. package/dist/development/lib/router/matcher.js +6 -1
  44. package/dist/development/lib/router/navigation.js +1 -1
  45. package/dist/development/lib/router/router.d.ts +2 -0
  46. package/dist/development/lib/router/router.js +58 -28
  47. package/dist/development/lib/router/url.js +1 -1
  48. package/dist/development/lib/router/utils.d.ts +7 -0
  49. package/dist/development/lib/router/utils.js +1 -1
  50. package/dist/development/lib/rsc/browser.js +3 -3
  51. package/dist/development/lib/rsc/errorBoundaries.js +1 -1
  52. package/dist/development/lib/rsc/html-stream/browser.js +1 -1
  53. package/dist/development/lib/rsc/html-stream/server.js +1 -1
  54. package/dist/development/lib/rsc/route-modules.js +1 -1
  55. package/dist/development/lib/rsc/server.ssr.js +1 -1
  56. package/dist/development/lib/server-runtime/cookies.js +1 -1
  57. package/dist/development/lib/server-runtime/crypto.js +1 -1
  58. package/dist/development/lib/server-runtime/data.js +1 -1
  59. package/dist/development/lib/server-runtime/dev.js +1 -1
  60. package/dist/development/lib/server-runtime/entry.js +1 -1
  61. package/dist/development/lib/server-runtime/errors.js +1 -1
  62. package/dist/development/lib/server-runtime/headers.js +1 -1
  63. package/dist/development/lib/server-runtime/invariant.js +1 -1
  64. package/dist/development/lib/server-runtime/mode.js +1 -1
  65. package/dist/development/lib/server-runtime/routeMatching.js +1 -1
  66. package/dist/development/lib/server-runtime/routes.js +1 -1
  67. package/dist/development/lib/server-runtime/server.js +13 -5
  68. package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
  69. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
  70. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
  71. package/dist/development/lib/server-runtime/sessions.js +2 -2
  72. package/dist/development/lib/server-runtime/single-fetch.js +1 -1
  73. package/dist/development/lib/server-runtime/urls.js +1 -1
  74. package/dist/development/lib/server-runtime/warnings.js +1 -1
  75. package/dist/development/lib/types/internal.js +1 -1
  76. package/dist/development/route-pattern.js +1 -1
  77. package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
  78. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  79. package/dist/development/vendor/turbo-stream-v2/unflatten.js +23 -3
  80. package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
  81. package/dist/production/dom-export.js +1 -1
  82. package/dist/production/index-react-server-client.js +1 -1
  83. package/dist/production/index-react-server.d.ts +50 -396
  84. package/dist/production/index-react-server.js +43 -15
  85. package/dist/production/index.js +1 -1
  86. package/dist/production/lib/actions.js +1 -1
  87. package/dist/production/lib/await.js +58 -0
  88. package/dist/production/lib/components.d.ts +41 -5
  89. package/dist/production/lib/components.js +62 -4
  90. package/dist/production/lib/context.d.ts +2 -2
  91. package/dist/production/lib/context.js +1 -1
  92. package/dist/production/lib/dom/dom.js +1 -1
  93. package/dist/production/lib/dom/lib.js +1 -1
  94. package/dist/production/lib/dom/server.js +1 -1
  95. package/dist/production/lib/dom/ssr/components.js +1 -1
  96. package/dist/production/lib/dom/ssr/data.js +1 -1
  97. package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
  98. package/dist/production/lib/dom/ssr/fallback.js +1 -1
  99. package/dist/production/lib/dom/ssr/fog-of-war.js +12 -3
  100. package/dist/production/lib/dom/ssr/hydration.js +1 -1
  101. package/dist/production/lib/dom/ssr/invariant.js +1 -1
  102. package/dist/production/lib/dom/ssr/links.js +1 -1
  103. package/dist/production/lib/dom/ssr/markup.js +1 -1
  104. package/dist/production/lib/dom/ssr/route-discovery.d.ts +2 -2
  105. package/dist/production/lib/dom/ssr/route-discovery.js +3 -3
  106. package/dist/production/lib/dom/ssr/routeModules.js +1 -1
  107. package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
  108. package/dist/production/lib/dom/ssr/routes.js +1 -1
  109. package/dist/production/lib/dom/ssr/server.js +1 -1
  110. package/dist/production/lib/dom/ssr/single-fetch.d.ts +1 -1
  111. package/dist/production/lib/dom/ssr/single-fetch.js +7 -7
  112. package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
  113. package/dist/production/lib/dom-export/hydrated-router.js +2 -2
  114. package/dist/production/lib/errors.js +1 -1
  115. package/dist/production/lib/hooks.d.ts +0 -3
  116. package/dist/production/lib/hooks.js +5 -6
  117. package/dist/production/lib/href.js +1 -1
  118. package/dist/production/lib/router/history.js +1 -1
  119. package/dist/production/lib/router/instrumentation.js +1 -1
  120. package/dist/production/lib/router/matcher-route-pattern.js +1 -1
  121. package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
  122. package/dist/production/lib/router/matcher.js +6 -1
  123. package/dist/production/lib/router/navigation.js +1 -1
  124. package/dist/production/lib/router/router.d.ts +2 -0
  125. package/dist/production/lib/router/router.js +58 -28
  126. package/dist/production/lib/router/url.js +1 -1
  127. package/dist/production/lib/router/utils.d.ts +7 -0
  128. package/dist/production/lib/router/utils.js +1 -1
  129. package/dist/production/lib/rsc/browser.js +3 -3
  130. package/dist/production/lib/rsc/errorBoundaries.js +1 -1
  131. package/dist/production/lib/rsc/html-stream/browser.js +1 -1
  132. package/dist/production/lib/rsc/html-stream/server.js +1 -1
  133. package/dist/production/lib/rsc/route-modules.js +1 -1
  134. package/dist/production/lib/rsc/server.ssr.js +1 -1
  135. package/dist/production/lib/server-runtime/cookies.js +1 -1
  136. package/dist/production/lib/server-runtime/crypto.js +1 -1
  137. package/dist/production/lib/server-runtime/data.js +1 -1
  138. package/dist/production/lib/server-runtime/dev.js +1 -1
  139. package/dist/production/lib/server-runtime/entry.js +1 -1
  140. package/dist/production/lib/server-runtime/errors.js +1 -1
  141. package/dist/production/lib/server-runtime/headers.js +1 -1
  142. package/dist/production/lib/server-runtime/invariant.js +1 -1
  143. package/dist/production/lib/server-runtime/mode.js +1 -1
  144. package/dist/production/lib/server-runtime/routeMatching.js +1 -1
  145. package/dist/production/lib/server-runtime/routes.js +1 -1
  146. package/dist/production/lib/server-runtime/server.js +13 -5
  147. package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
  148. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
  149. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
  150. package/dist/production/lib/server-runtime/sessions.js +2 -2
  151. package/dist/production/lib/server-runtime/single-fetch.js +1 -1
  152. package/dist/production/lib/server-runtime/urls.js +1 -1
  153. package/dist/production/lib/server-runtime/warnings.js +1 -1
  154. package/dist/production/lib/types/internal.js +1 -1
  155. package/dist/production/route-pattern.js +1 -1
  156. package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
  157. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
  158. package/dist/production/vendor/turbo-stream-v2/unflatten.js +23 -3
  159. package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
  160. package/docs/explanation/backend-for-frontend.md +0 -3
  161. package/docs/explanation/code-splitting.md +0 -3
  162. package/docs/explanation/concurrency.md +0 -3
  163. package/docs/explanation/hot-module-replacement.md +0 -3
  164. package/docs/explanation/lazy-route-discovery.md +0 -3
  165. package/docs/explanation/progressive-enhancement.md +0 -3
  166. package/docs/explanation/race-conditions.md +0 -3
  167. package/docs/explanation/react-transitions.md +0 -3
  168. package/docs/explanation/sessions-and-cookies.md +1 -1
  169. package/docs/explanation/state-management.md +0 -3
  170. package/docs/explanation/styling.md +0 -3
  171. package/docs/explanation/type-safety.md +0 -3
  172. package/docs/how-to/accessibility.md +0 -6
  173. package/docs/how-to/client-data.md +0 -3
  174. package/docs/how-to/data-strategy.md +0 -3
  175. package/docs/how-to/error-boundary.md +0 -3
  176. package/docs/how-to/error-reporting.md +0 -3
  177. package/docs/how-to/fetchers.md +0 -3
  178. package/docs/how-to/file-route-conventions.md +0 -3
  179. package/docs/how-to/file-uploads.md +0 -3
  180. package/docs/how-to/form-validation.md +0 -3
  181. package/docs/how-to/headers.md +0 -3
  182. package/docs/how-to/instrumentation.md +0 -3
  183. package/docs/how-to/middleware.md +6 -3
  184. package/docs/how-to/navigation-blocking.md +0 -3
  185. package/docs/how-to/optimize-revalidation.md +0 -3
  186. package/docs/how-to/pre-rendering.md +0 -3
  187. package/docs/how-to/presets.md +0 -3
  188. package/docs/how-to/react-server-components.md +0 -3
  189. package/docs/how-to/resource-routes.md +0 -3
  190. package/docs/how-to/route-discovery.md +4 -2
  191. package/docs/how-to/route-module-type-safety.md +0 -3
  192. package/docs/how-to/security.md +0 -3
  193. package/docs/how-to/server-bundles.md +0 -3
  194. package/docs/how-to/spa.md +0 -3
  195. package/docs/how-to/status.md +0 -3
  196. package/docs/how-to/suspense.md +22 -6
  197. package/docs/how-to/using-handle.md +0 -3
  198. package/docs/how-to/view-transitions.md +0 -3
  199. package/docs/start/framework/data-loading.md +9 -0
  200. package/docs/upgrading/future.md +0 -12
  201. package/docs/upgrading/v7.md +3 -33
  202. package/package.json +1 -1
  203. package/dist/development/lib/dom/global.d.ts +0 -35
  204. package/dist/production/lib/dom/global.d.ts +0 -35
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -50,6 +50,7 @@ function hydrate(index) {
50
50
  set(-0);
51
51
  continue;
52
52
  }
53
+ validateIndex(index, values.length);
53
54
  if (hydrated[index]) {
54
55
  set(hydrated[index]);
55
56
  continue;
@@ -121,11 +122,21 @@ function hydrate(index) {
121
122
  set(obj);
122
123
  continue;
123
124
  case "P":
125
+ validateIndex(b, values.length);
124
126
  if (hydrated[b]) set(hydrated[index] = hydrated[b]);
125
127
  else {
126
128
  const d = new Deferred();
129
+ const promise = d.promise;
130
+ promise.status = "pending";
131
+ promise.then((value) => {
132
+ promise.status = "fulfilled";
133
+ promise.value = value;
134
+ }, (reason) => {
135
+ promise.status = "rejected";
136
+ promise.reason = reason;
137
+ });
127
138
  deferred[b] = d;
128
- set(hydrated[index] = d.promise);
139
+ set(hydrated[index] = promise);
129
140
  }
130
141
  continue;
131
142
  case "E":
@@ -135,6 +146,7 @@ function hydrate(index) {
135
146
  set(error);
136
147
  continue;
137
148
  case "Z":
149
+ validateIndex(b, values.length);
138
150
  set(hydrated[index] = hydrated[b]);
139
151
  continue;
140
152
  default:
@@ -185,7 +197,12 @@ function hydrate(index) {
185
197
  r[0] = k;
186
198
  }]);
187
199
  postRun.push(() => {
188
- object[r[0]] = r[1];
200
+ Object.defineProperty(object, r[0], {
201
+ value: r[1],
202
+ enumerable: true,
203
+ configurable: true,
204
+ writable: true
205
+ });
189
206
  });
190
207
  }
191
208
  set(object);
@@ -195,5 +212,8 @@ function hydrate(index) {
195
212
  while (postRun.length > 0) postRun.pop()();
196
213
  return result;
197
214
  }
215
+ function validateIndex(index, length) {
216
+ if (!Number.isSafeInteger(index) || index < 0 || index >= length) throw new SyntaxError();
217
+ }
198
218
  //#endregion
199
219
  export { unflatten };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v8.5.0
2
+ * react-router v8.5.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -6,9 +6,6 @@ title: Backend For Frontend
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  While React Router can serve as your fullstack application, it also fits perfectly into the "Backend for Frontend" architecture.
13
10
 
14
11
  The BFF strategy employs a web server with a job scoped to serving the frontend web app and connecting it to the services it needs: your database, mailer, job queues, existing backend APIs (REST, GraphQL), etc. Instead of your UI integrating directly from the browser to these services, it connects to the BFF, and the BFF connects to your services.
@@ -6,9 +6,6 @@ title: Automatic Code Splitting
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  When using React Router's framework features, your application is automatically code split to improve the performance of initial load times when users visit your application.
13
10
 
14
11
  ## Code Splitting by Route
@@ -6,9 +6,6 @@ title: Network Concurrency Management
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  When building web applications, managing network requests can be a daunting task. The challenges of ensuring up-to-date data and handling simultaneous requests often lead to complex logic in the application to deal with interruptions and race conditions. React Router simplifies this process by automating network management while mirroring and expanding upon the intuitive behavior of web browsers.
13
10
 
14
11
  To help understand how React Router handles concurrency, it's important to remember that after `form` submissions, React Router will fetch fresh data from the `loader`s. This is called revalidation.
@@ -6,9 +6,6 @@ title: Hot Module Replacement
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Hot Module Replacement is a technique for updating modules in your app without needing to reload the page.
13
10
  It's a great developer experience, and React Router supports it when using Vite.
14
11
 
@@ -6,9 +6,6 @@ title: Lazy Route Discovery
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Lazy Route Discovery is a performance optimization that loads route information progressively as users navigate through your application, rather than loading the complete route manifest upfront.
13
10
 
14
11
  With Lazy Route Discovery enabled (the default), React Router sends only the routes needed for the initial server-side render in the manifest. As users navigate to new parts of your application, additional route information is fetched dynamically and added to the client-side manifest.
@@ -6,9 +6,6 @@ title: Progressive Enhancement
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  > Progressive enhancement is a strategy in web design that puts emphasis on web content first, allowing everyone to access the basic content and functionality of a web page, whilst users with additional browser features or faster Internet access receive the enhanced version instead.
13
10
  >
14
11
  > <cite>- [Wikipedia][wikipedia]</cite>
@@ -6,9 +6,6 @@ title: Race Conditions
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  While impossible to eliminate every possible race condition in your application, React Router automatically handles the most common race conditions found in web user interfaces.
13
10
 
14
11
  ## Browser Behavior
@@ -6,9 +6,6 @@ title: React Transitions
6
6
 
7
7
  [MODES: framework, data, declarative]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  [React 18][react-18] introduced the concept of "transitions" which allow you to differentiate urgent from non-urgent UI updates. To learn more about React Transitions and "concurrent rendering" Please refer to React's official documentation:
13
10
 
14
11
  - [What is Concurrent React][concurrent]
@@ -324,7 +324,7 @@ React Router makes it easy to store sessions in your own database if needed. The
324
324
  - `createData` will be called from `commitSession` on the initial session creation when no session ID exists in the cookie
325
325
  - `readData` will be called from `getSession` when a session ID exists in the cookie
326
326
  - `updateData` will be called from `commitSession` when a session ID already exists in the cookie
327
- - `deleteData` is called from `destroySession`
327
+ - `deleteData` is called from `destroySession` when the session has an ID
328
328
 
329
329
  The following example shows how you could do this using a generic database client:
330
330
 
@@ -6,9 +6,6 @@ title: State Management
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  State management in React typically involves maintaining a synchronized cache of server data on the client side. However, when using React Router as your framework, most of the traditional caching solutions become redundant because of how it inherently handles data synchronization.
13
10
 
14
11
  ## Understanding State Management in React
@@ -6,9 +6,6 @@ title: Styling
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Framework mode uses the React Router Vite plugin, so the styling story is mostly just Vite's styling story.
13
10
 
14
11
  React Router does not have a separate CSS pipeline for Framework mode. In practice, there are three patterns that matter:
@@ -6,9 +6,6 @@ title: Type Safety
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  If you haven't done so already, check out our guide for [setting up type safety][route-module-type-safety] in a new project.
13
10
 
14
11
  React Router generates types for each route in your app to provide type safety for the route module exports.
@@ -12,9 +12,6 @@ React Router makes certain accessibility practices the default where possible an
12
12
 
13
13
  [MODES: framework, data, declarative]
14
14
 
15
- <br/>
16
- <br/>
17
-
18
15
  The [`<Link>` component][link] renders a standard anchor tag, meaning that you get its accessibility behaviors from the browser for free!
19
16
 
20
17
  React Router also provides the [`<NavLink/>`][navlink] which behaves the same as `<Link>`, but it also provides context for assistive technology when the link points to the current page. This is useful for building navigation menus or breadcrumbs.
@@ -23,9 +20,6 @@ React Router also provides the [`<NavLink/>`][navlink] which behaves the same as
23
20
 
24
21
  [MODES: framework]
25
22
 
26
- <br/>
27
- <br/>
28
-
29
23
  If you are rendering [`<Scripts>`][scripts] in your app, there are some important things to consider to make client-side routing more accessible for your users.
30
24
 
31
25
  With a traditional multi-page website we don't have to think about route changes too much. Your app renders an anchor tag, and the browser handles the rest. If your users disable JavaScript, your React Router app should already work this way by default!
@@ -6,9 +6,6 @@ title: Client Data
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  You can fetch and mutate data directly in the browser using `clientLoader` and `clientAction` functions.
13
10
 
14
11
  These functions are the primary mechanism for data handling when using [SPA mode][spa]. This guide demonstrates common use cases for leveraging client data in Server-Side Rendering (SSR).
@@ -6,9 +6,6 @@ title: Data Strategy
6
6
 
7
7
  [MODES: data]
8
8
 
9
- <br />
10
- <br />
11
-
12
9
  <docs-warning>This is a low-level API intended for advanced use-cases. This overrides React Router's internal handling of `action`/`loader` execution, and if done incorrectly will break your app code. Please use with caution and perform the appropriate testing.</docs-warning>
13
10
 
14
11
  ## Overview
@@ -6,9 +6,6 @@ title: Error Boundaries
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  To avoid rendering an empty page to users, route modules will automatically catch errors in your code and render the closest `ErrorBoundary`.
13
10
 
14
11
  Error boundaries are not intended for rendering form validation errors or error reporting. Please see [Form Validation](./form-validation) and [Error Reporting](./error-reporting) instead.
@@ -6,9 +6,6 @@ title: Error Reporting
6
6
 
7
7
  [MODES: framework,data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  React Router catches errors in your route modules and sends them to [error boundaries](./error-boundary) to prevent blank pages when errors occur. However, `ErrorBoundary` isn't sufficient for logging and reporting errors.
13
10
 
14
11
  ## Server Errors
@@ -6,9 +6,6 @@ title: Using Fetchers
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Fetchers are useful for creating complex, dynamic user interfaces that require multiple, concurrent data interactions without causing a navigation.
13
10
 
14
11
  Fetchers track their own, independent state and can be used to load data, mutate data, submit forms, and generally interact with loaders and actions.
@@ -6,9 +6,6 @@ title: File Route Conventions
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  The `@react-router/fs-routes` package enables file-convention based route config.
13
10
 
14
11
  ## Setting up
@@ -6,9 +6,6 @@ title: File Uploads
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  _Thank you to David Adams for [writing an original guide](https://programmingarehard.com/2024/09/06/remix-file-uploads-updated.html/) on which this doc is based. You can refer to it for even more examples._
13
10
 
14
11
  ## Basic File Upload
@@ -6,9 +6,6 @@ title: Form Validation
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  This guide walks through a simple signup form implementation. You will likely want to pair these concepts with third-party validation libraries and error components, but this guide only focuses on the moving pieces for React Router.
13
10
 
14
11
  ## 1. Setting Up
@@ -6,9 +6,6 @@ title: HTTP Headers
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  ## Reading request headers
13
10
 
14
11
  The `request` sent to route handlers is a standard Web Fetch [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request), so you can read headers directly from the [`request.headers`](https://developer.mozilla.org/en-US/docs/Web/API/Request/headers) property:
@@ -6,9 +6,6 @@ title: Instrumentation
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Instrumentation allows you to add logging, error reporting, and performance tracing to your React Router application without modifying your actual route handlers. This enables comprehensive observability solutions for production applications on both the server and client.
13
10
 
14
11
  ## Overview
@@ -6,9 +6,6 @@ title: Middleware
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Middleware allows you to run code before and after the [`Response`][Response] generation for the matched path. This enables [common patterns][common-patterns] like authentication, logging, error handling, and data preprocessing in a reusable way.
13
10
 
14
11
  Middleware runs in a nested chain, executing from parent routes to child routes on the way "down" to your route handlers, then from child routes back to parent routes on the way "up" after a [`Response`][Response] is generated.
@@ -474,6 +471,12 @@ Which `ErrorBoundary` is rendered will differ based on whether your middleware t
474
471
 
475
472
  ### Authentication
476
473
 
474
+ Middleware on a protected route or a common ancestor can authenticate and authorize a request before the matched loaders and actions run.
475
+
476
+ Loaders run in parallel and can be requested independently, so parent loaders are not capable of "protecting" child route loaders or actions. Each protected loader and action must perform its own checks unless appropriate server middleware enforces them before the handler runs.
477
+
478
+ <docs-warning>Attach authorization middleware to the protected route or layout instead of gating its checks with literal pathname-prefix comparisons such as `url.pathname.startsWith("/admin")`. Literal checks may miss potential URL encodings that React Router route matching would cover.</docs-warning>
479
+
477
480
  ```tsx filename=app/middleware/auth.ts
478
481
  import { redirect } from "react-router";
479
482
  import { userContext } from "~/context";
@@ -6,9 +6,6 @@ title: Navigation Blocking
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  When users are in the middle of a workflow, like filling out an important form, you may want to prevent them from navigating away from the page.
13
10
 
14
11
  This example will show:
@@ -6,9 +6,6 @@ title: Revalidation Optimization
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  After a mutation or some navigations, React Router re-runs loaders so
13
10
  the UI stays in sync with the server. That default is the right
14
11
  starting point. When a loader is expensive, or a mutation cannot
@@ -6,9 +6,6 @@ title: Pre-Rendering
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Pre-Rendering allows you to speed up page loads for static content by rendering pages at build time instead of at runtime.
13
10
 
14
11
  ## Configuration
@@ -6,9 +6,6 @@ title: Presets
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  The [React Router config][react-router-config] supports a `presets` option to ease integration with other tools and hosting providers.
13
10
 
14
11
  [Presets][preset-type] can only do two things:
@@ -7,9 +7,6 @@ unstable: true
7
7
 
8
8
  [MODES: framework, data]
9
9
 
10
- <br/>
11
- <br/>
12
-
13
10
  <docs-warning>React Server Components support is experimental and subject to breaking changes in
14
11
  minor/patch releases. Please use with caution and pay **very** close attention
15
12
  to release notes for relevant changes.</docs-warning>
@@ -6,9 +6,6 @@ title: Resource Routes
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  When server rendering, routes can serve "resources" instead of rendering components, like images, PDFs, JSON payloads, webhooks, etc.
13
10
 
14
11
  ## Defining a Resource Route
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: Application-Controlled Route Discovery
2
+ title: Route Discovery
3
3
  unstable: true
4
4
  ---
5
5
 
6
- # Application-Controlled Route Discovery
6
+ # Route Discovery
7
7
 
8
8
  [MODES: framework]
9
9
 
@@ -21,6 +21,8 @@ export default {
21
21
 
22
22
  Without this flag, React Router keeps its existing discovery implementation and the hook is unavailable. The flag supports conventional Framework Mode only.
23
23
 
24
+ Enabling the flag does not require a custom implementation or a call to `unstable_useRouteDiscovery`. React Router continues to discover routes automatically and uses its built-in manifest-mismatch recovery unless you provide a custom `onManifestMismatch` handler.
25
+
24
26
  Keep `routeDiscovery.mode: "lazy"` (the default for SSR) and use `unstable_useRouteDiscovery` to choose when to discover destinations or load the complete route manifest.
25
27
 
26
28
  ```tsx
@@ -6,9 +6,6 @@ title: Route Module Type Safety
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  React Router generates route-specific types to power type inference for URL params, loader data, and more.
13
10
  This guide will help you set it up if you didn't start with a template.
14
11
 
@@ -6,9 +6,6 @@ title: Security
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  This is by no means a comprehensive guide, but React Router provides features to help address a few aspects under the _very large_ umbrella that is _Security_.
13
10
 
14
11
  ## `Content-Security-Policy`
@@ -6,9 +6,6 @@ title: Server Bundles
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  <docs-warning>This is an advanced feature designed for hosting provider integrations. When compiling your app into multiple server bundles, there will need to be a custom routing layer in front of your app directing requests to the correct bundle.</docs-warning>
13
10
 
14
11
  React Router typically builds your server code into a single bundle that exports a request handler function. However, there are scenarios where you might want to split your route tree into multiple server bundles, each exposing a request handler function for a subset of routes. To provide this flexibility, [`react-router.config.ts`][react-router-config] supports a `serverBundles` option, which is a function for assigning routes to different server bundles.
@@ -6,9 +6,6 @@ title: Single Page App (SPA)
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  <docs-info>This guide focuses on how to build Single Page Apps with React Router Framework mode. If you're using React Router in declarative or data mode, you can design your own SPA architecture.</docs-info>
13
10
 
14
11
  When using React Router as a framework, you can enable "SPA Mode" by setting `ssr:false` in your `react-router.config.ts` file. This will disable runtime server rendering and generate an `index.html` at build time that you can serve and hydrate as a SPA.
@@ -6,9 +6,6 @@ title: Status Codes
6
6
 
7
7
  [MODES: framework ,data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Set status codes from loaders and actions with `data`.
13
10
 
14
11
  ```tsx filename=app/project.tsx lines=[3,12-15,20,23]
@@ -6,9 +6,6 @@ title: Streaming with Suspense
6
6
 
7
7
  [MODES: framework, data]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Streaming with React Suspense allows apps to speed up initial renders by deferring non-critical data and unblocking UI rendering.
13
10
 
14
11
  React Router supports React Suspense by returning promises from loaders and actions.
@@ -66,9 +63,28 @@ export default function MyComponent({
66
63
  }
67
64
  ```
68
65
 
69
- ## With React 19
66
+ ## Opt into React's `use()` API
67
+
68
+ <docs-warning>The `unstable_promise` prop is experimental and may change in minor or patch releases.</docs-warning>
69
+
70
+ Use `<Await unstable_promise>` instead of `<Await resolve>` to opt into `React.use` under the hood while keeping the Await API:
71
+
72
+ ```tsx
73
+ <React.Suspense fallback={<div>Loading...</div>}>
74
+ <Await
75
+ unstable_promise={nonCriticalData}
76
+ errorElement={<LoadingError />}
77
+ >
78
+ {(value) => <h3>Non critical value: {value}</h3>}
79
+ </Await>
80
+ </React.Suspense>
81
+ ```
82
+
83
+ This should largely behave the same as `<Await resolve>` while avoiding the legacy React Router promise tracking. Both support render-prop children, `useAsyncValue`, and `useAsyncError`. One notable difference with `unstable_promise` is that `errorElement` only handles promise rejections. Errors thrown while rendering children bubble to the nearest React error boundary.
84
+
85
+ ## Use React directly
70
86
 
71
- If you're using React 19, you can use `React.use` instead of `Await`, but you'll need to create a new component and pass the promise down to trigger the suspense fallback.
87
+ You can also read the promise directly with `React.use`. Pass it to a child component rendered inside `<React.Suspense>` so the boundary can display its fallback while the promise is pending.
72
88
 
73
89
  ```tsx
74
90
  <React.Suspense fallback={<div>Loading...</div>}>
@@ -94,7 +110,7 @@ export const streamTimeout = 10_000;
94
110
 
95
111
  ## Handling early rejections (Node)
96
112
 
97
- React Router waits for all loaders to settle (via `Promise.all`) before it begins streaming the response. Once streaming has started, React Router catches subsequent rejections of your streamed promises and surfaces them to your `<Await>` (or React 19 `React.use`) error UI.
113
+ React Router waits for all loaders to settle (via `Promise.all`) before it begins streaming the response. Once streaming has started, React Router catches subsequent rejections of your streamed promises and surfaces them to your `<Await>` (or `React.use`) error UI.
98
114
 
99
115
  However, if a streamed promise rejects _before_ all of the route's loaders have settled, React Router has not yet been able to attach a handler to it. In Node, an unhandled promise rejection will crash the process unless you have a top-level handler registered.
100
116
 
@@ -6,9 +6,6 @@ title: Using handle
6
6
 
7
7
  [MODES: framework]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  You can build dynamic UI elements like breadcrumbs based on your route hierarchy using the [`useMatches`][use-matches] hook and [`handle`][handle] route exports.
13
10
 
14
11
  ## Understanding the Basics
@@ -6,9 +6,6 @@ title: View Transitions
6
6
 
7
7
  [MODES: framework, data, declarative]
8
8
 
9
- <br/>
10
- <br/>
11
-
12
9
  Use React's [`<ViewTransition>`][react-view-transition] component to animate client-side navigations. This requires React and React DOM 19.3 or later.
13
10
 
14
11
  <docs-warning>
@@ -80,6 +80,14 @@ export default function Product({
80
80
 
81
81
  Note that the `loader` function is removed from client bundles so you can use server only APIs without worrying about them being included in the browser.
82
82
 
83
+ ### Authentication and Authorization
84
+
85
+ React Router runs matched route loaders in parallel and loaders can be requested independently, such as during fetcher calls or navigations that do not revalidate every matched route. Therefore it is not possible for a parent loader to "protect" child route loaders or actions via authentication checks.
86
+
87
+ Unless guarded by appropriate [server middleware][auth-middleware], each protected loader and action must authenticate the request and authorize access to the data or operation before proceeding. For example, checking that a user is signed in does not establish that they have permission to access the requested project.
88
+
89
+ Middleware on a protected route or a common ancestor can enforce shared checks before the protected loaders and actions run. Any permissions not enforced by that middleware must still be checked in the individual loader or action.
90
+
83
91
  ## Static Data Loading
84
92
 
85
93
  When pre-rendering, loaders are used to fetch data during the production build.
@@ -199,3 +207,4 @@ See also:
199
207
  [streaming]: ../../how-to/suspense
200
208
  [client-data]: ../../how-to/client-data
201
209
  [fetchers]: ../../how-to/fetchers#loading-data
210
+ [auth-middleware]: ../../how-to/middleware#authentication
@@ -17,9 +17,6 @@ We highly recommend you make a commit after each step and ship it instead of doi
17
17
 
18
18
  [MODES: framework, data, declarative]
19
19
 
20
- <br/>
21
- <br/>
22
-
23
20
  React Router v9 will require the following minimum versions (as of now). You can prepare for the upgrade by updating them while still on v8:
24
21
 
25
22
  - `node@24+`
@@ -50,9 +47,6 @@ We document some [unstable] flags here as a reference for folks contributing to
50
47
 
51
48
  [MODES: framework]
52
49
 
53
- <br/>
54
- <br/>
55
-
56
50
  **Background**
57
51
 
58
52
  Now that the Web Streams API is [stable](https://nodejs.org/docs/latest-v22.x/api/webstreams.html) in Node 22+, it's viable for React Router to use React's [`renderToReadableStream`](https://react.dev/reference/react-dom/server/renderToReadableStream) in the server entry.
@@ -83,9 +77,6 @@ No code changes are required. If your app has a custom `entry.server.tsx`, this
83
77
 
84
78
  [MODES: framework]
85
79
 
86
- <br/>
87
- <br/>
88
-
89
80
  **Background**
90
81
 
91
82
  This flag lets React Router provide Vite's dependency optimizer with the client entry file and route module files. This can improve dependency optimization in development, but the behavior is still experimental.
@@ -110,9 +101,6 @@ No code changes are required. If you run into dependency optimization issues aft
110
101
 
111
102
  [MODES: data]
112
103
 
113
- <br/>
114
- <br/>
115
-
116
104
  **Background**
117
105
 
118
106
  This flag opts Data Routers into a new (and vastly more efficient) route matcher