Skip to content

Add support for AbsoluteRoutes/useAbsoluteRoutes #13877

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions docs/components/absolute-routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: AbsoluteRoutes
---

# `<AbsoluteRoutes>`

Rendered anywhere in the app, `<AbsoluteRoutes>` will match a set of child routes using absolute paths against the current [location][location] pathname.

```tsx
interface AbsoluteRoutesProps {
children?: React.ReactNode;
location?: Partial<Location> | string;
}
```

<docs-info>If you're using a data router like [`createBrowserRouter`][createbrowserrouter] it is uncommon to use this component as routes defined as part of a descendant `<AbsoluteRoutes>` tree cannot leverage the [Data APIs][data-apis] available to [`RouterProvider`][router-provider] apps. You **can and should** use this component within your `RouterProvider` application [while you are migrating][migrating-to-router-provider].</docs-info>

<docs-warning>This component is strictly a utility to be used to assist in migration from v5 to v6 so that folks can use absolute paths in descendant route definitions (which was a common pattern in RR v5). The intent is to remove this component in v7 so it is marked "deprecated" from the start as a reminder to work on moving your route definitions upwards out of descendant routes.<br/><br/>We expect the concept of "descendant routes" to be replaced by [Lazy Route Discovery][lazy-route-discovery-rfc] when that feature lands, so the plan is that folks can use `<AbsoluteRoutes>` to migrate from v5 to v6. Then, incrementally migrate those descendant routes to lazily discovered route `children` while on v6. Then when an eventual v7 releases, there will be no need for `AbsoluteRoutes` and it can be safely removed.</docs-warning>

Whenever the location changes, `<AbsoluteRoutes>` looks through all its child routes to find the best absolute-path match and renders that branch of the UI. `<Route>` elements may be nested to indicate nested UI, but their paths should all be specified via absolute paths. Parent routes render their child routes by rendering an [`<Outlet>`][outlet].

```tsx
function App() {
return (
<AbsoluteRoutes>
<Route path="/" element={<h1>Home</h1>} />
<Route path="/auth/*" element={<Auth />} />
</AbsoluteRoutes>
);
}

function Auth() {
return (
<AbsoluteRoutes>
<Route path="/auth" element={<AuthLayout />}>
<Route path="/auth" element={<AuthHome />} />
<Route path="/auth/login" element={<AuthLogin />} />
</Route>
</AbsoluteRoutes>
);
}
```

See also:

- [`<Routes>`][routes]

[location]: ../utils/location
[outlet]: ./outlet
[createbrowserrouter]: ../routers/create-browser-router
[data-apis]: ../routers/picking-a-router#data-apis
[router-provider]: ../routers/router-provider
[migrating-to-router-provider]: ../upgrading/v6-data
[lazy-route-discovery-rfc]: https://github.com/remix-run/react-router/discussions/11113
[routes]: ./routes
64 changes: 64 additions & 0 deletions docs/hooks/use-absolute-routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: useAbsoluteRoutes
---

# `useAbsoluteRoutes`

<details>
<summary>Type declaration</summary>

```tsx
declare function useAbsoluteRoutes(
routes: RouteObject[],
location?: Partial<Location> | string;
): React.ReactElement | null;
```

</details>

The `useAbsoluteRoutes` hook is the functional equivalent of [`<AbsoluteRoutes>`][absoluteroutes], but it uses JavaScript objects instead of `<Route>` elements to define your routes. These objects have the same properties as normal [`<Route>` elements][route], but they don't require JSX.

All route paths passed to `useAbsoluteRoutes` should be defined using absolute paths.

<docs-warning>This component is strictly a utility to be used to assist in migration from v5 to v6 so that folks can use absolute paths in descendant route definitions (which was a common pattern in RR v5). The intent is to remove this component in v7 so it is marked "deprecated" from the start as a reminder to work on moving your route definitions upwards out of descendant routes.<br/><br/>We expect the concept of "descendant routes" to be replaced by [Lazy Route Discovery][lazy-route-discovery-rfc] when that feature lands, so the plan is that folks can use `<AbsoluteRoutes>` to migrate from v5 to v6. Then, incrementally migrate those descendant routes to lazily discovered route `children` while on v6. Then when an eventual v7 releases, there will be no need for `AbsoluteRoutes` and it can be safely removed.</docs-warning>

The return value of `useAbsoluteRoutes` is either a valid React element you can use to render the route tree, or `null` if nothing matched.

```tsx
import * as React from "react";
import { useAbsoluteRoutes } from "react-router-dom";

function App() {
return (
<AbsoluteRoutes>
<Route path="/" element={<h1>Home</h1>} />
<Route path="/auth/*" element={<Auth />} />
</AbsoluteRoutes>
);
}

function Auth() {
let element = useAbsoluteRoutes([
path: "/auth",
element: <AuthLayout />,
children: [{
path: "/auth",
element: AuthHome,
}, {
path: "/auth/login",
element: AuthLogin,
}],
}]);

return element;
}
```

See also:

- [`useRoutes`][useroutes]

[absoluteroutes]: ../components/absolute-routes
[route]: ../components/route
[lazy-route-discovery-rfc]: https://github.com/remix-run/react-router/discussions/11113
[useroutes]: ./use-routes
3 changes: 3 additions & 0 deletions packages/react-router-dom-v5-compat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
* deprecate the deep require if we wanted to avoid the duplication here.
*/
export type {
AbsoluteRoutesProps,
ActionFunction,
ActionFunctionArgs,
AwaitProps,
Expand Down Expand Up @@ -112,6 +113,7 @@ export type {
} from "./react-router-dom";
export {
AbortedDeferredError,
AbsoluteRoutes,
Await,
BrowserRouter,
Form,
Expand Down Expand Up @@ -155,6 +157,7 @@ export {
unstable_HistoryRouter,
useBlocker,
unstable_usePrompt,
useAbsoluteRoutes,
useActionData,
useAsyncError,
useAsyncValue,
Expand Down
3 changes: 3 additions & 0 deletions packages/react-router-dom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export { createSearchParams };

// Note: Keep in sync with react-router exports!
export type {
AbsoluteRoutesProps,
ActionFunction,
ActionFunctionArgs,
AwaitProps,
Expand Down Expand Up @@ -146,6 +147,7 @@ export type {
} from "react-router";
export {
AbortedDeferredError,
AbsoluteRoutes,
Await,
MemoryRouter,
Navigate,
Expand All @@ -169,6 +171,7 @@ export {
redirectDocument,
renderMatches,
resolvePath,
useAbsoluteRoutes,
useActionData,
useAsyncError,
useAsyncValue,
Expand Down
3 changes: 3 additions & 0 deletions packages/react-router-native/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import URLSearchParams from "@ungap/url-search-params";

// Note: Keep in sync with react-router exports!
export type {
AbsoluteRoutesProps,
ActionFunction,
ActionFunctionArgs,
AwaitProps,
Expand Down Expand Up @@ -71,6 +72,7 @@ export type {
} from "react-router";
export {
AbortedDeferredError,
AbsoluteRoutes,
Await,
MemoryRouter,
Navigate,
Expand All @@ -95,6 +97,7 @@ export {
redirectDocument,
renderMatches,
resolvePath,
useAbsoluteRoutes,
useActionData,
useAsyncError,
useAsyncValue,
Expand Down
Loading