Browse documentation
Lesson 04 · URL state

Put filters in the URL

Build shareable, refresh-safe, typed issue filters with validated search params.

TanStack RouterCore18 minREV 02Markdown .md
After this lesson

Decide what belongs in the URL and give it stable defaults.

01

Search params are external input

Users can edit URLs and old bookmarks can contain stale data. Validate at the route boundary instead of scattering Number() calls through components.

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' : 'open',
  }),
  component: IssuesPage,
})

function IssuesPage() {
  const filters = Route.useSearch()
  return <p>Page {filters.page} · {filters.status}</p>
}
02

What belongs in the URL

Filters, sorting, pagination, and selected tabs usually belong in the URL because users share, bookmark, navigate, and refresh them. Transient details like hover state do not.

PRACTICE

Turn this lesson into a verifiable skill

Completion checkpoint

Filters, status, and page restore from the URL, so refreshes and shared links preserve the view.

Exercise

Add a priority filter with a default and omit that default when writing the URL.

Verification

An invalid page value should fall back safely, while a valid copied URL should reproduce the same filtered result.

Common pitfalls
  • Using a TypeScript assertion without runtime validation.
  • Accidentally clearing unrelated search parameters while updating one filter.
SOURCE REFERENCES · CHECKED 2026-08-03https://tanstack.com/router/latest/docs/guide/search-params
TanStack Atlas

Original bilingual knowledge · verified against primary sources

Friend linksGitHub