Capítulo 27 de 57
TanStack Router treats URL search params as first-class, JSON-typed application state (not raw URLSearchParams strings), providing automatic JSON serialization, a validateSearch step for typed/validated access, and composable middlewares to transform search params on every generated link.
URLSearchParams: It assumes flat string-only values, has no reliable nested-object/array support, and offers no validation layer; search params represent real app state (page number, filters) and deserve equivalent DX to other state managers, including referential integrity concerns.validateSearch: A Route option that takes the raw parsed Record<string, unknown> and returns a typed, validated object; this type flows to loader, beforeLoad, components, and is inherited by all child routes. Throwing inside validateSearch triggers the route's onError/errorComponent with error.routerCode === 'VALIDATE_SEARCH'.zodValidator, fallback() for typed defaults in Zod v3; Zod v4 schemas can be used directly), Valibot, ArkType, and Effect/Schema all integrate via Standard Schema or a dedicated adapter, giving typed input/output shapes for navigation vs. reading.Route.useSearch(): Reads validated search params inside the owning route's component.useSearch({ from, strict: false }): Reads search params outside a route's own component; strict: false loosens typing to allow reading from any route context.beforeLoad/component sees its own plus all parent routes' validated search fields.<Link search /> / navigate({ search }): Accept an object or an updater function (prev) => next to write search params; to="." combined with search={(prev) => ({...prev, ...})} updates search params without needing a typed from.({ search, next }) => result registered via search.middlewares on a route (commonly the root route) that transform search params whenever a link/href is built for that route or its descendants, and also run after search validation on navigation.retainSearchParams(keys): Built-in middleware that always carries specified search keys through to newly generated links if present in current search.stripSearchParams(defaults): Built-in middleware that omits search params from generated links when they equal their default value, keeping URLs clean.import { z } from 'zod'
const productSearchSchema = z.object({
page: z.number().catch(1),
filter: z.string().catch(''),
sort: z.enum(['newest', 'oldest', 'price']).catch('newest'),
})
export const Route = createFileRoute('/shop/products')({
validateSearch: productSearchSchema,
})
validateSearch using .catch() to silently fall back to defaults rather than erroring on malformed search params.export const Route = createRootRoute({
validateSearch: zodValidator(searchSchema),
search: {
middlewares: [retainSearchParams(['rootValue']), stripSearchParams(defaultValues)],
},
})
validateSearch (ideally via a schema library adapter) rather than trusting the raw parsed JSON, since search params originate as user-facing raw text..catch()/fallback-style validation over .default()-only when a malformed search param shouldn't interrupt the user's experience with an error screen.retainSearchParams, stripSearchParams, or custom ones) are the mechanism for cross-cutting search-param behavior (e.g. always keep a rootValue, always hide default-valued params) applied uniformly to every generated link.search field within ToOptions this chapter details.