All search state serialized into URL query parameters for back/forward navigation
Why it matters
When search state lives only in client memory, the back button becomes useless, sharing a result page over Slack or email delivers the unfiltered homepage, and refreshing the tab wipes every refinement. Users expect URLs to be durable addresses — breaking that contract means every deep link from Google, Reddit, or a friend lands on the wrong state. URL-synced state is also the only reliable way to give users back/forward history through their filter exploration, which doubles as an undo stack.
Severity rationale
Critical because URL-less state breaks sharability, bookmarks, back/forward navigation, and SEO indexing of filtered views.
Remediation
Drive all filter, sort, and pagination state through URLSearchParams and router.push. Read initial values from useSearchParams on mount so the URL is the single source of truth. Edit app/listings/search/page.tsx:
const updateFilters = (next) => {
const params = new URLSearchParams(searchParams)
Object.entries(next).forEach(([k, v]) => v ? params.set(k, v) : params.delete(k))
router.push(`?${params}`)
}
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Search & Discovery UX Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
Taxons
History
- 2026-04-18·v1.0.0·Initial import from directory-search-discovery·automated