Widget Builder
Design the rich, interactive cards and forms your agent shows in chat - with AI, a visual catalog, and a live preview.
Most answers are text. Some are better as something a visitor can see and tap. The Widget Builder lets you design rich, interactive cards, lists, product carousels, forms, charts, and buttons that your agent renders right inside the chat — so a visitor can pick a time, add an item to their cart, track an order, or submit details without ever leaving the conversation.
You build a widget once, attach it to an AI Action, and the agent fills it with live data and shows it whenever that action runs.
Start From a Template or a Blank Widget
- Open your chatbot in the April dashboard
- Go to Widgets in the sidebar
- Click Create widget
- Pick a starter from the gallery, or choose Blank widget to start from scratch
The gallery ships with ready-made starters you can use as-is or remix:
- Product card — a single product with title, price, and an Add to cart button
- Buy products — a swipeable carousel of products with prices and a select button
- Order tracker — an order summary with a status pill and a Track order button
- Order history — a stacked list of recent orders with status and totals
- Contact form — capture a name, email, and message inside the chat
- Pricing table — a list of plans with prices and a Choose plan button
- Pricing toggle — an interactive monthly/yearly switch
- Hotel booking — a rich card with image, amenities, rating, and a Book Now button
- Usage chart — a metric plotted across days as a compact bar chart
Each starter opens with realistic sample data so it previews instantly. Give the widget a name in the field at the top left — that name is how you'll find it when you attach it to an action.
The Two-Panel Builder
The builder has two halves: you author on the left and watch the result on the right. The left panel has four tabs.
AI Builder
Describe the widget you want in plain language and April generates the whole thing for you. Type something like:
A card showing a flight with the airline, departure and arrival times, the price, and a "Select flight" button.
April builds the layout, wires up the buttons, and generates matching sample data so it previews right away. To refine it, just describe the change — "add a baggage row," "make the price bold," "show a return-flight badge" — and April updates the existing widget instead of starting over.
April only ever uses components it actually knows how to render, and it's aware of the AI Actions you've already set up on this chatbot — so the buttons and forms it generates point at real actions rather than made-up ones.
Code
For precise control, the Code tab shows the widget's definition as plain JSON and lets you edit it directly. Every keystroke validates against the component catalog and previews live, so a typo or an unsupported component surfaces as an inline error instead of a broken render.
A definition is a tree of components. Text values can be literals, or data bindings written as { "$bind": "path" } that read from the data your action returns at render time:
{
"root": {
"type": "Card",
"title": { "$bind": "order_name" },
"body": { "$bind": "summary" },
"badge": { "type": "Badge", "label": { "$bind": "status_label" }, "variant": "success" },
"actions": [
{ "type": "Button", "label": "Track order", "variant": "primary", "action": "track_order" }
]
}
}
Here order_name, summary, and status_label are filled in live by the action, so the same widget renders correctly for every order.
Functions
The Functions tab lists every interactive element in your widget — each button and form submission becomes an event your agent receives when a visitor taps or submits it. A button that adds an item to a cart, a form that captures a lead, a slot a visitor picks — each one posts back to the conversation, and your agent handles it with a matching AI Action or with its instructions.
A few button behaviors are handled right inside the widget without involving the agent: opening a link in a new tab, dismissing the widget, and in-widget toggles (which power things like the monthly/yearly pricing switch). Everything else is a real event your agent can act on.
States
The States tab lets you show or hide parts of a widget conditionally, based on the data your action returns. Wrap any section in a Show condition and it only appears when the condition passes — for example, only show a Track order button when the status is shipped or out for delivery, or reveal an annual-savings note only when the visitor has the yearly plan selected.
You can describe these conditions in the AI Builder ("only show the tracking button when the order has shipped") or write them directly in the Code tab. Conditions support simple checks (equals, not equals, exists, empty, greater/less than, contains) and can be combined with AND/OR.
Live Preview
The right panel renders your widget exactly as a visitor will see it, updating as you type. You can:
- Switch the frame between a bare Widget, an embedded Chat bubble (with the agent header and an incoming message), and the full Agent page, so you can check how it looks in every place it might appear
- Toggle light and dark mode with the moon/sun control to confirm both themes look right
- Edit the sample data under Sample data to see how the widget reacts to different content — an empty list, a long title, five rows instead of two
- Save named examples (like "empty" or "shipped order") so you can flip between scenarios while you design, then re-load them later
When everything looks right, click Save. You can also Export a widget to a file to back it up or move it to another chatbot — note the action it's attached to won't travel with the file, so you'll re-attach it after importing.
Attaching a Widget to an Action
A widget shows up in chat when the action it's bound to runs. After you've saved your widget:
- Go to Actions in the sidebar
- Open the action you want to show the widget — for example, the action that looks up an order or fetches available times
- Choose one of the widget-backed action types (Server + widget or Widget only) and attach the widget you just built in the General step
- Save
From then on, whenever the agent runs that action, it fills your widget with the live result and renders it in the conversation. The buttons and forms inside the widget post their events straight back to the agent, so the visitor can keep the conversation moving with a single tap.
What You Can Build
The component catalog covers most of what an interactive chat reply needs:
- Cards — title, subtitle, body, image, a status badge, and action buttons
- Lists and carousels — a stacked list or a swipeable row, each item rendered from a card template
- Forms and inputs — text, email, phone, and number inputs, dropdowns, date pickers, checkboxes, radio groups, and text areas, all submitted as one action
- Buttons — primary/secondary/ghost styles, optional inline inputs collected before the action runs, and a loading spinner while it works
- Tables — columns and rows for structured data
- Charts — compact bar, line, and area charts, single- or multi-series, rendered inline
- Badges — colored status pills (success, warning, danger, info)
- Images and icons — theme-aware images and a library of labeled icons (great for amenity-style rows)
- Layout — rows, columns, boxes, dividers, spacers, titles, captions, and markdown blocks to compose rich, on-brand layouts
Widgets automatically pick up your chatbot's brand color and adapt to the visitor's light or dark theme.
Example
Say you've built an Order tracker widget and attached it to the action that looks up an order.
Visitor: Where's my order #1234?
Agent: Here's the latest on your order:
Order #1234 · Shipped Total: $48.00 · Arriving Friday [ Track order ]
Visitor: (taps Track order)
Agent: Your package left our facility this morning and is on a delivery vehicle now. Here's the live tracking link — you'll get a text when it's a few stops away.
The agent answered with a card instead of a paragraph, the visitor tapped a button instead of asking a follow-up, and the Track order action fired without anyone typing a thing.
Tips
- Start with a template close to what you want, then refine it in the AI Builder — it's faster than describing a whole widget from a blank canvas.
- Bind, don't hardcode. Use
{ "$bind": "..." }for anything that changes per visitor (prices, names, statuses) and reserve literal text for fixed labels. The same widget then works for every result. - Preview the edge cases. Save sample-data examples for an empty list, a very long title, and a failed lookup so a widget that looks great with two rows still looks great with twenty — or zero.
- Check both themes before you ship. Toggle dark mode in the preview to catch any contrast or image issues.
- Keep it minimal. A focused card with one clear action converts better than a busy widget — only include the fields and buttons the visitor needs to act.
- Name buttons by what they do. A button's event drives an AI Action, so a clear, specific button leads to a clear, specific outcome in the conversation.