4.1 KiB
A2UI Block Format
A2UI (AI-to-UI) lets you generate interactive UI controls directly in the chat. The
frontend parses a2ui code blocks and renders them as Tabler components — filter
toggles, sortable tables, card grids, and forms — without any page reload.
How to Generate
Wrap a JSON object in a fenced code block with the language tag a2ui:
```a2ui
{ "type": "...", ... }
```
The JSON must be a single object with a type field. The frontend selects the
renderer based on type and passes the remaining fields as props.
Block Types
filters
Renders a row of toggle chips. Use for quick category or attribute filtering.
{
"type": "filters",
"options": [
{ "label": "Toyota", "active": true },
{ "label": "Honda", "active": false },
{ "label": "Hyundai", "active": false },
{ "label": "Under $5K", "active": false }
]
}
| Field | Type | Description |
|---|---|---|
options |
array | List of filter chips |
options[].label |
string | Display text for the chip |
options[].active |
boolean | Whether the chip is pre-selected |
table
Renders a sortable data table. Use for structured comparisons across multiple items.
{
"type": "table",
"headers": ["Make/Model", "Year", "Price", "MPG", "Mileage"],
"rows": [
["Toyota Prius", "2019", "$8,500", "52 mpg", "61,000 mi"],
["Honda Insight", "2018", "$9,200", "49 mpg", "55,000 mi"],
["Hyundai Ioniq", "2019", "$8,900", "55 mpg", "48,000 mi"],
["Toyota Camry Hybrid", "2017", "$7,800", "46 mpg", "72,000 mi"],
["Ford Fusion Hybrid", "2018", "$7,200", "42 mpg", "68,000 mi"]
]
}
| Field | Type | Description |
|---|---|---|
headers |
string[] | Column header labels |
rows |
string[][] | Data rows; each row must match header count |
cards
Renders a card grid. Use for item listings where each result deserves its own tile.
{
"type": "cards",
"items": [
{
"title": "2019 Toyota Prius LE",
"description": "61,000 miles · Hybrid · Clean title · Seattle, WA",
"price": "$8,500",
"url": "https://www.cargurus.com/Cars/listings/prius-example"
}
]
}
| Field | Type | Description |
|---|---|---|
items |
array | List of card objects |
items[].title |
string | Card heading |
items[].description |
string | Supporting detail text |
items[].price |
string | Price label (formatted string, e.g. "$8,500") |
items[].url |
string | Link destination for the card action |
form
Renders a data-collection form. Use when you need user input to refine a search or configure a follow-up action.
{
"type": "form",
"fields": [
{ "name": "max_price", "type": "number", "label": "Max Price ($)", "value": 10000 },
{ "name": "radius", "type": "number", "label": "Search Radius (miles)", "value": 25 },
{
"name": "fuel_type",
"type": "select",
"label": "Fuel Type",
"options": ["hybrid", "electric", "any"]
}
],
"submitLabel": "Search"
}
| Field | Type | Description |
|---|---|---|
fields |
array | Ordered list of form fields |
fields[].name |
string | Field identifier (sent on submit) |
fields[].type |
string | "number", "text", "select" |
fields[].label |
string | Human-readable label |
fields[].value |
any | Default value (for number/text fields) |
fields[].options |
string[] | Choice list (for select fields) |
submitLabel |
string | Text on the submit button |
Rules
- Always use the
a2uilanguage tag. Any other tag (e.g.json) will render as plain code; the frontend will not parse it. - JSON must be a single object with a
typefield. Arrays and multi-root documents are not supported. - Generate A2UI when the user benefits from interactive controls. Filter chips, sortable tables, card grids, and forms add real value when the user is comparing options or needs to refine results.
- Don't overuse. Plain markdown lists and tables are fine for simple answers. Use A2UI only when interactivity meaningfully improves the experience.