The remix-run/react-router demo shows wrapping each lazily imported component in their own React.Suspense component:
import React from "react";
import { Route } from "react-router-dom";
const PublicLayout = React.lazy(() => "../Layouts/PublicLayout");
const PrivateLayout = React.lazy(() => "../Layouts/PrivateLayout");
const Index = React.lazy(() => "../Pages");
const Welcome = React.lazy(() => "../Pages/Welcome");
const Login = React.lazy(() => "../Pages/Login");
const Register = React.lazy(() => "../Pages/Register");
const Root = (
<Route
path="/"
element={(
<React.Suspense fallback={<>...</>}>
<Index />
</React.Suspense>
)}
>
<Route
element={(
<React.Suspense fallback={<>...</>}>
<PublicLayout />
</React.Suspense>
)}
>
<Route
path="/login"
element={(
<React.Suspense fallback={<>...</>}>
<Login />
</React.Suspense>
)}
/>
<Route
path="/register"
element={(
<React.Suspense fallback={<>...</>}>
<Register />
</React.Suspense>
)}
/>
</Route>
<Route
element={(
<React.Suspense fallback={<>...</>}>
<PrivateLayout />
</React.Suspense>
)}
>
<Route
path="/welcome"
element={(
<React.Suspense fallback={<>...</>}>
<Welcome />
</React.Suspense>
)}
/>
</Route>
</Route>
);
export default Root;
React.lazy
You can place the Suspense component anywhere above the lazy
component. You can even wrap multiple lazy components with a single
Suspense component.
You could also create a layout route that wraps a React.Suspense around an Outlet component.
Example:
import React from "react";
import { Route } from "react-router-dom";
const PublicLayout = React.lazy(() => "../Layouts/PublicLayout");
const PrivateLayout = React.lazy(() => "../Layouts/PrivateLayout");
const Index = React.lazy(() => "../Pages");
const Welcome = React.lazy(() => "../Pages/Welcome");
const Login = React.lazy(() => "../Pages/Login");
const Register = React.lazy(() => "../Pages/Register");
const SuspenseLayout = () => (
<React.Suspense fallback={<>...</>}>
<Outlet />
</React.Suspense>
);
const Root = (
<Route element={<SuspenseLayout />}>
<Route path="/" element={<Index />}>
<Route element={<PublicLayout />}>
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
</Route>
<Route element={<PrivateLayout />}>
<Route path="/welcome" element={<Welcome />} />
</Route>
</Route>
</Route>
);
export default Root;
Since the React.Suspense component just needs to be higher in the tree than the lazy component, you might also wrap the RouterProvider in Navigation in the Suspense component.
import React from "react";
import {
RouterProvider,
createBrowserRouter,
createRoutesFromElements
} from "react-router-dom";
import Root from "./Root";
const router = createBrowserRouter(createRoutesFromElements(Root));
const Navigation = () => {
return (
<React.Suspense fallback={<>...</>}>
<RouterProvider router={router} />
</React.Suspense>
);
};
export default Navigation;