> ## Documentation Index
> Fetch the complete documentation index at: https://prefab.prefect.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Wire format for the Prefab UI protocol.

The Prefab protocol defines the JSON wire format exchanged between a server (Python SDK) and a client (renderer). A server returns a `UIResponse` that serializes to the envelope below. The renderer parses it, resolves templates, interpolates state, and renders the component tree.

## Envelope

Every response is a JSON object with clean top-level keys:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "version": "0.2",
  "view": { ... },
  "defs": { ... },
  "state": {
    "count": 42,
    "name": "Alice"
  }
}
```

| Key       | Type        | Description                                                               |
| --------- | ----------- | ------------------------------------------------------------------------- |
| `version` | `string`    | Protocol version (currently `"0.2"`)                                      |
| `view`    | `Component` | The root component tree to render                                         |
| `defs`    | `object`    | Optional map of template name to component subtree (see Define/Use below) |
| `state`   | `object`    | Optional client-side state, accessible via `{{ key }}` interpolation      |

State keys must not start with `$` (reserved for interpolation builtins like `$event` and `$error`).

## Components

Every component is a JSON object with a `type` discriminator:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "Badge",
  "label": "Active",
  "variant": "success"
}
```

All components share these optional base fields:

| Field      | Type     | Description                                           |
| ---------- | -------- | ----------------------------------------------------- |
| `id`       | `string` | HTML `id` attribute, applied to the outermost element |
| `cssClass` | `string` | Additional Tailwind CSS classes                       |

Container components (Row, Column, Card, etc.) also have a `children` array of nested components.

For conditional rendering, use the [Condition](/protocol/condition) component with `cases` and an optional `else` branch.

## Actions

Actions define what happens on user interaction. They appear in event handler fields like `onClick`, `onChange`, and `onSubmit`. An action uses an `action` discriminator instead of `type`:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "action": "toolCall",
  "tool": "get_weather",
  "arguments": { "city": "{{ city }}" }
}
```

Action fields accept a single action, an array of actions (executed sequentially), or `null`:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "Button",
  "label": "Submit",
  "onClick": [
    { "action": "setState", "key": "loading", "value": true },
    { "action": "toolCall", "tool": "process" }
  ]
}
```

Available action types:

| Action                                    | Discriminator   | Description                      |
| ----------------------------------------- | --------------- | -------------------------------- |
| [SetState](/protocol/set-state)           | `setState`      | Set a client-side state variable |
| [ToggleState](/protocol/toggle-state)     | `toggleState`   | Flip a boolean state variable    |
| [CallTool](/protocol/tool-call)           | `toolCall`      | Call a server-side tool          |
| [SendMessage](/protocol/send-message)     | `sendMessage`   | Send a message to the chat       |
| [UpdateContext](/protocol/update-context) | `updateContext` | Silently update model context    |
| [OpenLink](/protocol/open-link)           | `openLink`      | Open a URL                       |
| [ShowToast](/protocol/show-toast)         | `showToast`     | Display a toast notification     |

## Interpolation

All string properties support `{{ key }}` placeholders that resolve against client-side state at render time. The special value `{{ $event }}` captures the triggering interaction's value (slider position, input text, checkbox state, etc.).

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "P",
  "content": "Hello, {{ name }}! You have {{ count }} items."
}
```

## Define / Use (Templates)

Templates let you define a component subtree once and reference it multiple times with different data.

**Defining a template** — entries in `defs` map a name to a component subtree:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "defs": {
    "user-card": {
      "type": "Card",
      "children": [
        { "type": "CardTitle", "content": "{{ name }}" },
        { "type": "CardDescription", "content": "{{ role }}" }
      ]
    }
  }
}
```

**Using a template** — a `$ref` node references a definition by name:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{ "$ref": "user-card" }
```

**With scoped data** — add `let` bindings to the `$ref` node:

```json theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "$ref": "user-card",
  "let": { "name": "Alice", "role": "Engineer" }
}
```

The renderer resolves `$ref` nodes by looking up the definition and rendering it with the current interpolation context. Circular references are detected and short-circuited.
