Documents
action-bar
action-bar
Type
External
Status
Published
Created
Mar 17, 2026
Updated
Mar 17, 2026

Buttons to interact with the message.

Anatomy#

import { ActionBarPrimitive } from "@assistant-ui/react";

const UserMessageBar = () => (
  <ActionBarPrimitive.Root>
    <ActionBarPrimitive.Edit />
    <ActionBarPrimitive.Copy />
  </ActionBarPrimitive.Root>
);

const AssistantMessageBar = () => (
  <ActionBarPrimitive.Root>
    <ActionBarPrimitive.Reload />
    <ActionBarPrimitive.Copy />
  </ActionBarPrimitive.Root>
);

API Reference#

Root#

Contains all parts of the action bar.

This primitive renders a <div> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveRootProps"
parameters={[
{
name: "asChild",
},
{
name: "hideWhenRunning",
type: "boolean",
default: "false",
description: (

Do not render the ActionBar when the thread is in running state.

),
},
{
name: "autohide",
type: '"always" | "not-last" | "never"',
default: '"never"',
description: (

Do not render the ActionBar unless the mouse is hovering over the
message.




"always": always autohide.


"not-last": only autohide if the message is not the last
one in the thread.

),
},
{
name: "autohideFloat",
type: '"always" | "single-branch" | "never"',
default: '"never"',
description: (

Float the ActionBar during autohide.




"always": always float during autohide.


"single-branch": only float if the message is the only
one in the thread.




Note: this only sets data-floating on the ActionBar. You need to set
the appropriate styles on the ActionBar to make it float.

),
},
]}
/>

Data attributeValues
[data-floating]Present when floating

Edit#

Enables edit mode on user message.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveEditProps"
parameters={[
{
name: "asChild",
},
]}
/>

Reload#

Regenerates the assistant message.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveReloadProps"
parameters={[
{
name: "asChild",
},
]}
/>

Copy#

Copies the message to the clipboard.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveCopyProps"
parameters={[
{
name: "asChild",
},
{
name: "copiedDuration",
type: "number",
description:
"The duration in milliseconds to change the message status to 'copied'.",
default: "3000",
},
]}
/>

Data attributeValues
[data-copied]Present when the message was recently copied.

Copied state#

Show a different icon for a few seconds after the message is copied.

<ActionBarPrimitive.Copy>
  <AuiIf condition={(s) => !s.message.isCopied}>
    <CopyIcon />
  </AuiIf>
  <AuiIf condition={(s) => s.message.isCopied}>
    <CopySuccessIcon />
  </AuiIf>
</ActionBarPrimitive.Copy>

or using the data-copied attribute:

<ActionBarPrimitive.Copy className="group">
  <CopyIcon className="group-data-[copied]:hidden" />
  <CheckIcon className="hidden group-data-[copied]:block" />
</ActionBarPrimitive.Copy>

Speak#

Plays the message text as speech.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveSpeakProps"
parameters={[
{
name: "asChild",
},
]}
/>

StopSpeaking#

Stops the message text from being played as speech.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveStopSpeakingProps"
parameters={[
{
name: "asChild",
},
]}
/>

Feedback Positive#

Shows a positive feedback submission button.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveFeedbackPositiveProps"
parameters={[
{
name: "asChild",
},
]}
/>

Data attributeValues
[data-submitted]Present when positive feedback was submitted.

Feedback Negative#

Shows a negative feedback submission button.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveFeedbackNegativeProps"
parameters={[
{
name: "asChild",
},
]}
/>

Data attributeValues
[data-submitted]Present when negative feedback was submitted.

ExportMarkdown#

Exports the message content as a Markdown file download by default, or calls a custom export handler when onExport is provided.

This primitive renders a <button> element unless asChild is set.

<ParametersTable
type="ActionBarPrimitiveExportMarkdownProps"
parameters={[
{
name: "asChild",
},
{
name: "filename",
type: "string",
description:
"The filename for the downloaded Markdown file. Defaults to 'message-{timestamp}.md'. Ignored when onExport is provided.",
},
{
name: "onExport",
type: "(content: string) => void | Promise",
description:
"Optional callback function that receives the message content. When provided, overrides the default Markdown download behavior. Use this to implement custom export logic (PDF, JSON, TXT, etc.).",
},
]}
/>

Examples#

Default Markdown export:

<ActionBarPrimitive.ExportMarkdown>
  <DownloadIcon />
  Export as Markdown
</ActionBarPrimitive.ExportMarkdown>

With custom filename:

<ActionBarPrimitive.ExportMarkdown filename="chat-response.md">
  <DownloadIcon />
  Download
</ActionBarPrimitive.ExportMarkdown>

Export as PDF (with custom logic):

<ActionBarPrimitive.ExportMarkdown
  onExport={async (content) => {
    const pdf = await generatePdf(content);
    downloadFile(pdf, "message.pdf");
  }}
  <FileIcon />
  Export PDF
</ActionBarPrimitive.ExportMarkdown>

Export as JSON:

<ActionBarPrimitive.ExportMarkdown
  onExport={(content) => {
    const json = JSON.stringify({ content, timestamp: Date.now() });
    const blob = new Blob([json], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "message.json";
    a.click();
    URL.revokeObjectURL(url);
  }}
  <CodeIcon />
  Export JSON
</ActionBarPrimitive.ExportMarkdown>