Path Params

Purpose and Scope

Path params are the route-path segments that turn part of a URL pathname into named data for a matched route. In TanStack Router, the guide defines the common form as a path segment prefixed with a dollar sign, such as a post identifier in a posts route. The segment matches only until the next slash, so it captures one pathname segment rather than the rest of the URL. This page explains how those params are declared, how they flow into route options, and how components read the same typed values through route-specific and global hooks.

Sources: docs/router/guide/path-params.md

Path params matter because they connect routing, data loading, and navigation into one typed contract. A route that declares a post identifier can use that identifier in its loader, can expose it to child routes, and can provide the same value to components that render under the match. The docs also distinguish between strict route-local access and looser access from arbitrary components, which is important when shared UI needs to read a parameter without being colocated in the route file. Treat the route path as the source of truth, and let Router infer the rest of the param shape.

Sources: docs/router/guide/path-params.md, docs/router/api/router/useParamsHook.md

Relevant Source Files

  • docs/router/guide/path-params.md — Defines the reader-facing path param model, examples for file routes, loader and beforeLoad usage, component hooks, child-route inheritance, and matching priority language for dynamic, optional, and wildcard routes.
  • docs/router/api/router/useParamsHook.md — Documents the public useParams hook contract, including strict mode, from-based selection, shouldThrow, select, structuralSharing, and the return value.
  • docs/router/api/router/RouteOptionsType.md — Documents route creation options that participate in param behavior, including path, parent route wiring, deprecated parseParams and stringifyParams, and the newer params parsing direction referenced by those deprecations.

Param Forms and Matching Model

The most direct param form is a required dynamic segment, written with a named dollar-prefixed segment in the route path. Examples in the guide include single-segment routes and nested-looking paths where only one segment is dynamic. Because each dynamic segment stops at the next slash, a route for a post can have child routes beneath it rather than needing one catch-all declaration. Once the parent match parses the value, descendants can also use it, so nested pages can rely on the parent identifier while adding their own route-specific UI, loaders, or validation.

Sources: docs/router/guide/path-params.md

Optional and splat-style params should be understood as broader matching tools around the same parsed-params idea. The guide calls out that multiple dynamic, optional, or wildcard routes can match the same URL, and that Router prioritizes the parsed path-param routes when deciding which route wins. Use required params when the segment is essential to the route identity, optional params when the route can represent both a base page and a more specific page, and splat or wildcard-style matching when a route intentionally accepts an open-ended remainder. Prefer the narrowest declaration that represents the URL shape, because it gives loaders, links, and hooks the clearest type information.

Sources: docs/router/guide/path-params.md

System-to-Code Mapping

The path declaration is the first piece of the system-to-code mapping. In file-based routing, the examples use createFileRoute with a path containing the parameter name. That path controls which URLs match and also gives TypeScript enough information to name the params object. The RouteOptions reference reinforces that routes are built from options, with a path property used for matching and getParentRoute required in code-based route construction so the route tree remains type safe. Parent relationships are not incidental: they determine which matches exist, which params are inherited, and where route APIs can safely read them.

Sources: docs/router/guide/path-params.md, docs/router/api/router/RouteOptionsType.md

Param parsing can also be customized at the route option layer. The RouteOptions reference documents older parseParams and stringifyParams hooks as deprecated in favor of params.parse and params.stringify, but the important behavior is still visible: raw path values are strings from the URL, a parser may transform or validate them, and a stringifier is needed when non-string params must be turned back into URL segments. If parsing throws, the route enters an error state. This makes route options the right place for canonical param interpretation rather than scattering ad hoc conversions across loaders and components.

Sources: docs/router/api/router/RouteOptionsType.md

Execution Flow

A typical required-param flow starts when the user visits a URL such as a blog post page. Router matches the route path, extracts the named segment from the pathname, and creates a params object for the match. The loader receives that params object, so it can fetch data for the exact entity identified by the URL. The same object is available to beforeLoad, which is useful for authorization, redirects, or early validation before the route component renders. Child routes inherit already-parsed params from their parent matches, so a nested comments route can still refer to the post identifier without redefining it.

Sources: docs/router/guide/path-params.md

Components usually read params through the route API that belongs to the route file. The guide shows Route.useParams in the same file as createFileRoute, which keeps the component tied to the exact route contract and preserves precise names such as the post identifier. For code-split components, the guide points readers toward getRouteApi so they can access the typed route API without importing the full route configuration into a lazy component file. This preserves the main workflow: define the param once in the route path, then consume the inferred typed value wherever that matched route is rendered.

Sources: docs/router/guide/path-params.md

API Components

The global useParams hook is for cases where a component is not written directly against a specific route API. Its reference says the hook returns all path parameters parsed for the closest match and its parent matches. In strict mode, callers can identify a route with from and get route-specific types. When strict is false, from is ignored and the result is loosened to a partial shape across all params, which reflects the ambiguity of reading from shared UI. The hook can also accept select to return a derived value and limit re-renders using shallow equality behavior.

Sources: docs/router/api/router/useParamsHook.md

The hook options are worth treating as part of the param contract, not just rendering details. shouldThrow defaults to true, so a missing match raises an invariant error; setting it false returns undefined instead, which is useful for optional shared UI. structuralSharing controls whether the selected return value participates in structural sharing, matching Router’s render-optimization model. These options let teams choose between strict correctness and flexible shared components. In route-owned components, prefer the route API. In reusable components that may render under several routes, use the global hook deliberately and document whether loose params are acceptable.

Sources: docs/router/api/router/useParamsHook.md

Compact Reference

import { createFileRoute, useParams } from '@tanstack/react-router'
 
export const Route = createFileRoute('/posts/$postId')({
  beforeLoad: async ({ params }) => {
    // params.postId is available before the route loads
  },
  loader: async ({ params }) => {
    return fetchPost(params.postId)
  },
  component: PostComponent,
})
 
function PostComponent() {
  const { postId } = Route.useParams()
  return <div>Post {postId}</div>
}
 
function SharedPostBadge() {
  const params = useParams({ strict: false })
  return params.postId ? <span>{params.postId}</span> : null
}

Key public names for this topic include the route path property, createFileRoute, Route.useParams, the global useParams hook, beforeLoad, loader, parseParams, stringifyParams, params.parse, and params.stringify. The route path names the params, loader and beforeLoad consume them during navigation, and component hooks consume them during render. Links and imperative navigation should use the same typed route information so that generated URLs provide the required values for required segments and respect any optional or wildcard route shape chosen for the route tree.

Sources: docs/router/guide/path-params.md, docs/router/api/router/useParamsHook.md, docs/router/api/router/RouteOptionsType.md

Next Steps

When adding a param route, first decide whether the segment is required, optional, or a wildcard-style remainder. Then define it in the route path, fetch or guard with it in loader or beforeLoad, and read it with the narrowest hook available to the component. If the value needs validation or conversion, centralize that in the route param parsing options instead of repeating conversion logic. Continue with the Type Safety, Data Loading, Navigation and Links, and Not Found or Redirects pages to see how params interact with generated links, loader dependencies, and error handling.