a reactive (signals based) hypermedia web framework (wip)
stormlightlabs.github.io/volt/
hypermedia
frontend
signals
1---
2outline: deep
3---
4
5# URL Plugin
6
7The url plugin bridges VoltXsignals with the browser’s address bar. Use it to hydrate page state from query parameters, mirror form inputs into the URL, or power hash/history based routing.
8
9## Quick Start
10
11```html
12<!-- Populate a signal on mount -->
13<div data-volt-url="read:filters.category"></div>
14
15<!-- Two-way sync between location.search and a signal -->
16<input name="q" data-volt-url="sync:searchQuery" />
17```
18
19Each binding follows `mode:signalPath[:basePath]`. The plugin resolves the signal via `ctx.findSignal` and wires it to one of the strategies below.
20
21## Modes
22
23### `read`
24
25One-way hydration. On mount the plugin reads `?signalPath=value` and assigns it to the signal. Later signal updates do not modify the URL.
26
27```html
28<div data-volt-url="read:filters.status"></div>
29```
30
31### `sync`
32
33Bidirectional query-string sync. The plugin:
34
351. Seeds the signal from `?signalPath=...`.
362. Subscribes to the signal and pushes URL updates (debounced) via `history.pushState`.
373. Listens for `popstate` to keep the signal in sync when the user navigates back/forward.
38
39The `serializeValue`/`deserializeValue` helpers support strings, numbers, booleans, JSON payloads, and empty values.
40
41```html
42<input placeholder="Search…" data-volt-url="sync:search" />
43```
44
45When the input changes the URL updates to `?search=...`. Clearing the input removes the parameter.
46
47### `hash`
48
49Two-way binding to `window.location.hash`. Useful for simple client-side routing or tab selection:
50
51```html
52<nav data-volt-url="hash:activeTab"></nav>
53```
54
55- Updates to the signal call `history.pushState` with the new hash.
56- `hashchange` events hydrate the signal when users edit the URL manually.
57
58### `history`
59
60Full routing synchronization with `pathname + search`. Optionally trim a base path when syncing:
61
62```html
63<main data-volt-url="history:route:/app"></main>
64```
65
66- The signal receives `/` when the user is at `/app`.
67- Pushing a new value updates the URL and dispatches `volt:navigate`.
68- Browser back/forward emits `volt:popstate` and refreshes the signal.
69
70Combine this mode with the navigate plugin to keep a global router signal in lockstep with address bar changes.
71
72## Handling Missing Signals
73
74If the plugin cannot resolve `signalPath` it logs a descriptive error and aborts. Ensure your scope exports naming matches when wiring bindings.
75
76## Cleanup
77
78Each mode registers the necessary event listeners (`popstate`, `hashchange`, `volt:navigate`) and unsubscribes during cleanup, so no manual teardown is required. All timers are also cleared to prevent stale updates.