React Router is a multi-strategy router for React. There are three primary ways, or "modes", to use it in your app. Across the docs you'll see these icons indicating which mode the content is relevant to.
The features available in each mode are additive, so moving from Declarative to Data to Framework simply adds more features at the cost of architectural control. So pick your mode based on how much control or how much help you want from React Router.
The mode depends on which "top level" router API you're using:
Declarative
Declarative mode enables basic routing features like matching URLs to components, navigating around the app, and providing active states with APIs like <Link>
, useNavigate
, and useLocation
.
import { BrowserRouter } from "react-router";
ReactDOM.createRoot(root).render(
<BrowserRouter>
<App />
</BrowserRouter>
);
Data
By moving route configuration outside of React rendering, Data Mode adds data loading, actions, pending states and more with APIs like loader
, action
, and useFetcher
.
import {
createBrowserRouter,
RouterProvider,
} from "react-router";
let router = createBrowserRouter([
{
path: "/",
Component: Root,
loader: loadRootData,
},
]);
ReactDOM.createRoot(root).render(
<RouterProvider router={router} />
);
Framework
Framework Mode wraps Data Mode with a Vite plugin to add the full React Router experience with:
href
import { index, route } from "@react-router/dev/routes";
export default [
index("./home.tsx"),
route("about", "./about.tsx"),
];
Every mode supports any architecture and deployment target, so the question isn't really about if you want SSR, SPA, etc. It's about how much you want to do yourself.
Use Framework Mode if you are:
→ Get Started with Framework Mode.
Use Data Mode if you:
Use Declarative Mode if you:
<BrowserRouter>
→ Get Started with Declarative Mode.
This is mostly for the LLMs, but knock yourself out:
API | Framework | Data | Declarative |
---|---|---|---|
Await | ✅ | ✅ | |
Form | ✅ | ✅ | |
Link | ✅ | ✅ | ✅ |
<Link discover> |
✅ | ||
<Link prefetch> |
✅ | ||
<Link preventScrollReset> |
✅ | ✅ | |
Links | ✅ | ||
Meta | ✅ | ||
NavLink | ✅ | ✅ | ✅ |
<NavLink discover> |
✅ | ||
<NavLink prefetch> |
✅ | ||
<NavLink preventScrollReset> |
✅ | ✅ | |
NavLink isPending |
✅ | ✅ | |
Navigate | ✅ | ✅ | ✅ |
Outlet | ✅ | ✅ | ✅ |
PrefetchPageLinks | ✅ | ||
Route | ✅ | ✅ | ✅ |
Routes | ✅ | ✅ | ✅ |
Scripts | ✅ | ||
ScrollRestoration | ✅ | ✅ | |
ServerRouter | ✅ | ||
usePrompt | ✅ | ✅ | ✅ |
useActionData | ✅ | ✅ | |
useAsyncError | ✅ | ✅ | |
useAsyncValue | ✅ | ✅ | |
useBeforeUnload | ✅ | ✅ | ✅ |
useBlocker | ✅ | ✅ | ✅ |
useFetcher | ✅ | ✅ | |
useFetchers | ✅ | ✅ | |
useFormAction | ✅ | ✅ | |
useHref | ✅ | ✅ | ✅ |
useInRouterContext | ✅ | ✅ | ✅ |
useLinkClickHandler | ✅ | ✅ | ✅ |
useLoaderData | ✅ | ✅ | |
useLocation | ✅ | ✅ | ✅ |
useMatch | ✅ | ✅ | ✅ |
useMatches | ✅ | ✅ | |
useNavigate | ✅ | ✅ | ✅ |
useNavigation | ✅ | ✅ | |
useNavigationType | ✅ | ✅ | ✅ |
useOutlet | ✅ | ✅ | ✅ |
useOutletContext | ✅ | ✅ | ✅ |
useParams | ✅ | ✅ | ✅ |
useResolvedPath | ✅ | ✅ | ✅ |
useRevalidator | ✅ | ✅ | |
useRouteError | ✅ | ✅ | |
useRouteLoaderData | ✅ | ✅ | |
useRoutes | ✅ | ✅ | ✅ |
useSearchParams | ✅ | ✅ | ✅ |
useSubmit | ✅ | ✅ | |
useViewTransitionState | ✅ | ✅ | ✅ |
isCookieFunction | ✅ | ✅ | |
isSessionFunction | ✅ | ✅ | |
createCookie | ✅ | ✅ | |
createCookieSessionStorage | ✅ | ✅ | |
createMemorySessionStorage | ✅ | ✅ | |
createPath | ✅ | ✅ | ✅ |
createRoutesStub | ✅ | ✅ | |
createSearchParams | ✅ | ✅ | ✅ |
data | ✅ | ✅ | |
generatePath | ✅ | ✅ | ✅ |
href | ✅ | ||
isCookie | ✅ | ✅ | |
isRouteErrorResponse | ✅ | ✅ | |
isSession | ✅ | ✅ | |
matchPath | ✅ | ✅ | ✅ |
matchRoutes | ✅ | ✅ | ✅ |
parsePath | ✅ | ✅ | ✅ |
redirect | ✅ | ✅ | |
redirectDocument | ✅ | ✅ | |
renderMatches | ✅ | ✅ | ✅ |
replace | ✅ | ✅ | |
resolvePath | ✅ | ✅ | ✅ |