Thin TanStack Route Template
Section titled “Thin TanStack Route Template”Use this for dashboard route files.
Route files should stay focused on:
- route declaration
validateSearchloaderDeps- thin prefetch or loader orchestration
- handing off to a feature page entry
They should not own business logic, transport logic, or large component trees.
Canonical route file
Section titled “Canonical route file”import { createFileRoute } from "@tanstack/react-router";import { {feature}RouteOptions } from "@legaciti/feature-{feature}";
export const Route = createFileRoute("/{-$locale}/(dashboard)/{route}")( {feature}RouteOptions,);Canonical route options
Section titled “Canonical route options”import { getRouteApi } from "@tanstack/react-router";import type { QueryClient } from "@tanstack/react-query";import { {feature}Page } from "./pages/{Feature}Page";import { validate{Feature}Search } from "./model/search-params";import { {feature}ListQueryOptions } from "./queries";
const routeApi = getRouteApi("/{-$locale}/(dashboard)/{route}");
export const {feature}RouteOptions = { validateSearch: validate{Feature}Search, loaderDeps: ({ search }: { search: Partial<{Feature}Search> }) => ({ page: search.page ?? 1, q: search.q ?? "", }), loader: async ({ context, deps, }: { context: { queryClient: QueryClient }; deps: {Feature}Search; }) => { await context.queryClient.ensureQueryData({feature}ListQueryOptions(deps)); }, component: RoutePage,};
function RoutePage() { const params = routeApi.useParams(); const search = routeApi.useSearch(); return <{Feature}Page locale={params.locale} search={search} />;}Do not put this in a route file
Section titled “Do not put this in a route file”- raw server function imports
- data mapping or business rule helpers
- large JSX trees for page composition
- reusable query key definitions
- feature-specific mutation wiring