Documentation
Docs
Introduction
Getting Started
Tutorial: build an app
Core Concepts
Routing
Server-Side Rendering
Mimir, state management
Pages & Layouts
API Routes
Styling & Theming
Building & Deploying
API Reference
Guides
Recipes
FAQ (use cases)
Navigation
There is exactly one rule that, if you follow it, makes a rune app feel instant and keeps your state intact: use the router for in-app navigation. This page is that rule, with the why.
<Link>
The Link component renders an <a> but intercepts the click to navigate on the client:
A Link still produces a real <a href>, so it is crawlable, middle-clickable (opens a new tab), and works
without JavaScript (it falls back to a normal navigation). When JS is present, the click is handled by the
client router: no reload, no flash, atoms preserved.
useRouter().navigate / navigate
For navigation triggered by logic rather than a click:
The cardinal rule
Never use
window.location.href = "..."or a plain<a href>for in-app links.
A plain <a> (without the router) or window.location triggers a full page reload:
- the document re-downloads and re-parses,
- the page re-renders from the server,
- and all client state is destroyed, every Mimir atom that was not persisted resets to its default, the
React tree is rebuilt, and the user sees a flash.
This is the single most common cause of "my state disappears when I click a link". The fix is always: use
Link or navigate.
External links (different origin) should be plain <a>, the router only handles in-app routes.
Back, forward, and history
useRouter() gives you back() and forward(), which call the History API. The router also honours the
browser's own back/forward buttons: it re-matches the route and renders, so navigating back is as instant as
navigating forward, and atoms survive both.
Side-effects on navigation
Because the page component swaps but the layout persists, run per-navigation effects keyed on the path:
Prefetching
The page chunks are listed in __routes and modulepreload-ed for the current page; the first time you
navigate to a route its chunk is fetched and then cached, subsequent visits are instant. For most apps the
preloads plus HTTP caching make navigation feel immediate without manual prefetch logic.
Navigation and state, the payoff
Put state in atoms and navigate with the router, and you get behaviour that is otherwise fiddly to build: a theme toggle, an open sidebar, a multi-step form draft, or a scroll position survive moving between pages, because the pages change but the atoms (and the layout holding them) do not. That is the whole reason the rule exists. See Mimir.
Next: redirects and protecting routes, Guards & redirects.