Status: backlog Priority: P2 Created: 2026-02-11 Owner: conductor
The routing system must maintain bidirectional synchronization between the statechart configuration and the browser URL. Currently, each route state independently pushes or replaces history in its on-entry handler (establish-route-params-node), which leads to several problems:
The URL must be the output of the statechart configuration, not an artifact of individual state entries.
:route/path (see url-path-design.md for path composition)replace-route!, not push-route!.apply-external-route must handle the full URL: path → target state, query params → state params, opaque params → per-state datapopstate) triggers apply-external-route with the historical URL. The system must transition to the correct state, which may require async processing.busy?, the URL change must be undone (already partially implemented in undo-url-change)popstate — an external route changeprocess-event! returns (or its promise resolves)async-url-restoration.md), URL updates are suppressed entirely until restoration completesintegration/fulcro/ui_routes.cljc — establish-route-params-node (refactor to not directly push history), routes, apply-external-route, busy?/undo-url-changeintegration/fulcro/route_history.cljc — May need a batch-update! or compute-url that takes full configurationintegration/fulcro.cljc — send! / event processing wrapper may need post-macrostep hookintegration/fulcro/route_url.cljc — URL composition from multiple state contributionsInstead of each state's on-entry pushing history, introduce a post-macrostep hook that computes and applies the URL:
1. User clicks "Settings" → route-to event fired
2. Macrostep runs: exit old states, enter new states (potentially async)
3. Configuration stabilizes
4. Post-macrostep hook:
a. Read active configuration
b. Find the active leaf route state(s)
c. Resolve URL path from leaf state's composed path
d. Collect query params from all active route states
e. Compute single URL
f. push-route! (or replace-route! for same-top-level transitions)
This hook can be implemented as:
scf/send! that handles the post-processingdone callback on the event processingEach route state declares its params (already supported via :route/params). The coordination layer:
Track the previous leaf route state(s) to make this determination.
start-routing!?istate charts)?busy? guard prevents back/forward and undoes URL changeCan you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |