Recipes

Booking History

A data table showing booking records with status, dates, and amounts — introduces the Table component for structured data.

Booking History

A structured table showing a customer's booking history — the kind of view Agent generates when a business owner asks to see recent bookings.

This recipe introduces the Table component — a new A2UI type that maps to Nuxt UI's UTable (powered by TanStack Table). It lets AI agents present tabular data with typed columns, alignment, and row data without knowing TanStack internals.

A2UI → Nuxt UI Mapping

A2UI PropertyNuxt UI PropNotes
columnscolumns (TanStack ColumnDef)Simplified: { key, label, align } → auto-converted
rowsdataArray of objects, keys match column key values
captionrendered as <p> above tableOptional table description
stickystickySticky header for scrollable tables

What the AI Generates

{"version":"v0.10","createSurface":{"surfaceId":"booking_history","catalogId":"standard"}}
{"version":"v0.10","updateComponents":{"surfaceId":"booking_history","components":[
  {"id":"root","component":"Column","children":["page_title","page_desc","bookings_table"]},
  {"id":"page_title","component":"Text","text":"Booking History","variant":"heading","level":2},
  {"id":"page_desc","component":"Text","text":"Recent bookings for Drammen Wellness Studio","variant":"muted"},
  {"id":"bookings_table","component":"Table","caption":"Showing last 7 days","columns":[
    {"key":"id","label":"#","align":"left"},
    {"key":"date","label":"Date","align":"left"},
    {"key":"customer","label":"Customer","align":"left"},
    {"key":"service","label":"Service","align":"left"},
    {"key":"status","label":"Status","align":"center"},
    {"key":"amount","label":"Amount","align":"right"}
  ],"rows":[
    {"id":"#1047","date":"Feb 14, 14:00","customer":"Guðrún Helgadóttir","service":"Deep Tissue — 60 min","status":"Confirmed","amount":"12.900 ISK"},
    {"id":"#1046","date":"Feb 14, 11:30","customer":"Jón Sigurðsson","service":"Hot Stone — 90 min","status":"Completed","amount":"18.500 ISK"},
    {"id":"#1045","date":"Feb 13, 16:00","customer":"Anna Kristjánsdóttir","service":"Aromatherapy — 45 min","status":"Completed","amount":"9.900 ISK"},
    {"id":"#1044","date":"Feb 13, 10:00","customer":"Ólafur Magnússon","service":"Deep Tissue — 60 min","status":"Cancelled","amount":"12.900 ISK"},
    {"id":"#1043","date":"Feb 12, 15:30","customer":"Sigrún Einarsdóttir","service":"Hot Stone — 90 min","status":"Completed","amount":"18.500 ISK"},
    {"id":"#1042","date":"Feb 12, 09:00","customer":"Björk Sveinsdóttir","service":"Deep Tissue — 60 min","status":"Completed","amount":"12.900 ISK"},
    {"id":"#1041","date":"Feb 11, 13:00","customer":"Einar Þórarinsson","service":"Aromatherapy — 45 min","status":"No-show","amount":"9.900 ISK"}
  ]}
]}}

Column Definition (Simplified)

The A2UI Table uses a simplified column format that LLMs can easily produce — no TanStack knowledge required:

{
  "key": "status",
  "label": "Status",
  "align": "center"
}

This is automatically converted to a TanStack ColumnDef at render time:

{
  accessorKey: 'status',
  header: 'Status',
  meta: { class: { th: 'text-center', td: 'text-center' } }
}

Component Properties

PropertyTypeRequiredDescription
columnsArray<{ key, label, align? }>YesColumn definitions
rowsArray<Record<string, unknown>>YesTable data — each object's keys should match column key values
captionstringNoDescription text above the table
stickybooleanNoMakes the header stick when scrolling

Try It

Paste the JSONL above into the Playground to see the table render live.

Real-World Context

In the AI Agents platform, this table appears when:

  • A business owner asks Agent: "Show me this week's bookings"
  • Agent queries the booking data and streams a Table component
  • The table renders progressively — columns appear first, then rows populate
  • Business owners can scan status at a glance: Confirmed, Completed, Cancelled, No-show