Browse documentation
Agent docs/router/validated-search
recipe

Validate pagination and filter search params

Turn untrusted URL search params into stable, typed route input.

View raw Markdown
CONTRACT

Execution contract

Use when
Use for filters, sorting, pagination, or shareable view state owned by the URL.
Avoid when
Do not store secrets, transient input, or large values that cannot be safely serialized.
Preconditions
Define allowed keys, runtime validation, defaults, and the canonical serialized URL shape.
Verification
Test valid, missing, and malformed values; refresh, back, and shared links must restore the same view.
Failure mode
If an update clears other keys, verify the search updater merges from previous state instead of returning a partial object.
Security
URL input is untrusted; successful parsing does not make it safe for SQL, file paths, or outbound requests.
01

Contract

validateSearch receives parsed but untrusted values. Its return value becomes the search type seen by loaders, Route.useSearch(), and child routes.

02

Implementation

Give invalid page values a stable default and constrain status to an explicit union.

src/routes/issues/index.tsxtsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/issues/')({
  validateSearch: (search: Record<string, unknown>) => ({
    page: Math.max(1, Number(search.page) || 1),
    status: search.status === 'closed' ? 'closed' as const : 'open' as const,
  }),
  component: IssuesPage,
})

function IssuesPage() {
  const { page, status } = Route.useSearch()
  return <p>{status} issues · page {page}</p>
}
03

Common failures

Do not reparse search values in every component. Do not assume Number() yields a valid number. If the project already uses Zod or Valibot, reuse its existing schema.

PRIMARY SOURCEShttps://tanstack.com/router/latest/docs/guide/search-params
TanStack Atlas

Original bilingual knowledge · verified against primary sources

Friend linksGitHub