Navigation and URL State
Navigate with Link and navigate(), and keep URL-owned state in the URL rather than mirroring it into component state.
Example
Keep shareable filters in route search state so refresh, history, and copied URLs preserve the same view.
import { currentRoute, updateRouteQuery } from '@askrjs/askr/router';
const route = currentRoute();
const status = () => route.query.get('status') ?? 'active';
updateRouteQuery({ status: 'paused', page: 1 });Link and navigate
Link renders a real <a> element and intercepts clicks to route through navigate() instead of a full page load, while still respecting middle-click, Ctrl/Cmd-click, Shift-click, and Alt-click so the native "open in new tab" and "download" behaviors keep working. It accepts either an href string or a typed to destination — never both — plus the usual rel, target, and aria-current props. For navigation triggered from code rather than a click — after a form submits, say — call navigate(path, options) directly with the same history and scroll options Link uses internally.
Search parameters
updateRouteQuery(updates, options?) patches the current URL's query string without a full navigation: pass a plain object of key-value updates, or a function that receives the live URLSearchParams for finer control like deleting a key conditionally. It defaults to history: 'replace' specifically so wiring it up to a search input doesn't produce a browser-history entry per keystroke. Reading the query back happens through RouteQuery on the current snapshot, which exposes get(), getAll(), has(), and toJSON() rather than a raw URLSearchParams instance.
History and scroll
NavigateOptions.history is 'push' or 'replace', controlling whether the navigation adds a new browser-history entry or overwrites the current one; replace: true is shorthand for the same thing. Scroll behavior is separate: NavigationScrollBehavior ('top' or 'preserve') governs what a fresh navigation does, while HistoryScrollBehavior ('restore' | 'top' | 'preserve') governs back/forward navigation specifically, since users generally expect scroll position to come back on browser-back but not on a forward click to a new page. ScrollRestorationOptions is app-wide configuration set once through configureScrollRestoration(), not a per-navigation option — NavigateOptions itself has its own narrower scroll field for overriding forward-navigation behavior on a single call, but there's no equivalent per-call override for back/forward scroll restoration.
Active route state
currentRoute() returns a RouteSnapshot with the matched path, typed params, query, hash, and a matches array covering every layout and page that contributed to the current render — useful for building breadcrumbs or highlighting the active section of a nav. It's synchronous, reflects whatever finished resolving most recently, and must be called during component render execution — calling it from outside render (a plain callback, module scope) throws rather than returning a stale snapshot. Pair it with aria-current="page" on Link when you need visually distinct "you are here" styling that also communicates correctly to screen readers.