You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The v7 upgrade is non-breaking if you are caught up on all future flags. These flags allow you to update your app one change at a time. We highly recommend you make a commit after each step and ship it instead of doing everything all at once.
10
10
11
-
If you are current on all future flags in v6, the v7 upgrade is non-breaking.
11
+
## Update to latest v6.x
12
12
13
-
First update to the latest minor version of v6.x and then the console will warn you for any flags that you have not enabled.
13
+
First update to the latest minor version of v6.x to have the latest future flags and console warnings.
14
14
15
-
```tsx
16
-
exportinterfaceFutureConfig {
17
-
v7_fetcherPersist:boolean;
18
-
v7_normalizeFormMethod:boolean;
19
-
v7_partialHydration:boolean;
20
-
v7_prependBasename:boolean;
21
-
v7_relativeSplatPath:boolean;
22
-
v7_startTransition:boolean;
23
-
}
15
+
👉 **Update to latest v6**
16
+
17
+
```shellscript nonumber
18
+
npm install react-router-dom@6
24
19
```
25
20
26
-
Once you are caught up, you can simply update to the latest version of v7 (theoretically!) without issue.
21
+
### v7_relativeSplatPath
27
22
28
-
```shellscript nonumber
29
-
npm install react-router-dom@7
23
+
**Background**
24
+
25
+
Changes the relative path matching and linking for multi-segment splats paths like `dashboard/*` (vs. just `*`). [View the CHANGELOG](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md#minor-changes-2) for more information.
26
+
27
+
👉 **Enable the flag**
28
+
29
+
Enabling the flag depends on the type of router:
30
+
31
+
```tsx
32
+
<BrowserRouter
33
+
future={{
34
+
v7_relativeSplatPath: true,
35
+
}}
36
+
/>
30
37
```
31
38
32
-
## Bundler Plugins
39
+
```tsx
40
+
createBrowserRouter(routes, {
41
+
future: {
42
+
v7_relativeSplatPath: true,
43
+
},
44
+
});
45
+
```
33
46
34
-
The rest of this document is optional. It describes how to incrementally take advantage of the new features in v7 including
47
+
**Update your Code**
48
+
49
+
If you have any routes with a path + a splat like `<Route path="dashboard/*">` and has relative links like `<Link to="relative">` or `<Link to="../relative">` beneath it, you will need to update your code.
50
+
51
+
👉 **Split the `<Route>` into two**
52
+
53
+
Split any multi-segment splat `<Route>` into a parent route with the path and a child route with the splat:
Update any `<Link>` elements within that route tree to include the extra `..` relative segment to continue linking to the same place:
79
+
80
+
```diff
81
+
function Dashboard() {
82
+
return (
83
+
<div>
84
+
<h2>Dashboard</h2>
85
+
<nav>
86
+
- <Link to="/">Dashboard Home</Link>
87
+
- <Link to="team">Team</Link>
88
+
- <Link to="projects">Projects</Link>
89
+
+ <Link to="../">Dashboard Home</Link>
90
+
+ <Link to="../team">Team</Link>
91
+
+ <Link to="../projects">Projects</Link>
92
+
</nav>
93
+
94
+
<Routes>
95
+
<Route path="/" element={<DashboardHome />} />
96
+
<Route path="team" element={<DashboardTeam />} />
97
+
<Route
98
+
path="projects"
99
+
element={<DashboardProjects />}
100
+
/>
101
+
</Routes>
102
+
</div>
103
+
);
104
+
}
105
+
```
41
106
42
-
We encourage you to take these steps to set your app up for future React features with React Server Components and Server Actions.
107
+
### v7_startTransition
43
108
44
-
### Vite
109
+
**Background**
45
110
46
-
First install the ReactRouter vite plugin:
111
+
This uses `React.useTransition` instead of `React.useState` for Router state updates. View the [CHANGELOG](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7_starttransition) for more information.
47
112
48
-
```shellscript nonumber
49
-
npm install -D @react-router/vite
113
+
👉 **Enable the flag**
114
+
115
+
```tsx
116
+
<BrowserRouter
117
+
future={{
118
+
v7_startTransition: true,
119
+
}}
120
+
/>
121
+
122
+
// or
123
+
<RouterProvider
124
+
future={{
125
+
v7_startTransition: true,
126
+
}}
127
+
/>
50
128
```
51
129
52
-
Then swap out the React plugin for React Router. The `react` key accepts the same options as the React plugin.
130
+
👉 **Update your Code**
131
+
132
+
You don't need to update anything unless you are using `React.lazy`_inside_ of a component.
133
+
134
+
Using `React.lazy` inside of a component is incompatible with `React.useTransition` (or other code that makes promises inside of components). Move `React.lazy` to the module scope and stop making promises inside of components. This is not a limitation of React Router but rather incorrect usage of React.
53
135
54
-
```diff filename=vite.config.ts
55
-
-import react from '@vitejs/plugin-react'
56
-
+import { plugin as app } from "@react-router/vite";
57
-
import { defineConfig } from "vite";
136
+
### v7_fetcherPersist
58
137
138
+
<docs-warning>If you are not using a `createBrowserRouter` you can skip this</docs-warning>
59
139
60
-
export default defineConfig({
61
-
plugins: [
62
-
- react(reactOptions)
63
-
+ app({ react: reactOptions })
64
-
],
140
+
**Background**
141
+
142
+
The fetcher lifecycle is now based on when it returns to an idle state rather than when its owner component unmounts: [View the CHANGELOG](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#persistence-future-flag-futurev7_fetcherpersist) for more information.
143
+
144
+
**Enable the Flag**
145
+
146
+
```tsx
147
+
createBrowserRouter(routes, {
148
+
future: {
149
+
v7_fetcherPersist: true,
150
+
},
65
151
});
66
152
```
67
153
68
-
### Webpack
154
+
**Update your Code**
69
155
70
-
<docs-error>TODO: update this when we know exactly what it looks like</docs-error>
156
+
It's unlikely to affect your app. You may want to check any usage of `useFetchers` as they may persist longer than they did before. Depending on what you're doing, you may render something longer than before.
71
157
72
-
If you are using Webpack, you will need to update your Webpack config to use the React Router plugin.
158
+
### v7_normalizeFormMethod
73
159
74
-
```shellscript nonumber
75
-
npm install -D @react-router/webpack
76
-
```
160
+
<docs-warning>If you are not using a `createBrowserRouter` you can skip this</docs-warning>
This normalizes `formMethod` fields as uppercase HTTP methods to align with the `fetch()` behavior. [View the CHANGELOG](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#futurev7_normalizeformmethod) for more information.
84
163
85
-
### Create React App
164
+
👉 **Enable the Flag**
86
165
87
-
<docs-error>TODO: update this when we know exactly what it looks like</docs-error>
166
+
```tsx
167
+
createBrowserRouter(routes, {
168
+
future: {
169
+
v7_normalizeFormMethod: true,
170
+
},
171
+
});
172
+
```
88
173
89
-
- Eject and add the Webpack plugin
90
-
- Switch to Vite: https://www.robinwieruch.de/vite-create-react-app/
174
+
**Update your Code**
91
175
92
-
## Entry Points
176
+
If any of your code is checking for lowercase HTTP methods, you will need to update it to check for uppercase HTTP methods (or call `toLowerCase()` on it).
93
177
94
-
After configuring the bundler, you'll need to shuffle around your app's entry points.
178
+
👉 **Compare `formMethod`to UPPERCASE**
95
179
96
-
<docs-error>TODO: add more details here</docs-error>
180
+
```diff
181
+
-useNavigation().formMethod === "post"
182
+
-useFetcher().formMethod === "get";
183
+
+useNavigation().formMethod === "POST"
184
+
+useFetcher().formMethod === "GET";
185
+
```
97
186
98
-
- Move `index.html` template to `root.tsx`
99
-
- Move entry/root component to `root.tsx` and `entry.client.tsx`
187
+
### v7_partialHydration
100
188
101
-
## Enable SSR and Pre-rendering
189
+
<docs-warning>If you are not using a `createBrowserRouter` you can skip this</docs-warning>
102
190
103
-
If you want to enable server rendering and static pre-rendering, you can do so with the `ssr` and `prerender` options in the bundler plugin.
191
+
This allows SSR frameworks to provide only partial hydration data. It's unlikely you need to worry about this, just turn the flag on. [View the CHANGELOG](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#partial-hydration) for more information.
104
192
105
-
```ts filename=vite.config.ts
106
-
import { pluginasapp } from"@react-router/vite";
107
-
import { defineConfig } from"vite";
193
+
👉 **Enable the Flag**
108
194
109
-
exportdefaultdefineConfig({
110
-
plugins: [
111
-
app({
112
-
ssr: true,
113
-
async prerender() {
114
-
return ["/", "/about", "/contact"];
115
-
},
116
-
}),
117
-
],
195
+
```tsx
196
+
createBrowserRouter(routes, {
197
+
future: {
198
+
v7_partialHydration: true,
199
+
},
118
200
});
119
201
```
120
202
121
-
See [Deploying][deploying] for more information on deploying a server.
203
+
## Upgrade to v7
204
+
205
+
Now that your app is caught up, you can simply update to v7 (theoretically!) without issue.
122
206
123
-
## Route Modules
207
+
👉 **install v7**
124
208
125
-
You can incrementally migrate your routes to route modules.
209
+
```shellscript nonumber
210
+
npm install react-router-dom@7
211
+
```
126
212
127
-
First create a `routes.ts` file that exports your routes.
213
+
Your app should continue to work but you'll get console warnings for importing from "react-router-dom". In v7 you can import everything directly from `"react-router"`.
Instead of manually updating imports, you can use this command. Make sure your git working tree is clean though so you can revert if it doesn't work as expected.
0 commit comments