UNPKG

10.1 kB Markdown View Raw
1---
2title: Future Flags
3order: 1
4---
5
6# Future Flags and Deprecations
7
8This guide walks you through the process of adopting future flags in your React Router app. By following this strategy, you will be able to upgrade to the next major version of React Router with minimal changes. To read more about future flags see [API Development Strategy][api-development-strategy].
9
10We highly recommend you make a commit after each step and ship it instead of doing everything all at once. Most flags can be adopted in any order, with exceptions noted below.
11
12## Update to latest v7.x
13
14First update to the latest minor version of v7.x to have the latest future flags. You may see a number of deprecation warnings as you upgrade, which we'll cover below.
15
16👉 Update to latest v7
17
18```sh
19npm install react-router@7 @react-router/{dev,node,etc.}@7
20```
21
22## `future.v8_middleware`
23
24[MODES: framework, data]
25
26<br/>
27<br/>
28
29**Background**
30
31Middleware allows you to run code before and after the [`Response`][Response] generation for the matched path. This enables common patterns like authentication, logging, error handling, and data preprocessing in a reusable way. Please see the [docs](../how-to/middleware) for more information.
32
33👉 **Enable the Flag**
34
35In Framework mode:
36
37```ts filename=react-router.config.ts
38import type { Config } from "@react-router/dev/config";
39
40export default {
41 future: {
42 v8_middleware: true,
43 },
44} satisfies Config;
45```
46
47In Data mode:
48
49```ts
50import { createBrowserRouter } from "react-router/dom";
51
52const router = createBrowserRouter(routes, {
53 future: {
54 v8_middleware: true,
55 },
56});
57```
58
59**Update your Code**
60
61If you're using the `context` parameter in `loader` and `action` functions, you may need to update your code:
62
63- In Framework mode, if you're using `react-router-serve`, you should not need to make any updates. Otherwise, this only applies if you have a custom server with a `getLoadContext` function. Please see the docs on the middleware [`getLoadContext` changes](../how-to/middleware#changes-to-getloadcontextapploadcontext) and the instructions to [migrate to the new API](../how-to/middleware#migration-from-apploadcontext).
64- In Data mode, add the `Future` module augmentation described in the [middleware docs](../how-to/middleware#1-typescript-augment-future-for-loaderaction-context) so `context` is typed correctly.
65
66## `future.v8_splitRouteModules`
67
68[MODES: framework]
69
70<br/>
71<br/>
72
73**Background**
74
75This feature enables splitting client-side route exports (`clientLoader`, `clientAction`, `clientMiddleware`, `HydrateFallback`) into separate chunks that can be loaded independently from the route component. This allows these exports to be fetched and executed while the component code is still downloading, improving performance for client-side data loading.
76
77This can be set to `true` for opt-in behavior, or `"enforce"` to require all routes to be splittable (which will cause build failures for routes that cannot be split due to shared code).
78
79👉 **Enable the Flag**
80
81```ts filename=react-router.config.ts
82import type { Config } from "@react-router/dev/config";
83
84export default {
85 future: {
86 v8_splitRouteModules: true,
87 },
88} satisfies Config;
89```
90
91**Update your Code**
92
93No code changes are required. This is an optimization feature that works automatically once enabled.
94
95## `future.v8_viteEnvironmentApi`
96
97[MODES: framework]
98
99<br/>
100<br/>
101
102**Background**
103
104This enables support for the experimental Vite Environment API, which provides a more flexible and powerful way to configure Vite environments. This is only available when using Vite 6+.
105
106👉 **Enable the Flag**
107
108```ts filename=react-router.config.ts
109import type { Config } from "@react-router/dev/config";
110
111export default {
112 future: {
113 v8_viteEnvironmentApi: true,
114 },
115} satisfies Config;
116```
117
118**Update your Code**
119
120Most users won't need to make any changes. However, if you have custom Vite configuration that previously relied on the `isSsrBuild` flag — such as a custom server build that sets `build.rollupOptions.input` — you'll need to move that configuration under the per-environment [Environment API][vite-environment] config instead.
121
122For example, a custom server build should move its SSR `rollupOptions` from the top-level `build` config into `environments.ssr.build`:
123
124```diff filename=vite.config.ts
125import { reactRouter } from "@react-router/dev/vite";
126import { defineConfig } from "vite";
127
128-export default defineConfig(({ isSsrBuild }) => ({
129- build: {
130- rollupOptions: isSsrBuild
131- ? {
132- input: "./server/app.ts",
133- }
134- : undefined,
135- },
136+export default defineConfig({
137+ environments: {
138+ ssr: {
139+ build: {
140+ rollupOptions: {
141+ input: "./server/app.ts",
142+ },
143+ },
144+ },
145+ },
146 plugins: [reactRouter()],
147-}));
148+});
149```
150
151See the [`node-custom-server` template][node-custom-server-template] for a complete example.
152
153## `future.v8_passThroughRequests`
154
155[MODES: framework]
156
157<br/>
158<br/>
159
160**Background**
161
162By default, React Router normalizes the `request.url` passed to your `loader`, `action`, and `middleware` functions by removing React Router's internal implementation details. Specifically, it removes `.data` suffixes and internal search parameters like `?index` and `?_routes`.
163
164This flag eliminates that normalization and passes the raw HTTP `request` instance to your handlers. This provides a few benefits:
165
166- Reduces server-side overhead by eliminating multiple `new Request()` calls on the critical path
167- Allows you to distinguish document from data requests in your handlers based on the presence of a `.data` suffix (useful for [observability] purposes)
168
169If you were previously relying on the normalization of `request.url`, you can switch to use the new sibling `url` parameter which contains a `URL` instance representing the normalized location.
170
171👉 **Enable the Flag**
172
173```ts filename=react-router.config.ts
174import type { Config } from "@react-router/dev/config";
175
176export default {
177 future: {
178 v8_passThroughRequests: true,
179 },
180} satisfies Config;
181```
182
183**Update your Code**
184
185If your code relies on inspecting the request URL, you should review it for any assumptions about the URL format:
186
187```tsx
188// ❌ Before: assuming no `.data` suffix in `request.url` pathname
189export async function loader({
190 request,
191}: Route.LoaderArgs) {
192 let url = new URL(request.url);
193 if (url.pathname === "/path") {
194 // This check might now behave differently because the request pathname will
195 // contain the `.data` suffix on data requests
196 }
197}
198
199// ✅ After: use `url` for normalized routing logic and `request.url`
200// for raw routing logic
201export async function loader({
202 request,
203 url,
204}: Route.LoaderArgs) {
205 if (url.pathname === "/path") {
206 // This will always have the `.data` suffix stripped
207 }
208
209 // And now you can distinguish between document versus data requests
210 let isDataRequest = new URL(
211 request.url,
212 ).pathname.endsWith(".data");
213}
214```
215
216## `future.v8_trailingSlashAwareDataRequests`
217
218[MODES: framework]
219
220<br/>
221<br/>
222
223**Background**
224
225React Router serves Framework mode data requests from `.data` URLs. Previously, data requests for routes with and without trailing slashes could map to the same `.data` URL because trailing slashes were not considered during URL generation. This flag preserves trailing slash semantics for data request URLs to avoid ambiguity when your app distinguishes between trailing-slash and non-trailing-slash URLs.
226
227Currently, your HTTP and `request` pathnames would be as follows for `/a/b/c` and `/a/b/c/`
228
229| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
230| ------------ | ----------------- | ----------------------- |
231| **Document** | `/a/b/c` | `/a/b/c` ✅ |
232| **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
233
234| URL `/a/b/c/` | **HTTP pathname** | **`request` pathname`** |
235| ------------- | ----------------- | ----------------------- |
236| **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
237| **Data** | `/a/b/c.data` | `/a/b/c` ⚠️ |
238
239With this flag enabled, these pathnames will be made consistent though a new `_.data` format for client-side `.data` requests:
240
241| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
242| ------------ | ----------------- | ----------------------- |
243| **Document** | `/a/b/c` | `/a/b/c` ✅ |
244| **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
245
246| URL `/a/b/c/` | **HTTP pathname** | **`request` pathname`** |
247| ------------- | ------------------ | ----------------------- |
248| **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
249| **Data** | `/a/b/c/_.data` ⬅️ | `/a/b/c/` ✅ |
250
251This flag also aligns the root data request to match this behavior by changing it from `/_root.data` to `/_.data`.
252
253👉 **Enable the Flag**
254
255```ts filename=react-router.config.ts
256import type { Config } from "@react-router/dev/config";
257
258export default {
259 future: {
260 v8_trailingSlashAwareDataRequests: true,
261 },
262} satisfies Config;
263```
264
265**Update your Code**
266
267If you have custom app, CDN, cache, or rewrite logic that matches `.data` request URLs, update it to handle the new trailing-slash-aware `/_.data` format.
268
269## Unstable Future Flags (Optional)
270
271We document some [unstable] flags here as a reference for folks contributing to the project via beta testing, but they are not generally recommended for production use and may having breaking changes patch/minor releases - adopt with caution!
272
273_No current unstable flags to document_
274
275[api-development-strategy]: ../community/api-development-strategy
276[unstable]: ../community/api-development-strategy#unstable-flags
277[observability]: ../how-to/instrumentation
278[Response]: https://developer.mozilla.org/en-US/docs/Web/API/Response
279[vite-environment]: https://vite.dev/guide/api-environment
280[node-custom-server-template]: https://github.com/remix-run/react-router-templates/blob/7c617a435510bc3add3a5395c07bc65328b65e9e/node-custom-server/vite.config.ts
281
\No newline at end of file