URLs are state containers
What “state in the URL” means
- Debate over terminology: some say a URL only locates state (per REST’s “resource” and “locator”), others argue a location that fully determines state is itself a valid “state description”.
- Distinction between:
- Navigational/client state (where the user is in the app, filters, selection) vs
- Application/server state (data in DB, sessions, workflows).
- HATEOAS discussion: hypermedia links encode possible continuations of application state, but that’s about discoverability and representation, not necessarily about stuffing client state into URLs.
Benefits of encoding state in URLs
- Better UX: refresh, back/forward, duplicate tab, reopening a closed tab, and deep-linking all behave predictably when state is derivable from the URL.
- Shareability and bookmarking: others can “see what you saw”; good for complex filters, map locations, dashboards, radar views, diagrams, and games with no backend.
- Developer benefits: easier debugging (“send me the URL”), quicker iteration, clearer mental model of state, and pressure to keep state manageable.
- Works well for idempotent/content-generating views where the same inputs always yield the same output.
Drawbacks, risks, and tradeoffs
- Permanence vs evolution: URLs are expected to be stable, but state schemas change; this creates versioning and migration burdens and potential bookmark breakage.
- Leakage: URLs are user-controlled, logged, forwarded, scraped, and may reveal internal or identifying state if misused.
- Length and aesthetics: very long, encoded URLs are ugly, hard to share in some apps, and can bump into practical limits.
- SEO and bots: parameter-heavy URLs can create many crawlable variants and odd search behavior.
- Treating URLs as a public API forces more careful compatibility guarantees.
UX, history, and when not to use URLs
- Users often expect refresh to reset problematic state, not reapply it; similarly, many don’t intend to share scroll position or incidental modal states.
- Some dislike history “pollution” (e.g., each modal or keystroke as a new entry); others insist careful use of
pushStatevsreplaceStatecan reconcile granular state with clean history. - Not all state belongs in URLs: themes, ephemeral UI tweaks, and purely session-specific data are cited as better fits for cookies, sessions, or local storage.
Implementation patterns and tools
- Common approaches: query params, fragments (
#), base64/gzip’d JSON, custom compact formats (e.g., rison), sometimes with signing or version tags. - Alternatives/adjuncts: server-side sessions, cookies, local/session storage, or treating the URL as a “descriptor” that keys into server-held state.
- Several libraries and examples are shared for React and other stacks to synchronize component state with the URL more ergonomically.