DataBrowserRouter
This is the recommended router for all React Router DOM applications.
DataBrowserRouter
enables the route data APIs like loaders, actions, fetchers and more for browser environments.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DataBrowserRouter } from "react-router-dom";
import Root from "./routes/root";
ReactDOM.render(
<DataBrowserRouter>
<Route element={<Root />} loader={Root.loader}>
<Route path="team" element={<Team />} loader={Team.loader}>
</Route>
</DataBrowserRouter>,
root
);
declare function DataBrowserRouter(
props: DataBrowserRouterProps
): React.ReactElement;
export interface DataBrowserRouterProps {
children?: React.ReactNode;
hydrationData?: HydrationState;
fallbackElement?: React.ReactElement;
window?: Window;
}
children
The children should always be Route
components.
<DataBrowserRouter initialEntries={["/events/123"]}>
<Route path="/" element={<Root />} loader={rootLoader}>
<Route
path="events/:id"
element={<Event />}
loader={eventLoader}
/>
</Route>
</DataBrowserRouter>
Unlike BrowserRouter
, you do not use Routes
.
<DataBrowserRouter initialEntries={["/events/123"]}>
<Routes>
<Route path="/" element={<Root />} loader={rootLoader}>
<Route
path="events/:id"
element={<Event />}
loader={eventLoader}
/>
</Route>
</Routes>
</DataBrowserRouter>
hydrationData
When server side rendering your React Router app, it's likely the server fetched data and included it into the HTML. In order for the client side hydration to work, the routes need to be able to render with the same data.
Typically, SSR implementations will provide that data on window
. The hydrationData
prop enables DataBrowserRouter
to render with the same data as the server without needing to fetch it again client side.
// hypothetical implementation where the server puts the hydration data on
// `window.routeData`
<DataBrowserRouter
hydrationData={{
// data for the loaders keyed by route ids
loaderData: {
"/": window._remix.routeData.root,
"/event/:id": window.routeData.event,
},
// data for an action, same shape as loaderData or null
actionData: null,
// if the server failed to load the data or render you can put the errors
// keyed by route ID here to trigger the route error boundaries
errors: null,
}}
/>
fallbackElement
If you are not server rendering your app, DataBrowserRouter
will initiate all matching route loaders when it mounts. During this time, you can provide a fallbackElement
to give the user some indication that the app is working.
<DataBrowserRouter fallbackElement={<SpinnerOfDoom />} />