Skip to Content
← Back to all demos

Action Buttons

Dynamic action buttons that provide context-aware interactions with each response

Context-aware actionsFour action typesSmart disablingTime-sensitive actions

Action Buttons Demo

Action buttons allow you to provide context-aware actions with each assistant response. Users can trigger handovers, open URLs, send queries, or emit custom events.

Key Features

  • Dynamic per-message actions - Different actions for each turn based on context
  • Four action types - trigger_handover, open_url, send_event, send_query
  • Smart disabling - Auto-disable actions from previous turns
  • oneTimeUse behavior - Actions disable after first click
  • expiresAfterTurns - Actions expire after N more turns
  • Icon flexibility - SVG strings, URLs, or emoji

💡 Tip: Click the "Chat with Acme" button in the bottom-right corner to open the widget and try the demo scenarios.

Action Events

Action events will appear here when you interact with action buttons in the widget...

Test Scenarios

Try typing these messages in the widget to see different action button patterns:

Standard Actions
Chat, Call-Me, Find Location buttons
"Help me get started"
Context-Specific
View account, download report
"Show my account status"
Time-Sensitive
Actions expire after next turn
"Special offers"
Send Query Actions
Buttons that send queries for the user
"Show me pricing"
Custom Handover
Handover with custom message
"I need urgent help"
Disable All on Click
All buttons disabled when one is clicked
"Choose a plan"

Configuration Example

// Via message interceptor
messageInterceptor: async (message, context) => {
  return {
    handled: true,
    response: {
      text: "Hello! How can I help you?",
      role: "assistant",
      actions: {
        position: "bottom",
        alignment: "center",
        spacing: "0.75rem",
        actions: [
          {
            id: "chat-agent",
            label: "Chat with Agent",
            icon: { type: "emoji", content: "💬" },
            action: { type: "trigger_handover" },
            style: {
              backgroundColor: "#2563eb",
              iconColor: "#ffffff",
            },
            behavior: {
              oneTimeUse: true,
            },
          },
        ],
      },
    },
  };
};

Action Types

trigger_handover

Triggers agent handover following the established handover pattern. Emits "handover" event. Supports custom message override.

{
  type: "trigger_handover",
  payload: {
    reason: "user_requested",
    priority: "normal",
    message: "Connecting you to our priority support team...", // Optional custom message
    metadata: {
      /* optional */
    },
  },
}

open_url

Opens URL with security validation (http/https/tel/mailto only).

{
  type: "open_url",
  url: "https://example.com/page",
  target: "_blank", // or "_self", "_parent", "_top"
}

send_event

Emits custom event through event emitter. Emits "customAction" event.

{
  type: "send_event",
  eventName: "download_statement",
  eventData: {
    /* optional */
  },
}

send_query

Sends a query on behalf of the user. Useful for quick shortcuts to common questions. Supports optional displayText to show different text in chat vs what's sent to API.

{
  type: "send_query",
  queryText: "What are your pricing plans?",
  displayText: "Show Pricing" // Optional: shown in chat instead of queryText
}

Behavior Options

oneTimeUse

Disables the action after the first click. Useful for actions like "Request Callback" that shouldn't be repeated.

disableAllOnClick

When combined with oneTimeUse, disables ALL buttons in the group when any button is clicked. Perfect for mutually exclusive choices like plan selection.

expiresAfterTurns

Auto-disables the action after N more conversation turns. Useful for time-sensitive offers or context-dependent actions.

Listening to Events

widget.on("actionClick", (data) => {
  console.log("Action clicked:", data.actionId, data.actionType);
});

widget.on("handover", (data) => {
  console.log("Handover triggered:", data.reason);
});

widget.on("customAction", (data) => {
  console.log("Custom event:", data.eventName, data.eventData);
});

widget.on("sendQuery", (data) => {
  console.log("Query sent:", data.queryText, data.displayText);
});