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

# Widget

> A small, native projection of your block — six templates, five themes, scheduled refreshes.

A block can ship a **widget**: a small, structured projection of its data that the platform renders natively, separately from the React/HTML iframe. One block, two surfaces: the canvas iframe for the full render, and the widget for tiny / glanceable displays.

The widget is a sub-doc on the manifest:

```json theme={null}
{
  "widget": {
    "template": "metric",
    "theme": "modern",
    "data": { "value": "$12,420", "label": "MRR" }
  }
}
```

Three fields. That's it.

<Note>
  Widget native rendering is iOS-only in v1 — the iOS app renders widgets on the home screen, lock screen, and in the daily morning brief. iOS support is rolling out gradually; once it lands, widgets you've already configured will start rendering with no changes.
</Note>

## Templates

Six render templates. Each declares its own `data` shape; the validator rejects data that doesn't match the chosen template's Zod schema.

<AccordionGroup>
  <Accordion title="metric">
    Big number + label, with optional trend.

    ```json theme={null}
    {
      "template": "metric",
      "data": {
        "value": "$12,420",
        "label": "MRR",
        "trend": "+8.3%",
        "trendDirection": "up"
      }
    }
    ```

    `value` and `label` are strings (formatting is your call — currency, percent, plain). `trendDirection` is one of `"up"`, `"down"`, `"flat"`.
  </Accordion>

  <Accordion title="sparkline">
    A tiny line of numeric points with a label.

    ```json theme={null}
    {
      "template": "sparkline",
      "data": {
        "label": "DAU 30d",
        "points": [120, 132, 128, 145, 160, 158, 172]
      }
    }
    ```

    At least 2 points required.
  </Accordion>

  <Accordion title="status">
    A single colored dot with a label. Use for up/down/degraded-style signals.

    ```json theme={null}
    {
      "template": "status",
      "data": {
        "color": "green",
        "label": "All systems normal"
      }
    }
    ```

    `color` is one of `"green"`, `"yellow"`, `"red"`, `"gray"`.
  </Accordion>

  <Accordion title="list">
    A label plus up to a handful of items (`primary` + optional `secondary`).

    ```json theme={null}
    {
      "template": "list",
      "data": {
        "label": "Open PRs",
        "items": [
          { "primary": "feat: postgres connector", "secondary": "@alice" },
          { "primary": "fix: webhook 401",          "secondary": "@bob" }
        ]
      }
    }
    ```

    At least 1 item required.
  </Accordion>

  <Accordion title="progress">
    A progress bar with current / target.

    ```json theme={null}
    {
      "template": "progress",
      "data": {
        "label": "Annual goal",
        "current": 142000,
        "target": 250000,
        "unit": "$"
      }
    }
    ```

    `target` must be positive.
  </Accordion>

  <Accordion title="text">
    A short string. Use for a quote, headline, or a note.

    ```json theme={null}
    {
      "template": "text",
      "data": { "text": "“Slow is smooth, smooth is fast.”" }
    }
    ```
  </Accordion>
</AccordionGroup>

There's also a `chart` template in the manifest schema (line / bar / area with multiple series), but the iOS native renderer for it is deferred. You can declare `chart` widgets today; iOS will skip them until support ships.

## Themes

Five themes select typography, palette, corner radius, and background style. Theme identity in v1 comes from these passive choices — no animation policy yet.

| Theme       | Vibe                                                              |
| ----------- | ----------------------------------------------------------------- |
| `modern`    | Default. Clean sans, generous whitespace, neutral palette.        |
| `splitflap` | Split-flap board look — slab serif numerals on a deep background. |
| `terminal`  | Monospace, green-on-black phosphor energy.                        |
| `newspaper` | High-contrast serif with thin rules.                              |
| `pastel`    | Soft pastel palette, rounded corners.                             |

Theme is optional. If omitted from the widget config, the iOS app uses the user-configured per-widget override (long-press → Edit Widget), falling back to `modern`.

## Configuring from the in-app editor

Open a block in `/blocks/[blockId]/edit`, click the **Widget** button on the toolbar. The Widget panel has:

* A toggle to enable / disable.
* A template picker (six options).
* A theme picker (five options).
* A sample-data JSON field, validated client-side against the chosen template's schema.

Saving the panel writes to `manifest.widget` via the `blocks.updateBlockWidget` mutation. You can also set it from an agent over MCP — see `blocks.update` and `blocks.setWidgetData` in the [tool reference](/mcp/tool-reference).

## Refreshing widget data

Widget data updates by one of three paths:

<CardGroup cols={2}>
  <Card title="Connector binding" icon="bolt" href="/connecting-data/stripe">
    Add a `binding` to the manifest pointing at a configured data source. The aggregator refreshes on a cadence and writes through to `widget.data` via the projection.
  </Card>

  <Card title="Scheduled run" icon="clock" href="/scheduled-runs/concepts">
    A BYOK agent runs on cron, computes the value, and calls `blocks.setWidgetData`. Useful when the data needs LLM reasoning to assemble.
  </Card>

  <Card title="MCP setWidgetData" icon="terminal" href="/mcp/tool-reference">
    Direct write from any MCP caller — your local dev script, a CI job, your agent on demand.
  </Card>

  <Card title="In-app edit" icon="pen" href="/authoring/in-app-editor">
    Hand-edit `widget.data` in the Widget panel. Useful for prototyping.
  </Card>
</CardGroup>

Every write to `widget.data` triggers an iOS silent push so the widget refreshes within seconds of the update.

## What's next

<CardGroup cols={2}>
  <Card title="BYOK keys" icon="key" href="/connecting-data/byok-keys">
    Bring your own LLM key — required for scheduled runs that drive widget refreshes.
  </Card>

  <Card title="Scheduled runs" icon="clock" href="/scheduled-runs/concepts">
    Cron-driven agent loops that keep widget data fresh.
  </Card>
</CardGroup>
