Skip to main content
Named form controls automatically sync their value to state — the slider below updates brightness on every drag, and the Muted text responds through {{ brightness }} interpolation. No action needed. SetState gives you explicit control when auto-binding isn’t enough: setting literal values, computing new state from old, or wiring up non-form elements like buttons. Drag the slider — the text updates instantly. set_initial_state(brightness=50) seeds the starting value; the name prop handles the rest.

Event Capture (the Default)

When you write SetState("brightness") without a second argument, it defaults to {{ $event }} — the value from the triggering interaction. What $event means depends on the component:
Component$event value
SliderCurrent slider position (number)
Input / TextareaCurrent text value (string)
Checkbox / SwitchChecked state (boolean)
SelectSelected option value (string)
RadioGroupSelected radio value (string)
Buttonundefined
This means SetState("key") is all you need for form controls — it automatically captures the right value.

Explicit Values

Pass a second argument to set a specific value instead of capturing the event. Click the buttons below to change the color: The div’s css_class uses {{ color }} interpolation, so clicking a button swaps the Tailwind class and the color changes instantly.

Resetting State

Use explicit values to build reset buttons:

Toggle State

ToggleState flips a boolean — True becomes False, False becomes True. It’s the shorthand for show/hide patterns, expand/collapse, and on/off toggles. ToggleState pairs naturally with If — toggle the state variable, and the conditional block shows or hides the content. Click the button above to see it in action.

Multiple Independent Toggles

Each ToggleState key is independent, so you can manage multiple visibility states:

Initial State

Seed state with initial values using set_initial_state():
Initial State
set_initial_state(volume=75, muted=False, theme="light")
Named form controls (name="volume") automatically sync with state — the slider starts at 75, the switch starts off. For tools, you can also set initial state via AppResult.state:
AppResult Initial State
from prefab_ui import AppResult

@mcp.tool()
async def settings() -> AppResult:
    return AppResult(
        view=...,
        state={"volume": 75, "muted": False},
    )

API Reference

SetState Parameters

key
str
required
State variable name to set. Can be passed as a positional argument.
value
Any
default:"\"{{ $event }}\""
Value to assign. Defaults to the event value from the triggering interaction (slider position, input text, checkbox state, etc.).

ToggleState Parameters

key
str
required
State variable name to toggle. Can be passed as a positional argument.

Protocol Reference

SetState
{
  "action": "setState",
  "key": "string (required)",
  "value?": "any"
}
ToggleState
{
  "action": "toggleState",
  "key": "string (required)"
}
For the complete protocol schema, see SetState, ToggleState.