Wire protocol
You don’t need to speak the wire protocol to build components — the client handles it. This page is for when you’re curious, debugging DevTools, or building something on top of Conduit.
Endpoint
Section titled “Endpoint”POST /conduit/update sits behind web middleware: session + CSRF + signed:relative.
Clients must use the signed URL from @conduitScripts / effects.endpoint — bare /conduit/update without a valid signature returns 403. See Signed update requests.
Send X-CSRF-TOKEN (or _token) and JSON shaped like this:
{ "fingerprint": { "id": "…", "name": "counter", "path": "/", "method": "GET" }, "serverMemo": { "data": { "count": 0, "label": "world" }, "checksum": "…", "errors": {} }, "updates": [["label", "friend"]], "calls": [{ "method": "increment", "params": [] }], "island": null}You can also send a batch:
{ "components": [ { "fingerprint": {…}, "serverMemo": {…}, "updates": [], "calls": [] } ]}Response effects
Section titled “Response effects”The JSON reply includes a fresh serverMemo plus an effects object. Common keys:
| Effect | Meaning |
|---|---|
html |
Full (or root) HTML to morph |
islands |
Map of island name → HTML |
data |
Latest public property bag |
errors |
Validation errors |
dispatches |
Events / $js payloads to run |
queryString |
URL query updates |
endpoint |
Rotated signed update URL |
redirect |
{ url, navigate } — full reload, or soft navigate when navigate is true |
The client applies data bindings before morphing so the UI moves first, then patches the DOM.
Do not rewrite serverMemo.data in the browser before POST — the checksum covers that bag. Send property changes as updates (or $set calls) and take the fresh memo from the response.
Checksums
Section titled “Checksums”Snapshots are HMAC’d with conduit.checksum_key or app.key. If someone tampers with serverMemo.data in the browser, the checksum fails and the update is rejected. That’s defense in depth on top of signed URLs and CSRF.
Assets
Section titled “Assets”@conduitScripts (or the asset route) serves:
- Alpine.js (CDN from
conduit.alpine_cdn, or the CSP build whencsp_safeis on) /conduit/conduit.js— directive binder, morpher,$wiremagics- Boot config:
window.__CONDUIT__ = { base, endpoint, asset }plus<meta name="conduit-endpoint">
In production, many teams bundle Alpine themselves and load only Conduit’s script. Point the config at your asset pipeline and you’re set.
Coalescing
Section titled “Coalescing”The browser merges updates/calls that land within conduit.coalesce_ms (default 16) into a single POST. That’s why rapid typing with wire:model.live doesn’t fire a request per keystroke — it feels like one smooth stream.
Mental picture
Section titled “Mental picture”[Browser] wire:click / $wire.foo() → coalesce (~16ms) → POST signed /conduit/update (+ CSRF)[Server] verify signature + checksum → hydrate component from memo → apply updates, run calls → render HTML / islands → return effects + new memo[Browser] apply data bindings → run dispatches / $js → morph HTML (or island)When something looks wrong, open the Network panel, find the update request, and inspect calls, updates, and effects.data. Nine times out of ten the story is right there.