@remix-run/router

Nested/Data-driven/Framework-agnostic Routing
- Static
- Latest Patch
- Latest Minor
- Latest Major
- 1.23.0
- 1.22.0
- 1.21.1
- 1.21.0
- 1.20.0
- 1.19.2
- 1.19.1
- 1.19.0
- 1.18.0
- 1.17.1
- 1.17.0
- 1.16.1
- 1.16.0
- 1.15.3
- 1.15.2
- 1.15.1
- 1.15.0
- 1.14.2
- 1.14.1
- 1.14.0
- 1.13.1
- 1.13.0
- 1.12.0
- 1.11.0
- 1.10.0
- 1.9.0
- 1.8.0
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.0
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.1
- 1.2.0
- 1.1.0
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- 0.1.0
- 1.23.0-pre-v6.0
- 1.22.0-pre-v6.1
- 1.21.2-pre-v6.0
- 1.21.1-pre.0
- 1.21.0-pre.0
- 1.20.0-pre.1
- 1.20.0-pre.0
- 1.19.2-pre.0
- 1.19.1-pre.0
- 1.19.0-pre.1
- 1.19.0-pre.0
- 1.18.0-pre.0
- 1.17.1-pre.0
- 1.17.0-pre.0
- 1.16.1-pre.0
- 1.16.0-pre.1
- 1.16.0-pre.0
- 1.15.3-pre.0
- 1.15.2-pre.0
- 1.15.1-pre.0
- 1.15.0-pre.0
- 1.14.2-pre.0
- 1.14.1-pre.0
- 1.14.0-pre.1
- 1.14.0-pre.0
- 1.13.1-pre.0
- 1.13.0-pre.0
- 1.12.0-pre.0
- 1.11.0-pre.1
- 1.11.0-pre.0
- 1.10.0-pre.0
- 1.9.0-pre.2
- 1.9.0-pre.1
- 1.9.0-pre.0
- 1.8.0-pre.0
- 1.7.2-pre.1
- 1.7.2-pre.0
- 1.7.1-pre.0
- 1.7.0-pre.0
- 1.6.3-pre.0
- 1.6.2-pre.0
- 1.6.1-pre.0
- 1.6.0-pre.0
- 1.5.0-pre.2
- 1.5.0-pre.1
- 1.5.0-pre.0
- 1.4.0-pre.0
- 1.3.3-pre.1
- 1.3.3-pre.0
- 1.3.2-pre.0
- 1.3.1-pre.0
- 1.3.0-pre.3
- 1.3.0-pre.2
- 1.3.0-pre.1
- 1.3.0-pre.0
- 1.2.1-pre.1
- 1.2.1-pre.0
- 1.2.0-pre.0
- 1.1.0-pre.1
- 1.1.0-pre.0
- 1.0.5-pre.2
- 1.0.5-pre.1
- 1.0.5-pre.0
- 1.0.4-pre.1
- 1.0.4-pre.0
- 1.0.3-pre.1
- 1.0.3-pre.0
- 1.0.2-pre.0
- 1.0.1-pre.0
- 0.2.0-pre.10
- 0.2.0-pre.9
- 0.2.0-pre.8
- 0.2.0-pre.7
- 0.2.0-pre.6
- 0.2.0-pre.5
- 0.2.0-pre.4
- 0.2.0-pre.3
- 0.2.0-pre.2
- 0.2.0-pre.1
- 0.2.0-pre.0
- 0.0.0-experimental-ff38e9e6
- 0.0.0-experimental-f92aa2e1
- 0.0.0-experimental-f8cbf972
- 0.0.0-experimental-f7aa35148
- 0.0.0-experimental-f728258d
- 0.0.0-experimental-f3b593c3
- 0.0.0-experimental-edf416237
- 0.0.0-experimental-e960cf1a
- 0.0.0-experimental-e7e9ce6e
- 0.0.0-experimental-e7ce8959
- 0.0.0-experimental-e6fb6e074
- 0.0.0-experimental-e192105b
- 0.0.0-experimental-e157216e3
- 0.0.0-experimental-e1311612e
- 0.0.0-experimental-e0f088aa
- 0.0.0-experimental-de419c3d
- 0.0.0-experimental-dc8656c8
- 0.0.0-experimental-dc307bdd5
- 0.0.0-experimental-db3389095
- 0.0.0-experimental-d90c8fb3
- 0.0.0-experimental-d7bf770a8
- 0.0.0-experimental-cffa549a1
- 0.0.0-experimental-cf9637ce
- 0.0.0-experimental-cec61865
- 0.0.0-experimental-ce5294fc
- 0.0.0-experimental-cbcd94b7
- 0.0.0-experimental-c9f8a7b2
- 0.0.0-experimental-c93c722c
- 0.0.0-experimental-c7dd3d3a
- 0.0.0-experimental-c5cae38f3
- 0.0.0-experimental-bcda00aaf
- 0.0.0-experimental-bc2c864b
- 0.0.0-experimental-ba938b84
- 0.0.0-experimental-b8437806
- 0.0.0-experimental-b3c9fc11b
- 0.0.0-experimental-b24023f3
- 0.0.0-experimental-b162e81d
- 0.0.0-experimental-af76d50e
- 0.0.0-experimental-add6f8aa
- 0.0.0-experimental-ad6954b7
- 0.0.0-experimental-acfea932
- 0.0.0-experimental-abead7ae1
- 0.0.0-experimental-a0888892
- 0.0.0-experimental-a077dc2d
- 0.0.0-experimental-9ffbba722
- 0.0.0-experimental-9c60e757e
- 0.0.0-experimental-9463fb5e
- 0.0.0-experimental-91f2bf54
- 0.0.0-experimental-8f9ef191
- 0.0.0-experimental-8bb3ffdf
- 0.0.0-experimental-88f4a9db3
- 0.0.0-experimental-832a0ee6
- 0.0.0-experimental-819a53c77
- 0.0.0-experimental-7f486334
- 0.0.0-experimental-7d87ffb8c
- 0.0.0-experimental-7c2094e9e
- 0.0.0-experimental-7b1bbb00
- 0.0.0-experimental-7a944bb54
- 0.0.0-experimental-73fcb9b28
- 0.0.0-experimental-71108452
- 0.0.0-experimental-7110596b
- 0.0.0-experimental-65d6b8c9
- 0.0.0-experimental-63b6834e
- 0.0.0-experimental-633882d6
- 0.0.0-experimental-5f6f59a6
- 0.0.0-experimental-5f08b33f
- 0.0.0-experimental-5df42afed
- 0.0.0-experimental-5bedc168
- 0.0.0-experimental-5a6545bf7
- 0.0.0-experimental-52e9b8eb3
- 0.0.0-experimental-519a1b654
- 0.0.0-experimental-4db3c3744
- 0.0.0-experimental-4a8a492a
- 0.0.0-experimental-4841e12b
- 0.0.0-experimental-48058118
- 0.0.0-experimental-432fcb2e
- 0.0.0-experimental-42adf24c
- 0.0.0-experimental-4286521e
- 0.0.0-experimental-3ec205f42
- 0.0.0-experimental-3e5084cc
- 0.0.0-experimental-3ce8d73c7
- 0.0.0-experimental-3be88c6fb
- 0.0.0-experimental-3ba3024e
- 0.0.0-experimental-35fa15e5
- 0.0.0-experimental-266d73f72
- 0.0.0-experimental-234a294e6
- 0.0.0-experimental-2272fa73
- 0.0.0-experimental-1e8b7a59
- 0.0.0-experimental-178bc9ee
- 0.0.0-experimental-15961e14
- 0.0.0-experimental-119d5d872
- 0.0.0-experimental-114cf0b7
- 0.0.0-experimental-1116190f7
- 0.0.0-experimental-0f302655
- 0.0.0-experimental-0f2dd78c
- 0.0.0-experimental-0db28b07
- 0.0.0-experimental-078ef8de9
- 0.0.0-experimental-0141b5ec
- 0.0.0-experimental-00c655af
Remix Router
The @remix-run/router
package is a framework-agnostic routing package (sometimes referred to as a browser-emulator) that serves as the heart of React Router and Remix and provides all the core functionality for routing coupled with data loading and data mutations. It comes with built-in handling of errors, race-conditions, interruptions, cancellations, lazy-loading data, and much, much more.
If you're using React Router, you should never import
anything directly from the @remix-run/router
- you should have everything you need in react-router-dom
(or react-router
/react-router-native
if you're not rendering in the browser). All of those packages should re-export everything you would otherwise need from @remix-run/router
.
[!WARNING]
This router is a low-level package intended to be consumed by UI layer routing libraries. You should very likely not be using this package directly unless you are authoring a routing library such as
react-router-dom
or one of it's other UI ports.
API
A Router instance can be created using createRouter
:
// Create and initialize a router. "initialize" contains all side effects
// including history listeners and kicking off the initial data fetch
let router = createRouter({
// Required properties
routes: [{
path: '/',
loader: ({ request, params }) => { /* ... */ },
children: [{
path: 'home',
loader: ({ request, params }) => { /* ... */ },
}]
},
history: createBrowserHistory(),
// Optional properties
basename, // Base path
mapRouteProperties, // Map framework-agnostic routes to framework-aware routes
future, // Future flags
hydrationData, // Hydration data if using server-side-rendering
}).initialize();
Internally, the Router represents the state in an object of the following format, which is available through router.state
. You can also register a subscriber of the signature (state: RouterState) => void
to execute when the state updates via router.subscribe()
;
interface RouterState {
// False during the initial data load, true once we have our initial data
initialized: boolean;
// The `history` action of the most recently completed navigation
historyAction: Action;
// The current location of the router. During a navigation this reflects
// the "old" location and is updated upon completion of the navigation
location: Location;
// The current set of route matches
matches: DataRouteMatch[];
// The state of the current navigation
navigation: Navigation;
// The state of any in-progress router.revalidate() calls
revalidation: RevalidationState;
// Data from the loaders for the current matches
loaderData: RouteData;
// Data from the action for the current matches
actionData: RouteData | null;
// Errors thrown from loaders/actions for the current matches
errors: RouteData | null;
// Map of all active fetchers
fetchers: Map<string, Fetcher>;
// Scroll position to restore to for the active Location, false if we
// should not restore, or null if we don't have a saved position
// Note: must be enabled via router.enableScrollRestoration()
restoreScrollPosition: number | false | null;
// Proxied `preventScrollReset` value passed to router.navigate()
preventScrollReset: boolean;
}
Navigations
All navigations are done through the router.navigate
API which is overloaded to support different types of navigations:
// Link navigation (pushes onto the history stack by default)
router.navigate("/page");
// Link navigation (replacing the history stack)
router.navigate("/page", { replace: true });
// Pop navigation (moving backward/forward in the history stack)
router.navigate(-1);
// Form submission navigation
let formData = new FormData();
formData.append(key, value);
router.navigate("/page", {
formMethod: "post",
formData,
});
// Relative routing from a source routeId
router.navigate("../../somewhere", {
fromRouteId: "active-route-id",
});
Fetchers
Fetchers are a mechanism to call loaders/actions without triggering a navigation, and are done through the router.fetch()
API. All fetch calls require a unique key to identify the fetcher.
// Execute the loader for /page
router.fetch("key", "/page");
// Submit to the action for /page
let formData = new FormData();
formData.append(key, value);
router.fetch("key", "/page", {
formMethod: "post",
formData,
});
Revalidation
By default, active loaders will revalidate after any navigation or fetcher mutation. If you need to kick off a revalidation for other use-cases, you can use router.revalidate()
to re-execute all active loaders.
Future Flags
We use Future Flags in the router to help us introduce breaking changes in an opt-in fashion ahead of major releases. Please check out the blog post and React Router Docs for more information on this process. The currently available future flags in @remix-run/router
are:
Flag | Description |
---|---|
v7_normalizeFormMethod |
Normalize useNavigation().formMethod to be an uppercase HTTP Method |
v7_prependBasename |
Prepend the basename to incoming router.navigate /router.fetch paths |