diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52e80ef14f..4aa0546c77 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,122 +13,128 @@ We manage release notes in this file instead of the paginated Github Releases Pa
Table of Contents
- [React Router Releases](#react-router-releases)
- - [v6.20.1](#v6201)
- - [Patch Changes](#patch-changes)
- - [v6.20.0](#v6200)
+ - [v6.21.0](#v6210)
+ - [What's Changed](#whats-changed)
+ - [`future.v7_relativeSplatPath`](#futurev7_relativesplatpath)
+ - [Partial Hydration](#partial-hydration)
- [Minor Changes](#minor-changes)
+ - [Patch Changes](#patch-changes)
+ - [v6.20.1](#v6201)
- [Patch Changes](#patch-changes-1)
- - [v6.19.0](#v6190)
- - [What's Changed](#whats-changed)
- - [`unstable_flushSync` API](#unstable_flushsync-api)
+ - [v6.20.0](#v6200)
- [Minor Changes](#minor-changes-1)
- [Patch Changes](#patch-changes-2)
- - [v6.18.0](#v6180)
+ - [v6.19.0](#v6190)
- [What's Changed](#whats-changed-1)
- - [New Fetcher APIs](#new-fetcher-apis)
- - [Persistence Future Flag (`future.v7_fetcherPersist`)](#persistence-future-flag-futurev7_fetcherpersist)
+ - [`unstable_flushSync` API](#unstable_flushsync-api)
- [Minor Changes](#minor-changes-2)
- [Patch Changes](#patch-changes-3)
- - [v6.17.0](#v6170)
+ - [v6.18.0](#v6180)
- [What's Changed](#whats-changed-2)
- - [View Transitions ๐](#view-transitions-)
+ - [New Fetcher APIs](#new-fetcher-apis)
+ - [Persistence Future Flag (`future.v7_fetcherPersist`)](#persistence-future-flag-futurev7_fetcherpersist)
- [Minor Changes](#minor-changes-3)
- [Patch Changes](#patch-changes-4)
- - [v6.16.0](#v6160)
+ - [v6.17.0](#v6170)
+ - [What's Changed](#whats-changed-3)
+ - [View Transitions ๐](#view-transitions-)
- [Minor Changes](#minor-changes-4)
- [Patch Changes](#patch-changes-5)
- - [v6.15.0](#v6150)
+ - [v6.16.0](#v6160)
- [Minor Changes](#minor-changes-5)
- [Patch Changes](#patch-changes-6)
- - [v6.14.2](#v6142)
+ - [v6.15.0](#v6150)
+ - [Minor Changes](#minor-changes-6)
- [Patch Changes](#patch-changes-7)
- - [v6.14.1](#v6141)
+ - [v6.14.2](#v6142)
- [Patch Changes](#patch-changes-8)
- - [v6.14.0](#v6140)
- - [What's Changed](#whats-changed-3)
- - [JSON/Text Submissions](#jsontext-submissions)
- - [Minor Changes](#minor-changes-6)
+ - [v6.14.1](#v6141)
- [Patch Changes](#patch-changes-9)
- - [v6.13.0](#v6130)
+ - [v6.14.0](#v6140)
- [What's Changed](#whats-changed-4)
+ - [JSON/Text Submissions](#jsontext-submissions)
- [Minor Changes](#minor-changes-7)
- [Patch Changes](#patch-changes-10)
- - [v6.12.1](#v6121)
- - [Patch Changes](#patch-changes-11)
- - [v6.12.0](#v6120)
+ - [v6.13.0](#v6130)
- [What's Changed](#whats-changed-5)
- - [`React.startTransition` support](#reactstarttransition-support)
- [Minor Changes](#minor-changes-8)
+ - [Patch Changes](#patch-changes-11)
+ - [v6.12.1](#v6121)
- [Patch Changes](#patch-changes-12)
- - [v6.11.2](#v6112)
+ - [v6.12.0](#v6120)
+ - [What's Changed](#whats-changed-6)
+ - [`React.startTransition` support](#reactstarttransition-support)
+ - [Minor Changes](#minor-changes-9)
- [Patch Changes](#patch-changes-13)
- - [v6.11.1](#v6111)
+ - [v6.11.2](#v6112)
- [Patch Changes](#patch-changes-14)
- - [v6.11.0](#v6110)
- - [Minor Changes](#minor-changes-9)
+ - [v6.11.1](#v6111)
- [Patch Changes](#patch-changes-15)
- - [v6.10.0](#v6100)
- - [What's Changed](#whats-changed-6)
+ - [v6.11.0](#v6110)
- [Minor Changes](#minor-changes-10)
- [Patch Changes](#patch-changes-16)
- - [v6.9.0](#v690)
+ - [v6.10.0](#v6100)
- [What's Changed](#whats-changed-7)
- - [`Component`/`ErrorBoundary` route properties](#componenterrorboundary-route-properties)
- - [Introducing Lazy Route Modules](#introducing-lazy-route-modules)
- [Minor Changes](#minor-changes-11)
- [Patch Changes](#patch-changes-17)
- - [v6.8.2](#v682)
+ - [v6.9.0](#v690)
+ - [What's Changed](#whats-changed-8)
+ - [`Component`/`ErrorBoundary` route properties](#componenterrorboundary-route-properties)
+ - [Introducing Lazy Route Modules](#introducing-lazy-route-modules)
+ - [Minor Changes](#minor-changes-12)
- [Patch Changes](#patch-changes-18)
- - [v6.8.1](#v681)
+ - [v6.8.2](#v682)
- [Patch Changes](#patch-changes-19)
- - [v6.8.0](#v680)
- - [Minor Changes](#minor-changes-12)
+ - [v6.8.1](#v681)
- [Patch Changes](#patch-changes-20)
- - [v6.7.0](#v670)
+ - [v6.8.0](#v680)
- [Minor Changes](#minor-changes-13)
- [Patch Changes](#patch-changes-21)
- - [v6.6.2](#v662)
+ - [v6.7.0](#v670)
+ - [Minor Changes](#minor-changes-14)
- [Patch Changes](#patch-changes-22)
- - [v6.6.1](#v661)
+ - [v6.6.2](#v662)
- [Patch Changes](#patch-changes-23)
- - [v6.6.0](#v660)
- - [What's Changed](#whats-changed-8)
- - [Minor Changes](#minor-changes-14)
+ - [v6.6.1](#v661)
- [Patch Changes](#patch-changes-24)
- - [v6.5.0](#v650)
+ - [v6.6.0](#v660)
- [What's Changed](#whats-changed-9)
- [Minor Changes](#minor-changes-15)
- [Patch Changes](#patch-changes-25)
- - [v6.4.5](#v645)
+ - [v6.5.0](#v650)
+ - [What's Changed](#whats-changed-10)
+ - [Minor Changes](#minor-changes-16)
- [Patch Changes](#patch-changes-26)
- - [v6.4.4](#v644)
+ - [v6.4.5](#v645)
- [Patch Changes](#patch-changes-27)
- - [v6.4.3](#v643)
+ - [v6.4.4](#v644)
- [Patch Changes](#patch-changes-28)
- - [v6.4.2](#v642)
+ - [v6.4.3](#v643)
- [Patch Changes](#patch-changes-29)
- - [v6.4.1](#v641)
+ - [v6.4.2](#v642)
- [Patch Changes](#patch-changes-30)
+ - [v6.4.1](#v641)
+ - [Patch Changes](#patch-changes-31)
- [v6.4.0](#v640)
- - [What's Changed](#whats-changed-10)
+ - [What's Changed](#whats-changed-11)
- [Remix Data APIs](#remix-data-apis)
- - [Patch Changes](#patch-changes-31)
+ - [Patch Changes](#patch-changes-32)
- [v6.3.0](#v630)
- - [Minor Changes](#minor-changes-16)
+ - [Minor Changes](#minor-changes-17)
- [v6.2.2](#v622)
- - [Patch Changes](#patch-changes-32)
- - [v6.2.1](#v621)
- [Patch Changes](#patch-changes-33)
- - [v6.2.0](#v620)
- - [Minor Changes](#minor-changes-17)
+ - [v6.2.1](#v621)
- [Patch Changes](#patch-changes-34)
- - [v6.1.1](#v611)
- - [Patch Changes](#patch-changes-35)
- - [v6.1.0](#v610)
+ - [v6.2.0](#v620)
- [Minor Changes](#minor-changes-18)
+ - [Patch Changes](#patch-changes-35)
+ - [v6.1.1](#v611)
- [Patch Changes](#patch-changes-36)
- - [v6.0.1](#v601)
+ - [v6.1.0](#v610)
+ - [Minor Changes](#minor-changes-19)
- [Patch Changes](#patch-changes-37)
+ - [v6.0.1](#v601)
+ - [Patch Changes](#patch-changes-38)
- [v6.0.0](#v600)
@@ -152,6 +158,35 @@ To add a new release, copy from this template:
-->
+## v6.21.0
+
+### 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
### Patch Changes
diff --git a/docs/components/form.md b/docs/components/form.md
index 65336f3b09..d5626d753a 100644
--- a/docs/components/form.md
+++ b/docs/components/form.md
@@ -109,6 +109,8 @@ If you need to post to a different route, then add an action prop:
- [Index Search Param][indexsearchparam] (index vs parent route disambiguation)
+Please see the [Splat Paths][relativesplatpath] section on the `useResolvedPath` docs for a note on the behavior of the `future.v7_relativeSplatPath` future flag for relative `useNavigate()` behavior within splat routes
+
## `method`
This determines the [HTTP verb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) to be used. The same as plain HTML [form method][htmlform-method], except it also supports "put", "patch", and "delete" in addition to "get" and "post". The default is "get".
@@ -394,3 +396,4 @@ You can access those values from the `request.url`
[history-state]: https://developer.mozilla.org/en-US/docs/Web/API/History/state
[use-view-transition-state]: ../hooks//use-view-transition-state
[view-transitions]: https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
+[relativesplatpath]: ../hooks/use-resolved-path#splat-paths
diff --git a/docs/components/link.md b/docs/components/link.md
index 9b415331f7..70a50876cd 100644
--- a/docs/components/link.md
+++ b/docs/components/link.md
@@ -63,6 +63,8 @@ A relative `` value (that does not begin with `/`) resolves relative to
`` with a `..` behaves differently from a normal `` when the current URL ends with `/`. `` ignores the trailing slash, and removes one URL segment for each `..`. But an `` value handles `..` differently when the current URL ends with `/` vs when it does not.
+Please see the [Splat Paths][relativesplatpath] section on the `useResolvedPath` docs for a note on the behavior of the `future.v7_relativeSplatPath` future flag for relative `` behavior within splat routes
+
## `relative`
By default, links are relative to the route hierarchy (`relative="route"`), so `..` will go up one `Route` level from the current contextual route. Occasionally, you may find that you have matching URL patterns that do not make sense to be nested, and you'd prefer to use relative _path_ routing from the current contextual route path. You can opt into this behavior with `relative="path"`:
@@ -202,3 +204,4 @@ function ImageLink(to) {
[view-transitions]: https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
[picking-a-router]: ../routers/picking-a-router
[navlink]: ./nav-link
+[relativesplatpath]: ../hooks/use-resolved-path#splat-paths
diff --git a/docs/guides/api-development-strategy.md b/docs/guides/api-development-strategy.md
index 7ef5cd4ab2..1944448301 100644
--- a/docs/guides/api-development-strategy.md
+++ b/docs/guides/api-development-strategy.md
@@ -63,11 +63,13 @@ const router = createBrowserRouter(routes, {
});
```
-| Flag | Description |
-| ------------------------ | --------------------------------------------------------------------- |
-| `v7_fetcherPersist` | Delay active fetcher cleanup until they return to an `idle` state |
-| `v7_normalizeFormMethod` | Normalize `useNavigation().formMethod` to be an uppercase HTTP Method |
-| `v7_prependBasename` | Prepend the router basename to navigate/fetch paths |
+| Flag | Description |
+| ------------------------------------------- | --------------------------------------------------------------------- |
+| `v7_fetcherPersist` | Delay active fetcher cleanup until they return to an `idle` state |
+| `v7_normalizeFormMethod` | Normalize `useNavigation().formMethod` to be an uppercase HTTP Method |
+| [`v7_partialHydration`][partialhydration] | Support partial hydration for Server-rendered apps |
+| `v7_prependBasename` | Prepend the router basename to navigate/fetch paths |
+| [`v7_relativeSplatPath`][relativesplatpath] | Fix buggy relative path resolution in splat routes |
### React Router Future Flags
@@ -94,3 +96,5 @@ These flags apply to both Data and non-Data Routers and are passed to the render
[feature-flowchart]: https://remix.run/docs-images/feature-flowchart.png
[picking-a-router]: ../routers/picking-a-router
[starttransition]: https://react.dev/reference/react/startTransition
+[partialhydration]: ../routers/create-browser-router#partial-hydration-data
+[relativesplatpath]: ../hooks/use-resolved-path#splat-paths
diff --git a/docs/guides/ssr.md b/docs/guides/ssr.md
index fae8ee1abb..ede4d67e08 100644
--- a/docs/guides/ssr.md
+++ b/docs/guides/ssr.md
@@ -165,6 +165,14 @@ And with that you've got a server-side-rendered and hydrated application! For a
As mentioned above, server-side rendering is tricky at scale and for production-grade applications, and we strongly recommend checking out [Remix][remix] if that's your goal. But if you are going the manual route, here's a few additional concepts you may need to consider:
+#### Hydration
+
+A core concept of Server Side Rendering is [hydration][hydration] which involves "attaching" a client-side React application to server-rendered HTML. To do this correctly, we need to create our client-side React Router application in the same state that it was in during the server render. When your server render loaded data via `loader` functions, we need to send this data up so that we can create our client router with the same loader data for the initial render/hydration.
+
+The basic usages of `` and `createBrowserRouter` shown in this guide handle this for you internally, but if you need to take control over the hydration process you can disable the automatic hydration process via [``][hydrate-false].
+
+In some advanced use cases, you may want to partially hydrate a client-side React Router application. You can do this via the [`future.v7_partialHydration`][partialhydration] flag passed to `createBrowserRouter`.
+
#### Redirects
If any loaders redirect, `handler.query` will return the `Response` directly so you should check that and send a redirect response instead of attempting to render an HTML document:
@@ -309,3 +317,6 @@ Again, we recommend you give [Remix](https://remix.run) a look. It's the best wa
[createstaticrouter]: ../routers/create-static-router
[staticrouterprovider]: ../routers/static-router-provider
[lazy]: ../route/lazy
+[hydration]: https://react.dev/reference/react-dom/client/hydrateRoot
+[hydrate-false]: ../routers/static-router-provider#hydrate
+[partialhydration]: ../routers/create-browser-router#partial-hydration-data
diff --git a/docs/hooks/use-href.md b/docs/hooks/use-href.md
index 680add0450..842e2e889d 100644
--- a/docs/hooks/use-href.md
+++ b/docs/hooks/use-href.md
@@ -18,8 +18,8 @@ declare function useHref(
The `useHref` hook returns a URL that may be used to link to the given `to` location, even outside of React Router.
-> **Tip:**
->
-> You may be interested in taking a look at the source for the ``
-> component in `react-router-dom` to see how it uses `useHref` internally to
-> determine its own `href` value.
+You may be interested in taking a look at the source for the `` component in `react-router-dom` to see how it uses `useHref` internally to determine its own `href` value
+
+Please see the [Splat Paths][relativesplatpath] section on the `useResolvedPath` docs for a note on the behavior of the `future.v7_relativeSplatPath` future flag for relative `useHref()` behavior within splat routes
+
+[relativesplatpath]: ../hooks/use-resolved-path#splat-paths
diff --git a/docs/hooks/use-navigate.md b/docs/hooks/use-navigate.md
index d8e25cabd8..4493b90228 100644
--- a/docs/hooks/use-navigate.md
+++ b/docs/hooks/use-navigate.md
@@ -54,6 +54,8 @@ The `navigate` function has two signatures:
- Either pass a `To` value (same type as ``) with an optional second `options` argument (similar to the props you can pass to [``][link]), or
- Pass the delta you want to go in the history stack. For example, `navigate(-1)` is equivalent to hitting the back button
+Please see the [Splat Paths][relativesplatpath] section on the `useResolvedPath` docs for a note on the behavior of the `future.v7_relativeSplatPath` future flag for relative `useNavigate()` behavior within splat routes
+
## `options.replace`
Specifying `replace: true` will cause the navigation to replace the current entry in the history stack instead of adding a new one.
@@ -119,3 +121,4 @@ The `unstable_viewTransition` option enables a [View Transition][view-transition
[picking-a-router]: ../routers/picking-a-router
[flush-sync]: https://react.dev/reference/react-dom/flushSync
[start-transition]: https://react.dev/reference/react/startTransition
+[relativesplatpath]: ../hooks/use-resolved-path#splat-paths
diff --git a/docs/hooks/use-resolved-path.md b/docs/hooks/use-resolved-path.md
index fcf4138809..efc70f8e71 100644
--- a/docs/hooks/use-resolved-path.md
+++ b/docs/hooks/use-resolved-path.md
@@ -22,5 +22,64 @@ This is useful when building links from relative values. For example, check out
See [resolvePath][resolvepath] for more information.
+## Splat Paths
+
+The original logic for `useResolvedPath` behaved differently for splat paths which in hindsight was incorrect/buggy behavior. This was fixed in [`6.19.0`][release-6.19.0] but it was determined that a large number of existing applications [relied on this behavior][revert-comment] so the fix was reverted in [`6.20.1`][release-6.20.1] and re-introduced in [`6.21.0`][release-6.21.0] behind a `future.v7_relativeSplatPath` [future flag][future-flag]. This will become the default behavior in React Router v7, so it is recommended to update your applications at your convenience to be better prepared for the eventual v7 upgrade.
+
+It should be noted that this is the foundation for all relative routing in React Router, so this applies to the following relative path code flows as well:
+
+- ``
+- `useNavigate()`
+- `useHref()`
+- `