Action templates
Action templates turn the widget from a text-only assistant into a guided, interactive surface: buttons, cards, forms, confirmations, status trackers, and vertical presets such as docs, lead capture, services booking, restaurant, ecommerce, and travel.
This is a foundation for assistants that can do useful work without each app forking the widget or inventing one-off UI. The core rule is simple: build verticals from generic primitives, then wire the actual business action on the server side.
Note
Client-side action templates are supported today. Hosted execution of arbitrary customer webhooks (tenant isolation, SSRF guards, idempotency, secrets, audit logs, rate limits, confirmation policies) is not yet available — implement server-side execution yourself in the meantime.
What ships in the widget
Import React primitives from the main package entrypoint, and import server-safe
manifest data/types from the ./actions subpath when you are in server code,
dashboard code, docs tooling, or any place that should not pull in the client
component entry.
import {
ActionButton,
ActionChips,
ActionForm,
ConfirmationCard,
EntityCard,
EntityCarousel,
StatusTracker,
SummaryCard,
} from '@mordn/chat-widget';
import {
leadCaptureTemplate,
type MordnActionDispatcher,
} from '@mordn/chat-widget/actions';The contract is intentionally small:
type MordnActionHandler = 'client' | 'server' | 'hosted';
type MordnActionLoadingBehavior = 'auto' | 'none' | 'self' | 'container';
type MordnActionConfirmationPolicy = 'none' | 'recommended' | 'required';
type MordnActionRiskLevel = 'ui' | 'read' | 'capture' | 'mutation' | 'regulated';
interface MordnActionConfig<TPayload = unknown> {
type: string; // e.g. lead.capture, ecommerce.cart.add
payload?: TPayload; // untrusted until the server validates it
handler?: MordnActionHandler;
loadingBehavior?: MordnActionLoadingBehavior;
confirmation?: MordnActionConfirmationPolicy;
idempotencyKey?: string;
label?: string;
risk?: MordnActionRiskLevel;
analyticsName?: string;
schema?: MordnActionSchema;
}
type MordnActionDispatcher = (event: MordnActionEvent) => Promise<MordnActionResult | void> | void;Example: lead capture
Use an action form to collect values, then hand the event to your host code. The host still validates and persists server-side.
import { ActionForm } from '@mordn/chat-widget';
import { leadCaptureTemplate, type MordnActionDispatcher } from '@mordn/chat-widget/actions';
const onAction: MordnActionDispatcher = async ({ action, values }) => {
if (action.type !== 'lead.capture') return;
await fetch('/api/leads', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(values),
});
};
export function LeadCaptureDemo() {
return (
<ActionForm
title="Book a demo"
description="Tell us where to follow up."
action={leadCaptureTemplate.actions[0]}
onAction={onAction}
fields={[
{ name: 'email', label: 'Work email', type: 'email', required: true },
{ name: 'company', label: 'Company' },
{ name: 'message', label: 'What are you trying to do?', type: 'textarea', required: true },
]}
/>
);
}Warning
Client-side examples are only interaction wiring. Never treat browser-submitted
payloads or browser-supplied user ids as authoritative. Server actions must use
getUserId / getChatUserId verified identity.
Generic primitives
ActionButton and ActionChips
Use for guided next steps, quick replies, local UI actions, or server actions.
ActionButtonemits oneMordnActionConfig.ActionChipsrenders a small set of next actions.- Use client handlers for local UI work such as opening a modal or checkout.
- Use server or hosted handlers for reads, capture, and mutations.
ActionForm
Use for lightweight structured input:
- lead capture
- reservation requests
- callback requests
- service intake
- quote requests
- support ticket details
For complex validation, payments, or sensitive data, open a host-owned page or modal and send only the final safe result back to the widget.
EntityCard and EntityCarousel
Use for vertical cards:
- menu items
- products
- services
- hotel options
- destinations
- plans
- events
- support resources
Each card supports image, title, subtitle, description, attributes, price or badge, and action buttons or safe external links.
SummaryCard and ConfirmationCard
Use a summary before consequential actions. A confirmation should show what will happen, where data will go, and how the user can cancel.
StatusTracker
Use for order status, booking state, setup checklists, support ticket progress, or itinerary steps.
Built-in starter manifests
The package ships starter manifests for six verticals:
| Template | What it covers |
|---|---|
docs-assistant | citations, setup guidance, open-page actions, unanswered question capture |
lead-capture | qualification, form capture, summary, CRM or webhook handoff |
services-booking | service selection, intake, request-to-book, status updates |
restaurant-assistant | menu cards, dietary badges, recommendations, reservation request |
ecommerce-concierge | product cards, variant selection, cart/checkout handoff |
travel-planner | destination or hotel cards, itinerary timeline, quote request |
The restaurant, ecommerce, and travel templates deliberately use request or handoff language by default. Don't let them imply confirmed inventory, purchase, payment, or reservation unless a configured action result actually confirms it.
Safety model
Action templates have five risk levels:
| Level | Examples | Default posture |
|---|---|---|
ui | open modal, navigate, open checkout link | client handler is fine |
read | search menu, lookup order, check public status | server validation and timeout |
capture | lead form, booking request, support ticket | confirmation or clear submit, audit redaction |
mutation | create CRM record, add to cart server-side, reserve slot | required confirmation and idempotency |
regulated | payment card, medical/legal/financial commitment | hand off outside chat |
Server-side or hosted execution should enforce:
- verified user identity
- schema validation
- authorization and tenant scope
- idempotency
- rate limits
- confirmation policy
- timeouts
- audit logs
- redaction for sensitive fields
- SSRF-safe webhook calls
Template strategy
Don't build one-off restaurant, ecommerce, or travel widgets. Build reusable primitives and declarative manifests, then layer verticals on top.
The docs assistant, lead capture, and services-booking templates need no live inventory, cart, or payment integration, so they're the fastest to stand up. Ecommerce and travel templates are worth reaching for once you have a stable action-execution and confirmation flow in place, since they carry more transactional risk.
Hosted execution and dashboard tooling
The primitives above cover client-side templates. Hosted, per-tenant action execution — with a dashboard template gallery, action editor, and analytics — is not yet available; server-side execution is currently something you wire up yourself, as described in the safety model above.
See AI UX extras for related follow-up chips, action-result cards, and tool approval patterns.