This skill should be used when the user asks to "add a route module", "scaffold a React Router page", "add a page route", "create a page component with routing", or "add a new route to the router".
Add a page slice and wire it into the React Router tree using createBrowserRouter.
routePath (required): URL path (e.g., /feed/articles, /billing/invoices/:id)pageSliceName (required): kebab-case name (e.g., feed-articles, billing-invoice-detail)layout (optional): existing layout component to wrap the pageauthGuard (optional): true to add an auth redirect check in the route loaderCreates:
apps/frontend/src/pages/<page-slice-name>/ui/page.tsx — page componentapps/frontend/src/pages/<page-slice-name>/index.ts — public APIModifies:
apps/frontend/src/app/router.ts — adds route entrycreateBrowserRouter configured in apps/frontend/src/app/router.tslayer=pages)Create pages/<page-slice-name>/ slice (FE-01 with layer=pages, segments=['ui'])
Create pages/<page-slice-name>/ui/page.tsx:
import type { FC } from 'react';
const <PageSliceName>Page: FC = () => {
return (
<main>
<h1>{/* TODO: page heading */}</h1>
</main>
);
};
export default <PageSliceName>Page;
pages/<page-slice-name>/index.ts:export { default as <PageSliceName>Page } from './ui/page';
apps/frontend/src/app/router.ts. Declare lazy at module scope (not inside the route config), then wrap in Suspense:import { lazy, Suspense } from 'react';
// Declare at module scope (before createBrowserRouter call):
const <PageSliceName>Page = lazy(() =>
import('../../../pages/<page-slice-name>').then((m) => ({ default: m.<PageSliceName>Page }))
);
// Add inside the createBrowserRouter routes array:
{
path: '<routePath>',
// If layout input provided, wrap <PageSliceName>Page in the layout component:
element: (
<Suspense fallback={null}>
<<PageSliceName>Page />
</Suspense>
),
// loader: authGuardLoader, // uncomment if authGuard: true
}
authGuard: true: add a loader function that checks auth state and redirects to the login page:import { redirect } from 'react-router-dom';
export const authGuardLoader = () => {
const token = localStorage.getItem('auth-token'); // TODO: use actual auth store
if (!token) return redirect('/login');
return null;
};
pnpm -C apps/frontend typecheckE_ROUTE_DUPLICATE: Path already registered → list existing routes and ask for a new pathE_TYPECHECK_UNAVAILABLE: typecheck script missing → run pnpm -C apps/frontend tsc --noEmit directlySee docs/project-overview.md → "FE-05 — React Router route module scaffold".