diff --git a/docs/upgrading/v7.md b/docs/upgrading/v7.md
index 197d62883c..e6e8cec736 100644
--- a/docs/upgrading/v7.md
+++ b/docs/upgrading/v7.md
@@ -5,7 +5,7 @@ order: 2
# Upgrading from v7
-We try our best to keep major version upgrades simple and boring through the use of opt-in APIs and [Future Flags][api-development-strategy]. Future flags are used to gate breaking changes that don't otherwise have a good call-site opt-in strategy. By adopting all opt-in APIs and future flags, you should be able to upgrade to the next major version of React Router with minimal changes.
+We try our best to keep major version upgrades simple and boring through the use of opt-in APIs and [Future Flags][api-development-strategy]. Future flags are used to gate breaking changes that don't otherwise have a good call-site opt-in strategy. By adopting all opt-in APIs and future flags while still on v7, you should be able to update to React Router v8 with minimal changes.
We 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.
@@ -16,19 +16,19 @@ We highly recommend you make a commit after each step and ship it instead of doi
-React Router v8 requires the following minimum versions. You can prepare for the upgrade by updating them while still on v7:
+React Router v8 requires the following minimum versions. Update them before updating React Router to v8:
- `node@22.22+`
- `react@19.2.7+`/`react-dom@19.2.7+`
-Framework mode will also require:
+Framework mode also requires:
- `vite@7+` (requires `future.v8_viteEnvironmentApi`)
- also make sure any custom Vite plugins or config are compatible with Vite 7
## Update to latest v7.x
-Before adopting any future flags or call-site opt-in changes, you should update to the latest minor version of v7.x to make sure you have access to the latest flags. You may see a number of deprecation warnings as you upgrade, which we'll cover below.
+Before adopting any future flags or call-site opt-in changes, update to the latest minor version of v7.x to make sure you have access to the latest flags. You may see a number of deprecation warnings as you upgrade, which we'll cover below.
👉 Update to latest v7
@@ -243,7 +243,7 @@ export async function loader({
React 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.
-Currently, your HTTP and `request` pathnames would be as follows for `/a/b/c` and `/a/b/c/`
+In v7, your HTTP and `request` pathnames are as follows for `/a/b/c` and `/a/b/c/`
| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
| ------------ | ----------------- | ----------------------- |
@@ -255,7 +255,7 @@ Currently, your HTTP and `request` pathnames would be as follows for `/a/b/c` an
| **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
| **Data** | `/a/b/c.data` | `/a/b/c` ⚠️ |
-With this flag enabled, these pathnames will be made consistent though a new `_.data` format for client-side `.data` requests:
+With this flag enabled, these pathnames are made consistent through a new `_.data` format for client-side `.data` requests:
| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
| ------------ | ----------------- | ----------------------- |
@@ -285,11 +285,11 @@ export default {
If 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.
-## Other Planned Breaking Changes
+## Other Breaking Changes
-The changes in this section are not controlled by future flags, but you can update your code in v7 to be ready for v8.
+The changes in this section are not controlled by future flags, but you can update your code while still on v7 before moving to v8.
-### `meta` `data` Argument
+### `meta`/`matches` `data` Values
[MODES: framework]
@@ -298,7 +298,13 @@ The changes in this section are not controlled by future flags, but you can upda
**Background**
-The `data` fields passed to route module `meta` functions are deprecated and will be removed in React Router v8. Use `loaderData` instead on `MetaArgs` and each item in `MetaArgs.matches`.
+React Router v8 removed deprecated `data` fields in favor of `loaderData` in a few places:
+
+- `meta` function `data` argument
+- `meta` function `matches` argument (`matches[i].data`)
+- `useMatches()` (`matches[i].data`)
+
+Use `loaderData` instead on `MetaArgs`, each item in `MetaArgs.matches`, and each match returned from `useMatches()`
👉 **Update your Code**
@@ -331,6 +337,17 @@ export function meta({ matches }: Route.MetaArgs) {
}
```
+Replace `data` with `loaderData` on `useMatches()` calls:
+
+```diff
+export default function Component({ matches, loaderData }: ComponentProps) {
+ let matches = useMatches();
+- const rootLoaderData = matches[0].data;
++ const rootLoaderData = matches[0].loaderData;
+ // ...
+}
+```
+
### `react-router-dom`
[MODES: framework, data, declarative]
@@ -340,7 +357,7 @@ export function meta({ matches }: Route.MetaArgs) {
**Background**
-React Router v8 will remove the `react-router-dom` re-export package. In v8, you should import DOM-specific APIs from `react-router/dom` and everything else from `react-router`.
+React Router v8 removes the `react-router-dom` re-export package. In v8, you should import DOM-specific APIs from `react-router/dom` and everything else from `react-router`.
👉 **Update your Code**
@@ -373,7 +390,7 @@ For DOM-specific APIs, import from `react-router/dom`:
**Background**
-React Router v8 will remove the React Router Cloudflare dev proxy. Cloudflare projects should use [`@cloudflare/vite-plugin`][cloudflare-vite-plugin] instead.
+React Router v8 removes the React Router Cloudflare dev proxy. Cloudflare projects should use [`@cloudflare/vite-plugin`][cloudflare-vite-plugin] instead.
👉 **Update your Code**
@@ -403,11 +420,11 @@ export default defineConfig({
**Background**
-The `@react-router/architect` adapter currently uses `X-Forwarded-Host` when creating the `request`, falling back to the `Host` header. In React Router v8, the adapter will use `event.requestContext.domainName` by default, falling back to the `Host` header.
+In v7, the `@react-router/architect` adapter uses `X-Forwarded-Host` when creating the `request`, falling back to the `Host` header. In React Router v8, the adapter uses `event.requestContext.domainName` by default, falling back to the `Host` header.
👉 **Update your Code**
-Opt in to the v8 behavior now by passing `useRequestContextDomainName: true`:
+Opt in to the v8 behavior while still on v7 by passing `useRequestContextDomainName: true`:
```ts
import { createRequestHandler } from "@react-router/architect";
@@ -419,11 +436,11 @@ export const handler = createRequestHandler({
});
```
-This option will be removed in v8 once the `event.requestContext.domainName` behavior is the default.
+This option is removed in v8 because the `event.requestContext.domainName` behavior is the default.
## Upgrade to v8
-Now that your app is caught up, you can simply update to v8 (theoretically!) without issue.
+Now that your app is caught up, update to v8:
```shellscript nonumber
# data/declarative mode