Skip to content

Routing

A URL is just another input. Most stacks bolt on a parallel router — its own components, lifecycle, and store. re-frame2 folds routing into the pipeline you already have: the URL is an input, the active route is ordinary state via a subscription, and navigation is an event. Traceable, time-travelling, and testable like everything else.

(:require [re-frame.core :as rf]
          [re-frame.routing])   ;; day8/re-frame2-routing — forget this → :rf.error/routing-artefact-missing

(rf/reg-route :app/article
  {:params [:map [:id :string]]}
  "/articles/:id")                    ;; path is the third slot, not a metadata key

@(rf/subscribe [:rf.route/params])    ;; => {:id "hello"}
(rf/dispatch [:rf.route/navigate {:to :app/article :params {:id "hello"}}])

Route loaders run on the server too — one data-fetch story with SSR, no separate server router.

Prerequisites. Core introduction — events, app-db, subscriptions, views. Routing plugs into those; it does not replace them.

When not to use routing

Situation Prefer
Single-screen app, no shareable URLs No routing artefact (zero cost)
In-memory UI steps with no URL app-db flags / a machine
Server-only redirects Host middleware or SSR response effects

Reach for routing when the address bar is part of the product — deep links, shareable state, Back/Forward, SEO/SSR entry.