Routing glossary¶
Optional routing capability: the URL is an input, the active route is ordinary state via subscriptions, and navigation is an event. See The model.
navigate¶
Change the route by dispatching navigation. The active route is a subscription you read like any other. Because navigation is an event, it is traceable, interceptable, and rewound by time-travel.
Related: The model.
route¶
A URL pattern registered with reg-route under an id, paired with match behaviour —
:params/:query schemas, a loader, a :can-leave /
:can-enter guard, scroll policy. The route table is the app's URL map.
route params¶
The active URL as state: read :rf.route/id, :rf.route/params, and
:rf.route/query through subscriptions. Path params and ?query= values (coerced
and defaulted) drive handlers and views; ?page=2 survives Back for free.
loader¶
What a route declares it needs on entry — :resources ensured loaded — so
a page's data requirement sits next to its URL. Loaders also run on the server; no
separate SSR data-fetch to keep in sync. A route's :on-match events are its
activation work, not its loader: the runtime fires and forgets them, and they never
touch route readiness. See Activation work and page data.
effective route plan¶
The resource requirements a navigation actually runs: every :resources entry
contributed by the route's chain, parent-most to leaf, with identical
requirements deduped to one fetch. Naming a :parent is what opts a child in, so a
shared shell read is declared once instead of restated per tab. Only :resources
compose this way.
intent prefetch¶
Warming a destination's effective route plan before the user
commits, via [route-link {… :prefetch :intent}] or a direct
[:rf.route/prefetch <address>] dispatch. Hover, focus, or touch runs the same plan
a navigation would — ownerless, non-blocking, and with no route state, guards, or
:on-match. Click through and the ordinary resource dedupe reuses the warmed work.
route chain¶
The active route's ancestry. A route names a :parent; @(subscribe [:rf.route/chain])
returns the lineage root-most first — on /articles/intro,
[:app/articles :app/article]. Shared layouts without <Outlet/>: the leaf is the
page; each ancestor wraps a shell. See Nested layouts.
transition¶
Route readiness — :idle, :loading, or :error — via :rf.route/transition, with
the structured failure on :rf.route/error. It is a projection over the blocking
:resources in the effective route plan: pending on a first
load, :error on a blocking first-load failure or a plan that could not be built,
:idle otherwise. A background refresh, a non-blocking read, an
intent prefetch, and :on-match never move it. One global fact
for a progress bar or error banner, not per-page loading flags.
nav-token¶
Counter that identifies one navigation. Route-declared resources are owned by the
token that planned them; a reply after a newer navigation is dropped instead of
overwriting the page you are on. Hand-rolled loaders opt in via the
:rf.route/nav-token coeffect and :rf.route/with-nav-token fx.
route guard¶
A boolean subscription on a route: :can-leave (true = leave is fine)
or :can-enter (true = enter is fine). The two refusals are deliberately
asymmetric. A :can-leave false parks the attempt in
[:rf/pending-navigation] — a question to the user — and your
view resolves it with [:rf.route/continue <id>] or
[:rf.route/cancel <id>] (the pending-nav id). A :can-enter false is
terminal: a question to application state, answered the same way
every time, so nothing commits and nothing parks. Unsaved changes → leave guard
(recipe); per-route auth → enter guard
(recipe); multi-route policy → optional
interceptor.
terminal entry¶
What a refused :can-enter does: commit no route slice, URL, scroll, resource, or
:on-match; park no pending value; and dispatch :rf.route/entry-denied exactly
once with the replayable :destination. There is nothing to resume and no entry
bypass — the return after signing in is a fresh navigation whose guard re-evaluates
naturally. Under SSR the same refusal renders the shell under a 403.
not-found¶
Reserved route id :rf.route/not-found. The runtime activates it when no
pattern matches — or when URL params fail their schema — with the offending URL in
params. Ordinary route you register and design; skip it and unmatched URLs get a bare
placeholder.
url-bound?¶
Flag that this frame owns the browser address bar. At most one frame is url-bound (none is legal — URL pushes then no-op). Its navigations write the URL; Back/Forward (popstate) dispatch to it. Other frames route in memory only — how a sidecar like Xray coexists without fighting over the URL.