Chat Components

Interactive Components

Copy page

Render clickable components inside AI responses that programmatically send follow-up messages on the user's behalf.

Custom components let your agent render rich, interactive UI inside chat responses. Combined with chatFunctionsRef (React) or the widget instance (JavaScript), those components can programmatically submit follow-up messages when a user clicks them, creating guided, conversational workflows without the user needing to type.

How it works

  1. Your agent calls a tool that emits a component data part with a type, name, and props
  2. The chat widget matches the component name to a render function you provide via the components prop
  3. Your render function builds the UI and calls submitMessage() to send a message on the user's behalf

Setup

The pattern requires two things in your aiChatSettings:

  • components - a map of component names to render functions
  • A way to call chat methods like submitMessage from inside those render functions. In React, use a chatFunctionsRef. In JavaScript, use the widget instance returned by Inkeep.EmbeddedChat().

When the agent emits a QuickActions component with an array of label/message pairs, the user sees clickable buttons. Clicking one sends that message as if the user typed it.

Example: clickable product cards

A more realistic example renders product or plan cards that let users drill into details with a single click.

When a user asks "What plans do you offer?", the agent calls its tool to emit PlanCard components. The user sees styled cards and can click any card to ask a targeted follow-up, creating a natural conversational flow.

Pre-filling the input

Instead of sending immediately, you can use updateInputMessage to pre-fill the input and let the user edit before sending. See the full list of available methods in the AIChatFunctions reference below.

Agent-side setup

For the agent to render these components, create data components in the Visual Builder. Each data component needs a name (matching the key in your components config) and a JSON schema defining its props.

Create the data components

Go to the Data Components tab in the left sidebar, then select New data component.

For the QuickActions component, use the following schema:

QuickActions schema
{
  "type": "object",
  "properties": {
    "actions": {
      "type": "array",
      "description": "List of quick action buttons to display",
      "items": {
        "type": "object",
        "description": "A single quick action button",
        "properties": {
          "label": {
            "type": "string",
            "description": "Button label shown to the user"
          },
          "message": {
            "type": "string",
            "description": "Message to submit when clicked"
          }
        },
        "required": ["label", "message"]
      }
    }
  },
  "required": ["actions"]
}

For the PlanCard component:

PlanCard schema
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Plan name, e.g. Starter, Pro, Enterprise"
    },
    "price": {
      "type": "string",
      "description": "Formatted price, e.g. $29/mo"
    },
    "features": {
      "type": "array",
      "description": "List of plan features",
      "items": {
        "type": "string",
        "description": "A single plan feature, e.g. Unlimited projects"
      }
    }
  },
  "required": ["name", "price", "features"]
}

Add the data components to your sub agent

Open your agent's Sub Agent settings and add both data components. The agent will automatically use them when the conversation calls for it.

See Sub Agents for details on adding data components.

Register the components in your chat widget

Use the same component names as keys in your components config, as shown in the setup section above. The names must match exactly.

For more on data components, see Custom UI Blocks.

Custom tool approval UI

When an agent tool requires human approval before executing, the widget shows a default approval card. You can replace this with your own UI by registering an IkpTool component.

IkpTool receives three props:

  • tool - the tool invocation state (ToolUIPart). tool.type is the tool name as provided by the widget, prefixed with tool- (e.g. tool-get_weather). Also includes tool.state, tool.input, tool.output, and tool.approval.
  • approve - a function to approve or deny the tool call. Call approve(true) to approve, approve(false) to deny.
  • renderMarkdown - a helper to render markdown strings. In React, returns a React element. In JavaScript, returns a React node (use plain text rendering instead for vanilla JS).

Tool states

StateMeaning
input-streamingTool input is being streamed
input-availableTool input is ready, execution pending
approval-requestedWaiting for user to approve or deny
approval-respondedUser has responded, execution proceeding
output-availableTool has completed successfully
output-errorTool execution failed
output-deniedUser denied the tool call

Example

IkpTool applies globally to all tool calls. To render different UI per tool, branch on tool.type:

per-tool-ui.tsx
IkpTool: (props) => {
  const { tool, approve } = props
  const toolName = tool.type.replace(/^tool-/, '')

  if (toolName === 'database-query') {
    return <DatabaseQueryApproval tool={tool} approve={approve} />
  }

  if (toolName === 'send-email') {
    return <EmailApproval tool={tool} approve={approve} />
  }

  // Fall back to a generic card for other tools
  return <GenericToolCard tool={tool} approve={approve} />
},

AIChatFunctions reference

Prop

Type

Programmatically sends a message in the chat.

Type

(message?: string) => void

Parameters

message -

Optional message text. If omitted, sends the current input value.

Programmatically updates the text in the chat input field.

Type

(message: string) => void

Parameters

message -

The new message text to set

Resets the chat to its initial state. Removes all messages and resets the chat.

Type

() => void

Displays a form overlay in the chat interface.

Type

(formSettings: AIChatFormSettings, getHelpOption?: GetHelpOption) => void

Parameters

formSettings -

Configuration object defining the form's fields and behavior

getHelpOption -

Optional getHelpOption that triggered the form (for analytics)

Programmatically sets focus to the chat input field. Useful after programmatic updates or when showing the chat interface.

Type

() => void