# React Router Releases
This page lists all releases/release notes for React Router back to `v6.0.0`. For releases prior to v6, please refer to the [Github Releases Page](https://github.com/remix-run/react-router/releases).
We manage release notes in this file instead of the paginated Github Releases Page for 2 reasons:
- Pagination in the Github UI means that you cannot easily search release notes for a large span of releases at once
- The paginated Github interface also cuts off longer releases notes without indication in list view, and you need to click into the detail view to see the full set of release notes
Table of Contents
- [React Router Releases](#react-router-releases)
- [v6.25.0](#v6250)
- [What's Changed](#whats-changed)
- [Stabilized `v7_skipActionErrorRevalidation`](#stabilized-v7_skipactionerrorrevalidation)
- [Minor Changes](#minor-changes)
- [Patch Changes](#patch-changes)
- [v6.24.1](#v6241)
- [Patch Changes](#patch-changes-1)
- [v6.24.0](#v6240)
- [What's Changed](#whats-changed-1)
- [Lazy Route Discovery (a.k.a. "Fog of War")](#lazy-route-discovery-aka-fog-of-war)
- [Minor Changes](#minor-changes-1)
- [Patch Changes](#patch-changes-2)
- [v6.23.1](#v6231)
- [Patch Changes](#patch-changes-3)
- [v6.23.0](#v6230)
- [What's Changed](#whats-changed-2)
- [Data Strategy (unstable)](#data-strategy-unstable)
- [Skip Action Error Revalidation (unstable)](#skip-action-error-revalidation-unstable)
- [Minor Changes](#minor-changes-2)
- [v6.22.3](#v6223)
- [Patch Changes](#patch-changes-4)
- [v6.22.2](#v6222)
- [Patch Changes](#patch-changes-5)
- [v6.22.1](#v6221)
- [Patch Changes](#patch-changes-6)
- [v6.22.0](#v6220)
- [What's Changed](#whats-changed-3)
- [Core Web Vitals Technology Report Flag](#core-web-vitals-technology-report-flag)
- [Minor Changes](#minor-changes-3)
- [Patch Changes](#patch-changes-7)
- [v6.21.3](#v6213)
- [Patch Changes](#patch-changes-8)
- [v6.21.2](#v6212)
- [Patch Changes](#patch-changes-9)
- [v6.21.1](#v6211)
- [Patch Changes](#patch-changes-10)
- [v6.21.0](#v6210)
- [What's Changed](#whats-changed-4)
- [`future.v7_relativeSplatPath`](#futurev7_relativesplatpath)
- [Partial Hydration](#partial-hydration)
- [Minor Changes](#minor-changes-4)
- [Patch Changes](#patch-changes-11)
- [v6.20.1](#v6201)
- [Patch Changes](#patch-changes-12)
- [v6.20.0](#v6200)
- [Minor Changes](#minor-changes-5)
- [Patch Changes](#patch-changes-13)
- [v6.19.0](#v6190)
- [What's Changed](#whats-changed-5)
- [`unstable_flushSync` API](#unstable_flushsync-api)
- [Minor Changes](#minor-changes-6)
- [Patch Changes](#patch-changes-14)
- [v6.18.0](#v6180)
- [What's Changed](#whats-changed-6)
- [New Fetcher APIs](#new-fetcher-apis)
- [Persistence Future Flag (`future.v7_fetcherPersist`)](#persistence-future-flag-futurev7_fetcherpersist)
- [Minor Changes](#minor-changes-7)
- [Patch Changes](#patch-changes-15)
- [v6.17.0](#v6170)
- [What's Changed](#whats-changed-7)
- [View Transitions π](#view-transitions-)
- [Minor Changes](#minor-changes-8)
- [Patch Changes](#patch-changes-16)
- [v6.16.0](#v6160)
- [Minor Changes](#minor-changes-9)
- [Patch Changes](#patch-changes-17)
- [v6.15.0](#v6150)
- [Minor Changes](#minor-changes-10)
- [Patch Changes](#patch-changes-18)
- [v6.14.2](#v6142)
- [Patch Changes](#patch-changes-19)
- [v6.14.1](#v6141)
- [Patch Changes](#patch-changes-20)
- [v6.14.0](#v6140)
- [What's Changed](#whats-changed-8)
- [JSON/Text Submissions](#jsontext-submissions)
- [Minor Changes](#minor-changes-11)
- [Patch Changes](#patch-changes-21)
- [v6.13.0](#v6130)
- [What's Changed](#whats-changed-9)
- [`future.v7_startTransition`](#futurev7_starttransition)
- [Minor Changes](#minor-changes-12)
- [Patch Changes](#patch-changes-22)
- [v6.12.1](#v6121)
- [Patch Changes](#patch-changes-23)
- [v6.12.0](#v6120)
- [What's Changed](#whats-changed-10)
- [`React.startTransition` support](#reactstarttransition-support)
- [Minor Changes](#minor-changes-13)
- [Patch Changes](#patch-changes-24)
- [v6.11.2](#v6112)
- [Patch Changes](#patch-changes-25)
- [v6.11.1](#v6111)
- [Patch Changes](#patch-changes-26)
- [v6.11.0](#v6110)
- [Minor Changes](#minor-changes-14)
- [Patch Changes](#patch-changes-27)
- [v6.10.0](#v6100)
- [What's Changed](#whats-changed-11)
- [Minor Changes](#minor-changes-15)
- [`future.v7_normalizeFormMethod`](#futurev7_normalizeformmethod)
- [Patch Changes](#patch-changes-28)
- [v6.9.0](#v690)
- [What's Changed](#whats-changed-12)
- [`Component`/`ErrorBoundary` route properties](#componenterrorboundary-route-properties)
- [Introducing Lazy Route Modules](#introducing-lazy-route-modules)
- [Minor Changes](#minor-changes-16)
- [Patch Changes](#patch-changes-29)
- [v6.8.2](#v682)
- [Patch Changes](#patch-changes-30)
- [v6.8.1](#v681)
- [Patch Changes](#patch-changes-31)
- [v6.8.0](#v680)
- [Minor Changes](#minor-changes-17)
- [Patch Changes](#patch-changes-32)
- [v6.7.0](#v670)
- [Minor Changes](#minor-changes-18)
- [Patch Changes](#patch-changes-33)
- [v6.6.2](#v662)
- [Patch Changes](#patch-changes-34)
- [v6.6.1](#v661)
- [Patch Changes](#patch-changes-35)
- [v6.6.0](#v660)
- [What's Changed](#whats-changed-13)
- [Minor Changes](#minor-changes-19)
- [Patch Changes](#patch-changes-36)
- [v6.5.0](#v650)
- [What's Changed](#whats-changed-14)
- [Minor Changes](#minor-changes-20)
- [Patch Changes](#patch-changes-37)
- [v6.4.5](#v645)
- [Patch Changes](#patch-changes-38)
- [v6.4.4](#v644)
- [Patch Changes](#patch-changes-39)
- [v6.4.3](#v643)
- [Patch Changes](#patch-changes-40)
- [v6.4.2](#v642)
- [Patch Changes](#patch-changes-41)
- [v6.4.1](#v641)
- [Patch Changes](#patch-changes-42)
- [v6.4.0](#v640)
- [What's Changed](#whats-changed-15)
- [Remix Data APIs](#remix-data-apis)
- [Patch Changes](#patch-changes-43)
- [v6.3.0](#v630)
- [Minor Changes](#minor-changes-21)
- [v6.2.2](#v622)
- [Patch Changes](#patch-changes-44)
- [v6.2.1](#v621)
- [Patch Changes](#patch-changes-45)
- [v6.2.0](#v620)
- [Minor Changes](#minor-changes-22)
- [Patch Changes](#patch-changes-46)
- [v6.1.1](#v611)
- [Patch Changes](#patch-changes-47)
- [v6.1.0](#v610)
- [Minor Changes](#minor-changes-23)
- [Patch Changes](#patch-changes-48)
- [v6.0.2](#v602)
- [Patch Changes](#patch-changes-49)
- [v6.0.1](#v601)
- [Patch Changes](#patch-changes-50)
- [v6.0.0](#v600)
## v6.25.0
Date: 2024-07-16
### What's Changed
#### Stabilized `v7_skipActionErrorRevalidation`
This release stabilizes the `future.unstable_skipActionErrorRevalidation` flag into [`future.v7_skipActionErrorRevalidation`](https://reactrouter.com/upgrading/future#v7_skipactionstatusrevalidation) in preparation for the upcoming React Router v7 release.
- When this flag is enabled, actions that return/throw a `4xx/5xx` `Response` will not trigger a revalidation by default
- This also stabilizes `shouldRevalidate`'s `unstable_actionStatus` parameter to `actionStatus`
### Minor Changes
- Stabilize `future.unstable_skipActionErrorRevalidation` as `future.v7_skipActionErrorRevalidation` ([#11769](https://github.com/remix-run/react-router/pull/11769))
### Patch Changes
- Fix regression and properly decode paths inside `useMatch` so matches/params reflect decoded params ([#11789](https://github.com/remix-run/react-router/pull/11789))
- Fix bubbling of errors thrown from `unstable_patchRoutesOnMiss` ([#11786](https://github.com/remix-run/react-router/pull/11786))
- Fix hydration in SSR apps using `unstable_patchRoutesOnMiss` that matched a splat route on the server ([#11790](https://github.com/remix-run/react-router/pull/11790))
**Full Changelog**: [`v6.24.1...v6.25.0`](https://github.com/remix-run/react-router/compare/react-router@6.24.1...react-router@6.25.0)
## v6.24.1
Date: 2024-07-03
### Patch Changes
- Remove `polyfill.io` reference from warning message because the domain was sold and has since been determined to serve malware ([#11741](https://github.com/remix-run/react-router/pull/11741))
- See https://sansec.io/research/polyfill-supply-chain-attack
- Export `NavLinkRenderProps` type for easier typing of custom `NavLink` callback ([#11553](https://github.com/remix-run/react-router/pull/11553))
- When using `future.v7_relativeSplatPath`, properly resolve relative paths in splat routes that are children of pathless routes ([#11633](https://github.com/remix-run/react-router/pull/11633))
- Fog of War (unstable): Trigger a new `router.routes` identity/reflow during route patching ([#11740](https://github.com/remix-run/react-router/pull/11740))
- Fog of War (unstable): Fix initial matching when a splat route matches ([#11759](https://github.com/remix-run/react-router/pull/11759))
**Full Changelog**: [`v6.24.0...v6.24.1`](https://github.com/remix-run/react-router/compare/react-router@6.24.0...react-router@6.24.1)
## v6.24.0
Date: 2024-06-24
### What's Changed
#### Lazy Route Discovery (a.k.a. "Fog of War")
We're really excited to release our new API for "Lazy Route Discovery" in `v6.24.0`! For some background information, please check out the original [RFC](https://github.com/remix-run/react-router/discussions/11113). The **tl;dr;** is that ever since we introduced the Data APIs in v6.4 via ``, we've been a little bummed that one of the tradeoffs was the lack of a compelling code-splitting story mirroring what we had in the ``/`` apps. We took a baby-step towards improving that story with `route.lazy` in `v6.9.0`, but with `v6.24.0` we've gone the rest of the way.
With "Fog of War", you can now load portions of the route tree lazily via the new `unstable_patchRoutesOnMiss` option passed to `createBrowserRouter` (and it's memory/hash counterparts). This gives you a way to hook into spots where React Router is unable to match a given path and patch new routes into the route tree during the navigation (or fetcher call).
Here's a very small example, but please refer to the [documentation](https://reactrouter.com/en/main/routers/create-browser-router#optsunstable_patchroutesonmiss) for more information and use cases:
```js
const router = createBrowserRouter(
[
{
id: "root",
path: "/",
Component: RootComponent,
},
],
{
async unstable_patchRoutesOnMiss({ path, patch }) {
if (path === "/a") {
// Load the `a` route (`{ path: 'a', Component: A }`)
let route = await getARoute();
// Patch the `a` route in as a new child of the `root` route
patch("root", [route]);
}
},
}
);
```
### Minor Changes
- Add support for Lazy Route Discovery (a.k.a. "Fog of War") ([#11626](https://github.com/remix-run/react-router/pull/11626))
### Patch Changes
- Fix `fetcher.submit` types - remove incorrect `navigate`/`fetcherKey`/`unstable_viewTransition` options because they are only relevant for `useSubmit` ([#11631](https://github.com/remix-run/react-router/pull/11631))
- Allow falsy `location.state` values passed to `` ([#11495](https://github.com/remix-run/react-router/pull/11495))
**Full Changelog**: [`v6.23.1...v6.24.0`](https://github.com/remix-run/react-router/compare/react-router@6.23.1...react-router@6.24.0)
## v6.23.1
Date: 2024-05-10
### Patch Changes
- Allow `undefined` to be resolved through `` ([#11513](https://github.com/remix-run/react-router/pull/11513))
- Add defensive `document` check when checking for `document.startViewTransition` availability ([#11544](https://github.com/remix-run/react-router/pull/11544))
- Change the `react-router-dom/server` import back to `react-router-dom` instead of `index.ts` ([#11514](https://github.com/remix-run/react-router/pull/11514))
- `@remix-run/router` - Support `unstable_dataStrategy` on `staticHandler.queryRoute` ([#11515](https://github.com/remix-run/react-router/pull/11515))
**Full Changelog**: [`v6.23.0...v6.23.1`](https://github.com/remix-run/react-router/compare/react-router@6.23.0...react-router@6.23.1)
## v6.23.0
Date: 2024-04-23
### What's Changed
#### Data Strategy (unstable)
The new `unstable_dataStrategy` API is a low-level API designed for advanced use-cases where you need to take control over the data strategy for your `loader`/`action` functions. The default implementation is today's behavior, to fetch all loaders in parallel, but this option allows users to implement more advanced data flows including Remix ["Single Fetch"](https://remix.run/docs/guides/single-fetch), user-land middleware/context APIs, automatic loader caching, and more. Please see the [docs](https://reactrouter.com/routers/create-browser-router#unstable_datastrategy) for more information.
**Note:** This is a low-level API intended for advanced use-cases. This overrides React Router's internal handling of `loader`/`action` execution, and if done incorrectly will break your app code. Please use with caution and perform the appropriate testing.
#### Skip Action Error Revalidation (unstable)
Currently, all active `loader`'s revalidate after any `action` submission, regardless of the `action` result. However, in the majority of cases a `4xx`/`5xx` response from an `action` means that no data was actually changed and the revalidation is unnecessary. We've introduced a new `future.unstable_skipActionErrorRevalidation` flag that changes the behavior here, and we plan to make this the default in future version of React Router.
With this flag enabled, `action`'s that return/throw a `4xx`/`5xx` response status will no longer automatically revalidate. If you need to revalidate after a `4xx`/`5xx` result with this flag enabled, you can still do that via returning `true` from `shouldRevalidate` - which now also receives a new `unstable_actionStatus` argument alongside `actionResult` so you can make decision based on the status of the `action` response without having to encode it into the action data.
### Minor Changes
- Add a new `unstable_dataStrategy` configuration option ([#11098](https://github.com/remix-run/react-router/pull/11098), [#11377](https://github.com/remix-run/react-router/pull/11377))
- `@remix-run/router` - Add a new `future.unstable_skipActionRevalidation` future flag ([#11098](https://github.com/remix-run/react-router/pull/11098))
- `@remix-run/router` - SSR: Added a new `skipLoaderErrorBubbling` options to the `staticHandler.query` method to disable error bubbling by the static handler for use in Remix's Single Fetch implementation ([#11098](https://github.com/remix-run/react-router/pull/11098), ([#11377](https://github.com/remix-run/react-router/pull/11377)))
**Full Changelog**: [`v6.22.3...v6.23.0`](https://github.com/remix-run/react-router/compare/react-router@6.22.3...react-router@6.23.0)
## v6.22.3
Date: 2024-03-07
### Patch Changes
- Fix a `future.v7_partialHydration` bug that would re-run loaders below the boundary on hydration if SSR loader errors bubbled to a parent boundary ([#11324](https://github.com/remix-run/react-router/pull/11324))
- Fix a `future.v7_partialHydration` bug that would consider the router uninitialized if a route did not have a loader ([#11325](https://github.com/remix-run/react-router/pull/11325))
**Full Changelog**: [`v6.22.2...v6.22.3`](https://github.com/remix-run/react-router/compare/react-router@6.22.2...react-router@6.22.3)
## v6.22.2
Date: 2024-02-28
### Patch Changes
- Preserve hydrated errors during partial hydration runs ([#11305](https://github.com/remix-run/react-router/pull/11305))
**Full Changelog**: [`v6.22.1...v6.22.2`](https://github.com/remix-run/react-router/compare/react-router@6.22.1...react-router@6.22.2)
## v6.22.1
Date: 2024-02-16
### Patch Changes
- Fix encoding/decoding issues with pre-encoded dynamic parameter values ([#11199](https://github.com/remix-run/react-router/pull/11199))
**Full Changelog**: [`v6.22.0...v6.22.1`](https://github.com/remix-run/react-router/compare/react-router@6.22.0...react-router@6.22.1)
## v6.22.0
Date: 2024-02-01
### What's Changed
#### Core Web Vitals Technology Report Flag
In 2021, the HTTP Archive launched the [Core Web Vitals Technology Report dashboard](https://discuss.httparchive.org/t/new-dashboard-the-core-web-vitals-technology-report/2178):
> By combining the powers of real-user experiences in the Chrome UX Report 26 (CrUX) dataset with web technology detections in HTTP Archive 30, we can get a glimpse into how architectural decisions like choices of CMS platform or JavaScript framework play a role in sitesβ CWV performance.
They use a tool called [`wappalyzer`](https://github.com/HTTPArchive/wappalyzer) to identify what technologies a given website is using by looking for certain scripts, global JS variables, or other identifying characteristics. For example, for Remix applications, they [look for the global `__remixContext`](https://github.com/HTTPArchive/wappalyzer/blob/c2a24ee7c2d07bf9c521f02584ae2dcf603ac0b7/src/technologies/r.json#L1328) variable to identify that a website is using Remix.
It was brought to our attention that React Router was unable to be reliably identified because there are no identifying global aspects. They are currently [looking for external scripts with `react-router`](https://github.com/HTTPArchive/wappalyzer/blob/c2a24ee7c2d07bf9c521f02584ae2dcf603ac0b7/src/technologies/r.json#L637) in the name. This will identify sites using React Router from a CDN such as `unpkg` - but it will miss the **vast** majority of sites that are installing React Router from the npm registry and bundling it into their JS files. This results in [drastically under-reporting](https://lookerstudio.google.com/s/pixHkNmGbN4) the usage of React Router on the web.
Starting with version `6.22.0`, sites using `react-router-dom` will begin adding a `window.__reactRouterVersion` variable that will be set to a string value of the SemVer major version number (i.e., `window.__reactRouterVersion = "6";`) so that they can be properly identified.
### Minor Changes
- Include a `window.__reactRouterVersion` for CWV Report detection ([#11222](https://github.com/remix-run/react-router/pull/11222))
- Add a `createStaticHandler` `future.v7_throwAbortReason` flag to throw `request.signal.reason` (defaults to a `DOMException`) when a request is aborted instead of an `Error` such as `new Error("query() call aborted: GET /path")` ([#11104](https://github.com/remix-run/react-router/pull/11104))
- Please note that `DOMException` was added in Node v17 so you will not get a `DOMException` on Node 16 and below.
### Patch Changes
- Respect the `ErrorResponse` status code if passed to `getStaticContextFormError` ([#11213](https://github.com/remix-run/react-router/pull/11213))
**Full Changelog**: [`v6.21.3...v6.22.0`](https://github.com/remix-run/react-router/compare/react-router@6.21.3...react-router@6.22.0)
## v6.21.3
Date: 2024-01-18
### Patch Changes
- Fix `NavLink` `isPending` when a `basename` is used ([#11195](https://github.com/remix-run/react-router/pull/11195))
- Remove leftover `unstable_` prefix from `Blocker`/`BlockerFunction` types ([#11187](https://github.com/remix-run/react-router/pull/11187))
**Full Changelog**: [`v6.21.2...v6.21.3`](https://github.com/remix-run/react-router/compare/react-router@6.21.2...react-router@6.21.3)
## v6.21.2
Date: 2024-01-11
### Patch Changes
- Leverage `useId` for internal fetcher keys when available ([#11166](https://github.com/remix-run/react-router/pull/11166))
- Fix bug where dashes were not picked up in dynamic parameter names ([#11160](https://github.com/remix-run/react-router/pull/11160))
- Do not attempt to deserialize empty JSON responses ([#11164](https://github.com/remix-run/react-router/pull/11164))
**Full Changelog**: [`v6.21.1...v6.21.2`](https://github.com/remix-run/react-router/compare/react-router@6.21.1...react-router@6.21.2)
## v6.21.1
Date: 2023-12-21
### Patch Changes
- Fix bug with `route.lazy` not working correctly on initial SPA load when `v7_partialHydration` is specified ([#11121](https://github.com/remix-run/react-router/pull/11121))
- Fix bug preventing revalidation from occurring for persisted fetchers unmounted during the `submitting` phase ([#11102](https://github.com/remix-run/react-router/pull/11102))
- De-dup relative path logic in `resolveTo` ([#11097](https://github.com/remix-run/react-router/pull/11097))
**Full Changelog**: [`v6.21.0...v6.21.1`](https://github.com/remix-run/react-router/compare/react-router@6.21.0...react-router@6.21.1)
## v6.21.0
Date: 2023-12-13
### What's Changed
#### `future.v7_relativeSplatPath`
We fixed a splat route path-resolution bug in `6.19.0`, but later determined a large number of applications were relying on the buggy behavior, so we reverted the fix in `6.20.1` (see [#10983](https://github.com/remix-run/react-router/issues/10983), [#11052](https://github.com/remix-run/react-router/issues/11052), [#11078](https://github.com/remix-run/react-router/issues/11078)).
The buggy behavior is that the default behavior when resolving relative paths inside a splat route would _ignore_ any splat (`*`) portion of the current route path. When the future flag is enabled, splat portions are included in relative path logic within splat routes.
For more information, please refer to the [`useResolvedPath` docs](https://reactrouter.com/hooks/use-resolved-path#splat-paths) and/or the [detailed changelog entry](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md#6210).
#### Partial Hydration
We added a new `future.v7_partialHydration` future flag for the `@remix-run/router` that enables partial hydration of a data router when Server-Side Rendering. This allows you to provide `hydrationData.loaderData` that has values for _some_ initially matched route loaders, but not all. When this flag is enabled, the router will call `loader` functions for routes that do not have hydration loader data during `router.initialize()`, and it will render down to the deepest provided `HydrateFallback` (up to the first route without hydration data) while it executes the unhydrated routes. ([#11033](https://github.com/remix-run/react-router/pull/11033))
### Minor Changes
- Add a new `future.v7_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route. ([#11087](https://github.com/remix-run/react-router/pull/11087))
- Add a new `future.v7_partialHydration` future flag that enables partial hydration of a data router when Server-Side Rendering ([#11033](https://github.com/remix-run/react-router/pull/11033))
### Patch Changes
- Properly handle falsy error values in `ErrorBoundary`'s ([#11071](https://github.com/remix-run/react-router/pull/11071))
- Catch and bubble errors thrown when trying to unwrap responses from `loader`/`action` functions ([#11061](https://github.com/remix-run/react-router/pull/11061))
- Fix `relative="path"` issue when rendering `Link`/`NavLink` outside of matched routes ([#11062](https://github.com/remix-run/react-router/pull/11062))
**Full Changelog**: [`v6.20.1...v6.21.0`](https://github.com/remix-run/react-router/compare/react-router@6.20.1...react-router@6.21.0)
## v6.20.1
Date: 2023-12-01
### Patch Changes
- Revert the `useResolvedPath` fix for splat routes due to a large number of applications that were relying on the buggy behavior (see [#11052](https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329)) ([#11078](https://github.com/remix-run/react-router/pull/11078))
- We plan to re-introduce this fix behind a future flag in the next minor version (see [this comment](https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329))
- This fix was included in versions `6.19.0` and `6.20.0`. If you are upgrading from `6.18.0` or earlier, you would not have been impacted by this fix.
**Full Changelog**: [`v6.20.0...v6.20.1`](https://github.com/remix-run/react-router/compare/react-router@6.20.0...react-router@6.20.1)
## v6.20.0
Date: 2023-11-22
> [!WARNING]
> Please use version `6.20.1` or later instead of `6.20.0`. We discovered that a large number of apps were relying on buggy behavior that was fixed in this release ([#11045](https://github.com/remix-run/react-router/pull/11045)). We reverted the fix in `6.20.1` and will be re-introducing it behind a future flag in a subsequent release. See [#11052](https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329) for more details.
### Minor Changes
- Export the `PathParam` type from the public API ([#10719](https://github.com/remix-run/react-router/pull/10719))
### Patch Changes
- Do not revalidate unmounted fetchers when `v7_fetcherPersist` is enabled ([#11044](https://github.com/remix-run/react-router/pull/11044))
- Fix bug with `resolveTo` path resolution in splat routes ([#11045](https://github.com/remix-run/react-router/pull/11045))
- This is a follow up to [#10983](https://github.com/remix-run/react-router/pull/10983) to handle the few other code paths using `getPathContributingMatches`
- This removes the `UNSAFE_getPathContributingMatches` export from `@remix-run/router` since we no longer need this in the `react-router`/`react-router-dom` layers
**Full Changelog**: [`v6.19.0...v6.20.0`](https://github.com/remix-run/react-router/compare/react-router@6.19.0...react-router@6.20.0)
## v6.19.0
Date: 2023-11-16
> [!WARNING]
> Please use version `6.20.1` or later instead of `6.19.0`. We discovered that a large number of apps were relying on buggy behavior that was fixed in this release ([#10983](https://github.com/remix-run/react-router/pull/10983)). We reverted the fix in `6.20.1` and will be re-introducing it behind a future flag in a subsequent release. See [#11052](https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329) for more details.
### What's Changed
#### `unstable_flushSync` API
This release brings a new `unstable_flushSync` option to the imperative APIs (`useSubmit`, `useNavigate`, `fetcher.submit`, `fetcher.load`) to let users opt-into synchronous DOM updates for pending/optimistic UI.
```js
function handleClick() {
submit(data, { flushSync: true });
// Everything is flushed to the DOM so you can focus/scroll to your pending/optimistic UI
setFocusAndOrScrollToNewlyAddedThing();
}
```
### Minor Changes
- Add `unstable_flushSync` option to `useNavigate`/`useSubmit`/`fetcher.load`/`fetcher.submit` to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates ([#11005](https://github.com/remix-run/react-router/pull/11005))
- Remove the `unstable_` prefix from the [`useBlocker`](https://reactrouter.com/en/main/hooks/use-blocker) hook as it's been in use for enough time that we are confident in the API ([#10991](https://github.com/remix-run/react-router/pull/10991))
- We do not plan to remove the prefix from `unstable_usePrompt` due to differences in how browsers handle `window.confirm` that prevent React Router from guaranteeing consistent/correct behavior
### Patch Changes
- Fix `useActionData` so it returns proper contextual action data and not _any_ action data in the tree ([#11023](https://github.com/remix-run/react-router/pull/11023))
- Fix bug in `useResolvedPath` that would cause `useResolvedPath(".")` in a splat route to lose the splat portion of the URL path. ([#10983](https://github.com/remix-run/react-router/pull/10983))
- β οΈ This fixes a quite long-standing bug specifically for `"."` paths inside a splat route which incorrectly dropped the splat portion of the URL. If you are relative routing via `"."` inside a splat route in your application you should double check that your logic is not relying on this buggy behavior and update accordingly.
- Fix issue where a changing fetcher `key` in a `useFetcher` that remains mounted wasn't getting picked up ([#11009](https://github.com/remix-run/react-router/pull/11009))
- Fix `useFormAction` which was incorrectly inheriting the `?index` query param from child route `action` submissions ([#11025](https://github.com/remix-run/react-router/pull/11025))
- Fix `NavLink` `active` logic when `to` location has a trailing slash ([#10734](https://github.com/remix-run/react-router/pull/10734))
- Fix types so `unstable_usePrompt` can accept a `BlockerFunction` in addition to a `boolean` ([#10991](https://github.com/remix-run/react-router/pull/10991))
- Fix `relative="path"` bug where relative path calculations started from the full location pathname, instead of from the current contextual route pathname. ([#11006](https://github.com/remix-run/react-router/pull/11006))
```jsx
}>
;
function Component() {
return (
<>
{/* This is now correctly relative to /a/b, not /a/b/c */}
>
);
}
```
**Full Changelog**: [`6.18.0...6.19.0`](https://github.com/remix-run/react-router/compare/react-router@6.18.0...react-router@6.19.0)
## v6.18.0
Date: 2023-10-31
### What's Changed
#### New Fetcher APIs
Per this [RFC](https://github.com/remix-run/remix/discussions/7698), we've introduced some new APIs that give you more granular control over your fetcher behaviors.
- You may now specify your own fetcher identifier via `useFetcher({ key: string })`, which allows you to access the same fetcher instance from different components in your application without prop-drilling
- Fetcher keys are now exposed on the fetchers returned from `useFetchers` so that they can be looked up by `key`
- `Form` and `useSubmit` now support optional `navigate`/`fetcherKey` props/params to allow kicking off a fetcher submission under the hood with an optionally user-specified `key`
- `