Button
Clickable button in a bot message — inline onClick handler, typed value, and primary/danger styling.
Overview
Button is a clickable control for an Actions row. Its onClick handler is written inline in your JSX and bound by the engine: the button that reaches the platform carries only an opaque action id, and the click is routed back to your handler. Button is generic over its value prop, so the value the click carries is fully typed.
Import
import { Button } from "@copilotkit/bot-ui";Props
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Usage
Inline reply
<Actions>
<Button
style="primary"
onClick={async ({ thread }) => {
await thread.post("🚀 Shipping!");
}}
>
Ship it
</Button>
</Actions>Typed value with awaitChoice (human-in-the-loop)
The clicked button's value is what thread.awaitChoice resolves to:
function ConfirmWrite({ action }: { action: string }) {
return (
<Message>
<Section>{action}</Section>
<Actions>
<Button style="primary" value={{ confirmed: true }}>Create</Button>
<Button style="danger" value={{ confirmed: false }}>Cancel</Button>
</Actions>
</Message>
);
}
const choice = await thread.awaitChoice<{ confirmed: boolean }>(
<ConfirmWrite action="Create Linear issue CPK-1234?" />,
);Handlers that close over data
Inline handlers are re-derived from the component's props after a restart. If a handler closes over data that can't be reconstructed from props, wrap it with bind().
Behavior
- Content-stable binding — the handler is snapshotted under a minted opaque id (
ck:…). Only that id and the button'svaluecross the wire to the platform; handler code and other props never leave the process. - Expiry — with the default in-memory ActionStore, clicks on buttons posted before a process restart are acked but ignored (no error message is posted).
On Slack
Renders as a button element: label truncated at 75 characters (SLACK_LIMITS.buttonText), action_id capped at 255, serialized value capped at 2000 characters (SLACK_LIMITS.buttonValue). Clicks are acked within Slack's 3-second deadline, then dispatched asynchronously.
Related
- InteractionContext — what the handler receives
- bind() — persist small handler args explicitly
- ActionStore — binding, rehydration, durability
- Thread.awaitChoice — block until a click resolves