Type-Safe Path Params in TanStack Router
TanStack Router parses segments like $slug or $id in file names at route-tree generation time, and uses that to infer parameter names and types for every useParams() call and every <Link params={{ ... }}> you write. For example, if src/routes/$locale/blog/$slug.tsx exists, any <Link to="/$locale/blog/$slug" params={{ locale, slug }}> pointing at it will fail to type-check the moment you forget a param or typo one.
Path params are strings by default, but if you need a specific shape — a numeric ID, for instance — you can add params.parse to the route definition.
export const Route = createFileRoute('/$locale/posts/$postId')({
params: {
parse: (raw) => ({ postId: Number(raw.postId) }),
stringify: (parsed) => ({ postId: String(parsed.postId) }),
},
loader: ({ params }) => fetchPost(params.postId), // params.postId: number
})
The file path becoming the type declaration is the single biggest payoff of file-based routing.
Because every page in this project is nested under the /$locale layout route, the locale param is automatically part of every child route's params. Narrowing the runtime value with an isLocale() guard is enough to safely pass it into locale-aware functions like getBlogEntry(slug, locale).