what

Wired State

Real-time shared variables pushed to all connected browsers via WebSocket. When one user changes a wired value, every other user sees the update instantly.

What Is Wired State

Session data is per-user. Application data is shared but only updates on page load. Wired state bridges the gap — it is shared across all users and pushes changes to every connected browser in real time via WebSocket.

Think of it as a live broadcast channel for your template variables.

Declaring Wired Variables

Declare wired variables in the <what> block of your application.what file:

application.what
data.wired = ["live_count", "online_users", "latest_message"]

Displaying Values

Use the #wired.key# syntax in any template. Like session and app variables, wired values are wrapped in reactive <span w-bind="wired.key"> elements.

<p>Live visitors: #wired.live_count#</p>
<p>Latest message: #wired.latest_message#</p>

Mutating Values

Use w-set with the wired. prefix:

<button w-set="wired.live_count += 1">I'm Here</button>

<button w-set="wired.latest_message = 'Hello everyone!'">
  Send Greeting
</button>

<button w-set="wired.counter = 0">Reset Counter</button>
Important: Only authenticated users can mutate wired.* variables. Reading is available to all visitors.

How It Works

The framework maintains a WebSocket endpoint at /w-wire. When a page references any #wired.*# variable, the client JavaScript automatically connects to this endpoint.

  1. A user clicks a w-set="wired.key += 1" button
  2. The server applies the mutation atomically in the database
  3. The server broadcasts the new value to all connected WebSocket clients
  4. Each client receives a JSON message: {"wired.key":"42"}
  5. The client-side JavaScript updates every <span w-bind="wired.key"> on the page

The update happens without any page reload or polling. All connected browsers see the change simultaneously.

WebSocket message format
{"wired.live_count":"42","wired.latest_message":"Hello everyone!"}

Reacting to Changes — w-watch

Auto-binding updates the text of a #wired.*# value. When a change should instead re-fetch a whole chunk of HTML from the server — for example, reloading a message list when a new message arrives — pair w-watch with w-get/w-post. When the named wired variable changes, the client re-runs the fetch and swaps the response into the target.

<!-- Re-fetch the message list whenever wired.chat_ping changes -->
<div w-watch="wired.chat_ping"
     w-get="/w-partial/messages"
     w-target="#messages" w-swap="innerHTML"></div>

<div id="messages"><include src="partials/messages.html"/></div>

A common pattern: bump a “ping” counter (w-set="wired.chat_ping += 1") when something changes, and let every client’s w-watch re-pull the fresh HTML. That is exactly how the Chat demo stays live for everyone.

Use Cases

ScenarioExample
Live dashboardShow real-time visitor count, active sessions
Chat indicatorsDisplay "typing..." or latest message preview
Collaborative countersLive voting, reaction counts visible to all
AnnouncementsPush a message that appears on all open tabs
Status monitorsServer health, queue depths, deployment status

Combining with Other Scopes

A single w-set expression can update wired, app, and session data together:

<button w-set="wired.live_reactions += 1; session.my_reactions += 1; app.total_reactions += 1">
  React
</button>

This increments the live counter (all browsers see it instantly), tracks the user's personal count in their session, and updates the persistent global total — all in one request.

Tip: Wired state is stored in the database alongside application data. The only difference is the broadcast behavior — wired mutations push updates via WebSocket, while app mutations only update the current user's page.

Initial Values

Set a default initial value for a wired variable using inline syntax in any page's <what> block:

<what>
wired.live_count = 0
</what>
Tip: Default vs Force. wired.count = 0 is a default — it only applies when no persisted value exists yet (e.g. first deploy). If users have already incremented the counter, the persisted value is kept. To always reset a value on page load, use set.wired.count = 0 instead.
<what>
wired.count = 0           <!-- default: only if no persisted value -->
set.wired.count = 0       <!-- force: always reset on page load -->
</what>