Routing
Jumbo React Vite uses React Router 7 with createBrowserRouter and RouterProvider. The router
maps URL prefixes to layout shell components and delegates page-level routes to per-demo route
files.
Router setup
The router is created once in src/routes/index.tsx and passed to <RouterProvider> in App.tsx:
// src/App.tsx
import { RouterProvider } from 'react-router-dom';
import { router } from './routes';
function App() {
return (
// ... providers ...
<RouterProvider router={router} />
);
}Top-level route structure
Each top-level route maps a URL prefix to a layout shell and uses generateChildRoutes() to attach
the page routes as children:
// src/routes/index.tsx
const routes: RouteObject[] = [
{
path: '/',
element: <StretchedLayout />,
children: generateChildRoutes(demoRoutes),
},
{
path: '/demo-1',
element: <Demo1Layout />,
children: generateChildRoutes(demoRoutes, '/demo-1'),
},
{
path: '/demo-2',
element: <Demo2Layout />,
children: generateChildRoutes(demo2Routes, '/demo-2'),
},
{
path: '/demo-3',
element: <Demo3Layout />,
children: generateChildRoutes(demo3Routes, '/demo-3'),
},
{
path: '/demo-4',
element: <Demo4Layout />,
children: generateChildRoutes(demo4Routes, '/demo-4'),
},
{
path: '/auth',
element: <SoloLayout />,
children: generateChildRoutes(authRoutes, '/auth'),
},
{
path: '/extra-pages',
element: <SoloLayout />,
children: generateChildRoutes(extraRoutes, '/extra-pages'),
},
{
path: '*',
element: <NotFound />,
},
];
export const router = createBrowserRouter(routes);generateChildRoutes()
generateChildRoutes() in src/utilities/helpers/index.tsx prefixes all child paths with a base
path, enabling the same page route definitions to be reused across multiple layout prefixes:
// src/utilities/helpers/index.tsx
export function generateChildRoutes(
pages: RouteObject[],
basePath: string = ''
): RouteObject[] {
return pages.map((page) => ({
...page,
path: `${basePath}${page.path}`,
children: page.children
? generateChildRoutes(page.children, `${basePath}${page.path}/`)
: [],
}));
}For example, the route { path: '/dashboards/misc', element: <MiscPage /> } in demoRoutes
becomes /demo-1/dashboards/misc when passed with basePath: '/demo-1'.
Page route files
| File | Layout prefix | Default home |
|---|---|---|
src/routes/demo-routes.tsx | / and /demo-1, /demo-4 | /dashboards/misc |
src/routes/demo2-routes.tsx | /demo-2 | Social wall |
src/routes/demo3-routes.tsx | /demo-3 | Public profile |
src/routes/demo4-routes.tsx | /demo-4 | /dashboards/misc |
src/routes/solo-routes.tsx | /auth, /extra-pages | Login |
The Page wrapper
Most routes use the Page component to optionally apply a HOC before rendering:
// src/routes/demo-routes.tsx (excerpt)
{
path: '/dashboards/misc',
element: <Page Component={MiscPage} hoc={withAuth} />,
},// src/components/Page/Page.tsx
const Page = ({ Component, hoc }: PageProps) => {
if (hoc) {
const WrappedComponent = hoc(Component);
return <WrappedComponent />;
}
return <Component />;
};Route protection with withAuth
withAuth is a HOC that checks authentication state before rendering a page. Unauthenticated users
are redirected to /auth/login-1:
// src/hoc/withAuth.tsx
const withAuth = (Component: React.ComponentType) => {
return (): React.JSX.Element | null => {
const { isAuthenticated, loading } = useAuth();
if (loading) return <Spinner />;
if (!isAuthenticated) return <Navigate to='/auth/login-1' />;
return <Component />;
};
};Pass hoc={withAuth} on every protected route. Auth pages (login, signup) omit the HOC.
Adding a new page
Create the page component
Add a new file in the appropriate
src/pages/<category>/directory:tsx// src/pages/dashboards/AnalyticsPage.tsx export function AnalyticsPage() { return <div>Analytics</div>; }Register the route
Add an entry to the relevant route file:
typescript// src/routes/demo-routes.tsx import { AnalyticsPage } from '@/pages/dashboards/AnalyticsPage'; // Inside the routes array: { path: '/dashboards/analytics', element: <Page Component={AnalyticsPage} hoc={withAuth} />, },Add a nav item (optional)
Add an entry to the menus file of the layout you want to show it in:
typescript// src/layouts/StretchedLayout/menus.ts { label: 'Analytics', path: '/dashboards/analytics' }
React Router uses the HTML5 History API. Any server serving the production build must send
index.html for all routes. The included vercel.json handles this for Vercel. For other
hosts, configure a /* → /index.html rewrite rule. See the
Deployment guide for platform-specific
instructions.