UNPKG

wcz-layout

Version:

124 lines (112 loc) 4.35 kB
--- name: routing description: "Use when: creating or modifying TanStack Router routes, feature folders, navigation, permissions, loaders, suspense flows, or route-scoped components/hooks." --- ## Rules - Always include `requirePermission("all")` in the route's `beforeLoad` function to enforce access control unless the route is meant to be public. - Use `Route.useRouteContext()` to access the authenticated user. User can be `null` if the route doesn't include `requirePermission`. - Use the route `loader` option to preload db collections. Preload only root-level collections. - Create a `pendingComponent` for routes that suspend or preload meaningful data. - Route names must always be kebab-case. Entity route names must always be plural. - If a feature contains only one route, create a single file route: `src/routes/libraries.tsx` - If a feature contains multiple related routes, create a folder: `src/routes/libraries/index.tsx` - Colocate route-specific components/hooks inside `routes/<feature>/-components` or `-hooks`. - Root-level `components/` and `hooks/` are only for code shared across multiple routes. - After creating a new route, add or ask for a navigation item with a unique icon from `@mui/icons-material` in `src/routes/__root.tsx`. ## Base Project Structure ```txt src/ # client-first architecture ├── components/ # shared components across multiple routes ├── db-collections/ # tanstack-db collections ├── hooks/ # shared hooks across multiple routes ├── lib/ # contains isomorphic/shared logic usable by both client and server ├── auth/ ├── permissions.ts └── scopes.ts ├── locales/ ├── cs.json └── en.json └── schemas/ # shared zod schemas ├── routes/ # TanStack Router file-based routing ├── __root.tsx ├── index.tsx └── features/ # route group with multiple pages ├── -components/ # components specific to feature routes ├── -hooks/ # hooks specific to feature routes ├── index.tsx ├── create.tsx ├── edit.$id.tsx └── $id.tsx ├── server/ # server-only code ├── db/ ├── migrations/ ├── schemas/ # drizzle database schemas └── feature.ts └── index.ts # drizzle db instance ├── middleware/ └── databaseMiddleware.ts └── feature.ts # server functions / api logic └── types/ ``` ## Examples ```ts // imports import { useDialogs, useTranslation } from "wcz-layout/hooks"; import { requirePermission, uuidv7 } from "wcz-layout/utils"; // src/routes/features/create.tsx export const Route = createFileRoute("/features/create")({ component: RouteComponent, beforeLoad: requirePermission("all"), pendingComponent: FeatureSkeleton, loader: () => { featureCollection.preload(); }, }); function RouteComponent() { const { t } = useTranslation(); const { alert, confirm } = useDialogs(); const { user } = Route.useRouteContext(); // route component code... } // __root.tsx const { user } = Route.useRouteContext(); const navigation: Navigation = [ { kind: "item", to: "/", title: "Home", icon: <Home />, hidden: !user?.hasPermission("all"), }, { kind: "header", title: "Documentation", }, { kind: "group", title: "Components", icon: <Widgets />, children: [ { kind: "item", to: "/components/navigation", title: "Navigation", icon: <AccountTree />, }, { kind: "divider", }, { kind: "item", to: "/components/forms", title: "Forms", icon: <Code />, }, ], }, ]; // __root.tsx how to add public route <LayoutProvider {/* other props */} options={{ publicRoutes: ["/feature-name"] }}> ```