Zum Hauptinhalt springen

URL state (one typed spec for search params, navigate vs shallow writes)

Generated from pattern-library/registry.json — do not edit by hand; change the registry and run bun run patterns:build.

Category: Architecture & Request Pipeline · Tier: deep · Maturity: proven (verified 2026-10-23 @ 1a5496b-dirty) · Risk: low — a wrong mode shows up as a load that never re-runs (shallow for data) or charts that restart on every pick (navigate for view state)

Search params are read and written through one typed spec shared by loads and components — invalid input falls back instead of throwing, defaults never reach the URL, foreign params survive — and every write picks navigate (goto, the load re-runs) or shallow (replaceState from $app/navigation, no load, no navigation hooks), never raw history.

When to use: Use when sort, paging, a search term or a view selection must survive reload, sharing and back/forward.

Avoid when

  • The state is private or sensitive — tokens, emails, anything that must not land in logs, referrers or shared links
  • The state is large or structured enough to hit URL length limits; keep it server-side and put an id in the URL

Alternatives

  • runed useSearchParams or sveltekit-search-params — prefer when a dependency is acceptable and the app does not need the same spec in its server loads
  • Snapshots (export const snapshot) — prefer when the state should survive back/forward but must not be shareable

Docs

Code

  • src/lib/state/url-state.ts — urlParam codecs, readUrlState, writeUrlState, urlStateHref (GitHub · GitLab)
  • src/lib/state/url-state.svelte.ts — createUrlState: navigate vs shallow, debounce (GitHub · GitLab)
  • src/routes/[[locale=locale]]/admin/users/list-params.ts — A route-local spec the load and the page share (GitHub · GitLab)

Tests

  • src/lib/state/url-state.test.ts — Fallbacks on hostile input, clamping, canonical URLs, foreign params, round trip (GitHub · GitLab)
  • src/lib/state/url-state.svelte.test.ts — navigate writes via goto, shallow via replaceState with page.state, debounce (GitHub · GitLab)

Proof

Invariants

  • Every search param a page uses is parsed and written through one spec shared by its load and its component.
  • Reading never throws; an invalid value is the param's fallback.
  • A param equal to its fallback is never written, and params outside the spec are preserved.
  • No code writes history directly; view state uses shallow replaceState, load-driving state uses goto.

Emulation notes

  • Decide the write mode by asking whether any load reads the param — not by whether the URL should change.
  • Under shallow writes page.url stays at the loaded URL; read the values from the state object.
  • Give the component the same fallback the load parses with, or a param dropped from the URL means two different things.

Depends on


Machine-readable record: url-search-state in pattern-library/registry.json.

← Back to Pattern Library

Geht dieses Pattern noch besser? Sag uns, wie.

Feedback geben