Dynamic switching
Studio writes this format for you. Add the node in the Code editor ; from then on the Inspector's Logic tab ( ⌘⇧3 ) shows a Condition section for it, holding the value it switches on and a row per case.
A
$switch
node swaps what renders in one spot based on a state value: the node binds
$switch
to a
reference
, and
cases
maps each possible value to what should render. When the state changes, the old case is torn down and the new one renders in its place. That covers view switching, wizard steps, and a client-side router, in pure JSON.
{
"tagName": "main",
"children": [
{
"$switch": { "$ref": "#/state/currentRoute" },
"cases": {
"home": { "$ref": "./views/home.json" },
"about": { "$ref": "./views/about.json" },
"profile": { "$ref": "./views/profile.json" }
}
}
]
}
External cases
A case value that is a
$ref
to a
.json
file loads that
document
on demand, so a case is fetched only when its key first becomes active, so unvisited views cost nothing up front. Each external case is an independent component with its own
state
scope.
Inline cases
A case value may also be an inline element definition. Inline cases render in the surrounding document's scope, so they can bind its state directly:
{
"$switch": { "$ref": "#/state/status" },
"cases": {
"loading": { "tagName": "p", "textContent": "Loading…" },
"error": { "tagName": "p", "textContent": "undefined" },
"success": { "$ref": "./views/results.json" }
}
}
Driving the switch
The selector is ordinary state, so anything that writes state switches the view: an event handler, an expression , or a data source:
{
"state": { "currentRoute": "home" },
"children": [
{
"tagName": "button",
"textContent": "About",
"onclick": {
"$expression": {
"operator": "=",
"target": { "$ref": "#/state/currentRoute" },
"value": "about"
}
}
}
]
}
How it works
The runtime renders the
$switch
node as a container element (its
tagName
, or
div
when none is given) and watches the bound reference inside a reactive effect. On every change it clears the container and renders the matching case: inline cases render immediately with the current scope; external cases are fetched, their scope is built, and the result is appended, with stale responses discarded if the key changed again mid-load. A key with no matching case renders nothing.
In Studio
Select the node and open the Logic tab ( ⌘⇧3 ). Its Condition section is the node's two halves:
Expression is what the node switches on. Its value-source chip offers From data… (a signal) and Mixed text ; there is no fixed-value rung, because a literal
$switchdoes not render.Cases is one row per key. Edit a row's text to rename that case, click → to select what it renders, click the dot on its label to remove it, and + Add case appends another.
The section is drawn for a node that already carries a
$switch
, so the node itself is added in the
Code editor
. The
Outline
lists the cases as child rows of the node, and each case is selectable there.
On the canvas,
Edit
mode stands in the first case so the node has something to show. An external first case draws a dashed
[$switch: home | about]
marker naming the keys instead. Switch the canvas to
Preview
to watch the real selector drive it.
Rules
$switchmust be a$ref, typically#/state/.... A literal value is meaningless and does not render.Case keys are matched against the resolved value as strings; there is no default case, and an unmatched value renders an empty container.
External cases have isolated scope; to share data with a case, make it an inline element, or lift shared state to
window#/globals.Switching fully tears down the outgoing case: its DOM and reactive bindings are disposed, and per-component state re-initializes on the next visit.
For URL-driven pages prefer file-based routing ;
$switchis for switching within a page.
Related
References : the
$refschemes$switchbindsState : declaring the selector value
Props and scope : why external cases are isolated
Routing : URL-based page selection for sites
Logic tab : the Condition section that edits a
$switchand its casesCode editing : where the node itself is added