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.