useSearchNavigate: Type-Safe URL State Without the Drift
A small hook over TanStack Router's navigate that keeps tabs, dialogs, and pages in the URL with types intact, and why the write lands after the commit instead of during render. The Problem You are building a company page with three tabs and a button that opens a "New purchase" dialog. The page works on the first click. import { useState } from " react " ; function CompanyPage () { const [ tab ,…
Type-safe URL state without drift: A solution for TanStack Router
A small hook called useSearchNavigate in TanStack Router helps maintain tabs, dialogs, and pages in the URL with type safety. The issue arises when a user refreshes the page, causing the tab and dialog state to reset. This problem persists when copying the link and sending it to a colleague or pressing the browser back button after switching tabs.
The first attempt to fix this issue is to seed useState from the URL, but this breaks on back and forward navigation as the URL and the screen disagree. The second fix involves manually writing the query string using window.history.pushState, which updates the URL but fails to trigger re-rendering from the new value. The third option is to use Link search={{ tab: purchase }} everywhere, which maintains the URL's source of truth but loses the user's place every time they change tabs.
The third fix resolves the issue by declaring the search schema on the route, reading it with a typed hook, and writing it through one setter. The search schema is declared on the route, read using a typed hook, and written through one setter, eliminating the need for a copy that can drift. The hook binds to a single route's path, ensuring every write goes to the same clipboard.
A write does not change state directly; it asks the router for a new clipboard, which is checked and the page re-renders only after the router accepts it. Components read the checked entry through useSearch, returning the validated, typed value. Writes are navigations, treated as page changes by default.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.