diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ef0eafb2d6..030777127e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -129,7 +129,7 @@ jobs:
run: pnpm build
- name: Publish to npm and create releases
- run: pnpm changes:publish -- --branch=${{ github.ref_name }}
+ run: pnpm changes:publish --branch=${{ github.ref_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b2055c192f..564b788e0d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,7 +16,16 @@ We manage release notes in this file instead of the paginated Github Releases Pa
Table of Contents
- [React Router Releases](#react-router-releases)
+ - [v8.0.0](#v800)
+ - [Baseline Support](#baseline-support)
+ - [Adopted Future Flag Behavior](#adopted-future-flag-behavior)
+ - [Removed `react-router-dom`](#removed-react-router-dom)
+ - [Removed deprecated `meta` `data` fields](#removed-deprecated-meta-data-fields)
+ - [Cloudflare Vite Plugin](#cloudflare-vite-plugin)
+ - [`@react-router/architect` `useRequestContextDomainName`](#react-routerarchitect-userequestcontextdomainname)
+- [React Router v7 Releases](#react-router-v7-releases)
- [v7.18.0](#v7180)
+ - [CSRF Check Logic Fix](#csrf-check-logic-fix)
- [v7.17.0](#v7170)
- [v7.16.0](#v7160)
- [v7.15.1](#v7151)
@@ -93,6 +102,182 @@ We manage release notes in this file instead of the paginated Github Releases Pa
+## v8.0.0
+
+Date: 2026-06-17
+
+### What's Changed
+
+React Router v8 is here!
+
+We introduced a new [Open Governance](https://remix.run/blog/rr-governance) model last year and this marks the first major release on our new planned yearly major release cadence. We chose the June timeframe this year to align with the EOL timeframe for Node 20. Node 22 is [scheduled](https://nodejs.org/en/about/previous-releases) to reach EOL in the May 2027 timeframe so we'll be aiming for a v9 release around the same time next year.
+
+Our [API Development Strategy](https://reactrouter.com/community/api-development-strategy) aims to make major releases relatively boring by introducing breaking changes ahead of time behind [Future Flags](https://reactrouter.com/upgrading/v7). If you've adopted all active future flags in v7, then from a React Router API surface you're in good shape for v8. All `future.v8_*` flags have been removed (or lifted to a top-level config) and their behaviors are now the default.
+
+#### Baseline Support
+
+React Router v8 updates the following minimum supported versions:
+
+- Node 22.22.0+
+ - Starting with v8, React Router will officially support all Active LTS node versions and only the **latest** minor branch of Maintenance LTS versions
+ - This better allows us to bump minimum Maintenance LTS versions to account for newly released security patches
+ - It also allows us to more quickly and easily adopt new Active LTS features backported to Maintenance LTS lines
+ - Upgraded minimum Maintenance LTS versions will be done in React Router minor releases
+- React 19.2.7+
+- Vite 7+
+
+To modernize the library, React Router is now published as an ESM-only module and tsconfig `target`/`lib` fields have been updated to ES2022 across the board
+
+#### Adopted Future Flag Behavior
+
+The following v8 future flags have been removed and their behaviors are now the default:
+
+- `future.v8_trailingSlashAwareDataRequests`
+- `future.v8_passThroughRequests`
+- `future.v8_middleware`
+- `future.v8_viteEnvironmentApi`
+- `future.v8_splitRouteModules` has been moved to a to a top-level `splitRouteModules` config option and is enabled by default
+
+#### Removed `react-router-dom`
+
+In v7, we collapsed the DOM APIs into `react-router/dom`, but to ease the v6->v7 upgrade we continued re-exporting everything through `react-router-dom`. We have now dropped `react-router-dom`, so if you didn't get around to swapping your imports in v7, you will need to swap them to `react-router` and `react-router/dom` for v8.
+
+#### Removed deprecated `meta` `data` fields
+
+The `data` fields passed to route module `meta` functions were deprecated in v7 and are remove din v8. Use `loaderData` instead of `data` on `MetaArgs` and each item in `MetaArgs.matches`.
+
+#### Cloudflare Vite Plugin
+
+The React Router Cloudflare dev proxy (`@react-router/dev/vite/cloudflare`) has been removed in v8. Cloudflare projects should use [`@cloudflare/vite-plugin`](https://developers.cloudflare.com/workers/vite-plugin/) instead.
+
+#### `@react-router/architect` `useRequestContextDomainName`
+
+The `@react-router/architect` `createRequestHandler` `useRequestContextDomainName` option has been removed as that is now the default behavior in v8.
+
+### Major Changes
+
+- `react-router` - Update minimum Node version to 22.22.0 ([#14928](https://github.com/remix-run/react-router/pull/14928))
+- `react-router` - Update minimum React version to 19.2.7 ([#15062](https://github.com/remix-run/react-router/pull/15062))
+- `react-router` - Remove the `future.v8_trailingSlashAwareDataRequests` flag ([#15100](https://github.com/remix-run/react-router/pull/15100))
+ - Trailing slash-aware data request URLs are now the default behavior.
+- `react-router` - Remove `future.v8_passThroughRequests` flag - the raw incoming `request` is now always passed through to `loader`/`action`. Use `url` for the normalized URL without React Router-specific implementation details (`.data` suffixes, `index`/`_routes` search params). ([#15079](https://github.com/remix-run/react-router/pull/15079))
+- `react-router` - Remove `future.v8_middleware` flag — middleware is always enabled in v8 ([#15078](https://github.com/remix-run/react-router/pull/15078))
+ - The `future.v8_middleware` flag has been removed; middleware is now always enabled
+ - The `context` parameter passed to `loader`, `action`, and `middleware` functions is always a `RouterContextProvider` instance
+ - `getLoadContext` functions in custom servers must return a `RouterContextProvider` — returning a plain object is no longer supported
+ - The `MiddlewareEnabled` type (previously exported as `UNSAFE_MiddlewareEnabled`) has been removed since the conditional it gated is now unconditional
+ - The `Future` module augmentation pattern (`interface Future { v8_middleware: true }`) is no longer needed to type `context` in Data Mode
+- `react-router` - Remove `future.v8_passThroughRequests` flag - the raw incoming `request` is now always passed through to `loader`/`action`. ([#15079](https://github.com/remix-run/react-router/pull/15079))
+- `react-router` - Move `future.v8_splitRouteModules` to a top-level `splitRouteModules` config option and change the default behavior to `true` ([#15086](https://github.com/remix-run/react-router/pull/15086))
+ - Set `splitRouteModules: false` to keep route modules in a single chunk
+ - Set `splitRouteModules: "enforce"` to require all routes to be splittable
+- `@react-router/dev` - Removed the `future.v8_viteEnvironmentApi` flag because the Vite Environment API is always enabled ([#15077](https://github.com/remix-run/react-router/pull/15077))
+- `@react-router/dev` - Removed the `future.unstable_previewServerPrerendering` flag and make prerendering with the Vite Environment API the default. ([#15077](https://github.com/remix-run/react-router/pull/15077))
+- `react-router` - Update `tsconfig.json` `target`/`lib` from `ES2020 -> ES2022` ([591853e](https://github.com/remix-run/react-router/commit/591853e))
+- `react-router` - Switch the published packages in `packages/` to ESM-only. ([#14895](https://github.com/remix-run/react-router/pull/14895)) ([59ebcf1](https://github.com/remix-run/react-router/commit/59ebcf1))
+- `react-router` - Remove deprecated `data` parameter in favor of `loaderData` for `meta` APIs (to align with `Route.ComponentProps`) ([#14931](https://github.com/remix-run/react-router/pull/14931))
+ - `Route.MetaArgs`, `Route.MetaMatch`, `MetaArgs`, `MetaMatch`, `Route.ComponentProps.matches`, `UIMatch`
+- `react-router` - Remove internal `hasErrorBoundary` field added to `router.routes` when using a data router ([#15074](https://github.com/remix-run/react-router/pull/15074))
+ - This should not impact user-facing code since this was an internal prop and was computed based on the presence of `ErrorBoundary` or `errorElement` on your route
+ - `hasErrorBoundary` is no longer accepted on `RouteObject` (`IndexRouteObject`/`NonIndexRouteObject`), `DataRouteObject`, `` JSX props, or as a key in `lazy` route definitions.
+ - The `MapRoutePropertiesFunction` signature no longer requires returning `hasErrorBoundary`; the router infers it directly.
+- `react-router` - Remove `react-router-dom` package ([#15076](https://github.com/remix-run/react-router/pull/15076))
+ - In v7 everything DOM-specific was collapsed into `react-router/dom`
+ - `react-router-dom` was kept around as a convenience so existing v6 app imports would still work
+ - For v8, you will need to swap `react-router-dom` imports:
+ - `RouterProvider`/`HydratedRouter` should be imported from `react-router/dom`
+ - Everything else should be imported from `react-router`
+- `@react-router/architect` - Bump `@architect/functions` to v8 ([#15106](https://github.com/remix-run/react-router/pull/15106))
+- `@react-router/architect` - Remove the `useRequestContextDomainName` option from `createRequestHandler` - this is now the default behavior ([#15188](https://github.com/remix-run/react-router/pull/15188))
+- `@react-router/dev` - Remove `@react-router/dev/vite/cloudflare` dev proxy export; use `@cloudflare/vite-plugin` instead ([#15077](https://github.com/remix-run/react-router/pull/15077))
+ - Drops support for `wrangler@3` as a peer dependency of `@react-router/dev`
+- `@react-router/dev` - Require Vite 7+ and make the Vite Environment API build path mandatory ([#15077](https://github.com/remix-run/react-router/pull/15077))
+- `@react-router/express` - Bump dependencies ([#15106](https://github.com/remix-run/react-router/pull/15106))
+ - Bumped `express` from `^4.19.2` to `^4.22.2`
+ - Bumped the `express` peer dependency from `^4.17.1 || ^5` to `^4.22.2 || ^5`
+ - Bumped `@types/express` from `^4.17.9` to `^4.17.25`
+- `@react-router/node` - Switch from `@mjackson/node-fetch-server` to `@remix-run/node-fetch-server` now that we can directly use ESM-only packages ([#14930](https://github.com/remix-run/react-router/pull/14930))
+- `@react-router/serve` - Switch from `@mjackson/node-fetch-server` to `@remix-run/node-fetch-server` now that we can directly use ESM-only packages ([#14930](https://github.com/remix-run/react-router/pull/14930))
+- `create-react-router` - Switch from `@remix-run/web-fetch` to native `fetch` internally. ([#14929](https://github.com/remix-run/react-router/pull/14929))
+ - This removes the underlying `HTTPS_PROXY` support that `node-fetch` and subsequently `@remix-run/web-fetch` supported
+
+### Minor Changes
+
+- `react-router` - Bump dependencies ([#15080](https://github.com/remix-run/react-router/pull/15080))
+ - Bumped `cookie` from `^1.0.1` to `^1.1.1`
+ - Bumped `set-cookie-parser` from `^2.6.0` to `^3.1.0`
+- `@react-router/cloudflare` - Bump `@cloudflare/workers-types` fromn `^4.20260520.1` to `^4.20260527.1` ([#15106](https://github.com/remix-run/react-router/pull/15106))
+- `@react-router/dev` - Bump dependencies ([#15080](https://github.com/remix-run/react-router/pull/15080))
+ - Bumped `@babel/core` from `^7.27.7` to `^7.29.7`
+ - Bumped `@babel/generator` from `^7.27.5` to `^7.29.7`
+ - Bumped `@babel/parser` from `^7.27.7` to `^7.29.7`
+ - Bumped `@babel/plugin-syntax-jsx` from `^7.27.1` to `^7.29.7`
+ - Bumped `@babel/preset-typescript` from `^7.27.1` to `^7.29.7`
+ - Bumped `@babel/traverse` from `^7.27.7` to `^7.29.7`
+ - Bumped `@babel/types` from `^7.27.7` to `^7.29.7`
+ - Bumped `dedent` from `^1.5.3` to `^1.7.2`
+ - Bumped `jsesc` from `3.0.2` to `3.1.0`
+ - Bumped `lodash` from `^4.17.21` to `^4.18.1`
+ - Bumped `prettier` from `^3.6.2` to `^3.8.3`
+ - Bumped `@remix-run/node-fetch-server` from `^0.13.0` to `^0.13.3`
+ - Bumped `react-refresh` from `^0.14.0` to `^0.18.0`
+ - Bumped `semver` from `^7.3.7` to `^7.8.1`
+ - Bumped `tinyglobby` from `^0.2.14` to `^0.2.16`
+ - Bumped `valibot` from `^1.2.0` to `^1.4.1`
+- `@react-router/dev` - Replace `cookie` and `set-cookie-parser` with `cookie-es` ([#15109](https://github.com/remix-run/react-router/pull/15109))
+- `@react-router/dev` - Removed the `vite-node` dependency in favor of Vite's native module runner APIs ([#15104](https://github.com/remix-run/react-router/pull/15104))
+- `@react-router/serve` - Bump `express` from `4.21.2` to `5.2.1` ([#15101](https://github.com/remix-run/react-router/issues/15101))
+- `create-react-router` - Bump dependencies ([#15080](https://github.com/remix-run/react-router/pull/15080))
+ - Bumped `execa` from `5.1.1` to `9.6.1`
+ - Bumped `log-update` from `^5.0.1` to `^8.0.0`
+ - Bumped `semver` from `^7.3.7` to `^7.8.1`
+ - Bumped `sort-package-json` from `^1.55.0` to `^3.6.1`
+ - Bumped `strip-ansi` from `^6.0.1` to `^7.2.0`
+ - Bumped `tar-fs` from `^2.1.3` to `^3.1.2`
+
+### Patch Changes
+
+- `react-router` - Ensure client middleware errors load lazy route error boundaries before bubbling ([#15086](https://github.com/remix-run/react-router/pull/15086))
+- `react-router` - Remove explicit `onSubmit` type override from `SharedFormProps` to fix deprecation warning with `@types/react@19.x` ([#14932](https://github.com/remix-run/react-router/pull/14932)) ([59ebcf1](https://github.com/remix-run/react-router/commit/59ebcf1))
+- `react-router` - Update package builds to preserve individual module files in published artifacts. Public APIs and documented import paths are unchanged. ([#15092](https://github.com/remix-run/react-router/pull/15092))
+ - Updated package TypeScript configs to support modern module syntax used by the build configuration.
+- `react-router` - Migrate package builds from `tsup` to `tsdown`. Published package entry points and public APIs are unchanged. ([#15092](https://github.com/remix-run/react-router/pull/15092))
+- `react-router` - Upgrade React Router's TypeScript tooling to TypeScript 6. Runtime behavior and public APIs are unchanged. ([#15092](https://github.com/remix-run/react-router/pull/15092))
+- `@react-router/architect` - Bump dependencies ([#15080](https://github.com/remix-run/react-router/pull/15080))
+ - Bumped `@types/aws-lambda` from `^8.10.82` to `^8.10.161`
+- `@react-router/dev` - Bump dependencies ([#15080](https://github.com/remix-run/react-router/pull/15080))
+ - Bumped `@babel/core` from `^7.29.0` to `^7.29.7`
+ - Bumped `@babel/generator` from `^7.29.1` to `^7.29.7`
+ - Bumped `@babel/parser` from `^7.29.3` to `^7.29.7`
+ - Bumped `@babel/plugin-syntax-jsx` from `^7.28.6` to `^7.29.7`
+ - Bumped `@babel/preset-typescript` from `^7.28.5` to `^7.29.7`
+ - Bumped `@babel/traverse` from `^7.29.0` to `^7.29.7`
+ - Bumped `@babel/types` from `^7.29.0` to `^7.29.7`
+ - Bumped `babel-dead-code-elimination` from `^1.0.6` to `^1.0.12`
+ - Bumped `chokidar` from `^4.0.0` to `^5.0.0`
+ - Bumped `es-module-lexer` from `^1.3.1` to `^2.1.0`
+ - Bumped `exit-hook` from `2.2.1` to `5.1.0`
+ - Bumped `isbot` from `^5.1.11` to `^5.1.40`
+ - Bumped `p-map` from `^7.0.3` to `^7.0.4`
+ - Bumped `pathe` from `^1.1.2` to `^2.0.3`
+ - Bumped `pkg-types` from `^2.3.0` to `^2.3.1`
+ - Bumped `react-refresh` from `^0.14.0` to `^0.18.0`
+ - Bumped `semver` from `^7.8.0` to `^7.8.1`
+ - Bumped `tinyglobby` from `^0.2.14` to `^0.2.16`
+ - Bumped `valibot` from `^1.4.0` to `^1.4.1`
+- `@react-router/dev` - Fix Windows libuv assertion (`!(handle->flags & UV_HANDLE_CLOSING)` in `src/win/async.c`) during prerendering by using `node:http` instead of `fetch` for internal prerender requests against the Vite preview server ([#15077](https://github.com/remix-run/react-router/pull/15077))
+- `@react-router/fs-routes` - Bump dependencies ([#15091](https://github.com/remix-run/react-router/pull/15091))
+ - Bumped `minimatch` from `^9.0.0` to `^10.2.5`
+- `@react-router/node` - Bump dependencies ([#15106](https://github.com/remix-run/react-router/pull/15106))
+ - Bumped `@remix-run/node-fetch-server` from `^0.13.0` to `^0.13.3`
+- `@react-router/serve` - Bump dependencies ([#15091](https://github.com/remix-run/react-router/pull/15091))
+ - Bumped `@remix-run/node-fetch-server` from `^0.13.0` to `^0.13.3`
+ - Bumped `get-port` from `5.1.1` to `7.2.0`
+
+**Full Changelog**: [`v7.18.0...v8.0.0`](https://github.com/remix-run/react-router/compare/react-router@7.18.0...react-router@8.0.0)
+
+# React Router v7 Releases
+
## v7.18.0
Date: 2026-06-16
diff --git a/README.md b/README.md
index f634862dc7..8e1210841f 100644
--- a/README.md
+++ b/README.md
@@ -2,27 +2,30 @@
[npm-badge]: https://img.shields.io/npm/v/react-router.svg
[npm]: https://www.npmjs.org/package/react-router
-[build-badge]: https://img.shields.io/github/actions/workflow/status/remix-run/react-router/test.yml?branch=dev&style=square
+[build-badge]: https://img.shields.io/github/actions/workflow/status/remix-run/react-router/test-unit.yml?branch=main&style=square
[build]: https://github.com/remix-run/react-router/actions/workflows/test-unit.yml
-React Router is a multi-strategy router for React bridging the gap from React 18 to React 19. You can use it maximally as a React framework or minimally as a library with your own architecture.
+React Router is a multi-strategy router for React. You can use it maximally as a React framework or minimally as a library with your own architecture.
- [Getting Started - Framework](https://reactrouter.com/start/framework/installation)
- [Getting Started - Library](https://reactrouter.com/start/library/installation)
-- [Upgrade from v6](https://reactrouter.com/upgrading/v6)
-- [Upgrade from Remix](https://reactrouter.com/upgrading/remix)
+- [Upgrade from v7](https://reactrouter.com/upgrading/v7)
- [Changelog](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md)
## Packages
- [`react-router`](./packages/react-router)
+- [`create-react-router`](./packages/create-react-router)
- [`@react-router/dev`](./packages/react-router-dev)
- [`@react-router/node`](./packages/react-router-node)
-- [`@react-router/cloudflare`](./packages/react-router-cloudflare)
- [`@react-router/serve`](./packages/react-router-serve)
+- [`@react-router/express`](./packages/react-router-express)
+- [`@react-router/architect`](./packages/react-router-architect)
+- [`@react-router/cloudflare`](./packages/react-router-cloudflare)
- [`@react-router/fs-routes`](./packages/react-router-fs-routes)
## Previous Versions
+- [v7](https://reactrouter.com/v7)
- [v6](https://reactrouter.com/v6)
- [v5](https://v5.reactrouter.com/)
diff --git a/docs/api/components/Await.md b/docs/api/components/Await.md
index 0ff499af41..8b34c3a8e0 100644
--- a/docs/api/components/Await.md
+++ b/docs/api/components/Await.md
@@ -20,7 +20,7 @@ https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/co
## Summary
-[Reference Documentation ↗](https://api.reactrouter.com/v7/functions/react-router.Await.html)
+[Reference Documentation ↗](https://api.reactrouter.com/v8/functions/react-router.Await.html)
Used to render promise values with automatic error handling.
diff --git a/docs/api/components/Form.md b/docs/api/components/Form.md
index 144d3eb596..15a016c564 100644
--- a/docs/api/components/Form.md
+++ b/docs/api/components/Form.md
@@ -20,7 +20,7 @@ https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/do
## Summary
-[Reference Documentation ↗](https://api.reactrouter.com/v7/functions/react-router.Form.html)
+[Reference Documentation ↗](https://api.reactrouter.com/v8/functions/react-router.Form.html)
A progressively enhanced HTML [`