Skip to main content
Streamdown adds interactive controls to tables, code blocks, and Mermaid diagrams automatically. All controls are configurable through the controls prop.

The controls prop

The controls prop accepts a boolean or a granular configuration object:
type ControlsConfig =
  | boolean
  | {
      table?:
        | boolean
        | {
            copy?: boolean;
            download?: boolean;
            fullscreen?: boolean;
          };
      code?:
        | boolean
        | {
            copy?: boolean;
            download?: boolean;
          };
      mermaid?:
        | boolean
        | {
            download?: boolean;
            copy?: boolean;
            fullscreen?: boolean;
            panZoom?: boolean;
          };
    };
The default value is true, which enables all controls. Set controls={false} to disable every control across all block types.

Table controls

Tables rendered from GFM syntax gain three controls in the top-right corner:

Copy

Opens a dropdown menu with three copy formats:
  • Markdown — copies the table in pipe-separated Markdown syntax
  • CSV — comma-separated values for spreadsheet import
  • TSV — tab-separated values
The table is also copied as HTML for rich pasting into apps that support it.

Download

Opens a dropdown with two download formats:
  • CSV — ready for Excel, Google Sheets, etc.
  • Markdown — portable documentation format

Fullscreen

Opens the table in a modal overlay for easier reading of wide tables. Close with Escape or by clicking the backdrop.

Configuring table controls

// Disable download, keep copy and fullscreen
<Streamdown controls={{ table: { download: false } }}>
  {markdown}
</Streamdown>

// Disable all table controls
<Streamdown controls={{ table: false }}>
  {markdown}
</Streamdown>

Code block controls

Code blocks display controls in the top-right corner on hover.

Copy

Copies the raw code content (without syntax highlighting spans). Shows a checkmark for 2 seconds on success. Disabled while isAnimating={true} to prevent copying incomplete code.

Download

Downloads the code as a plain text file. The file extension is inferred from the language identifier — for example, a typescript block downloads as file.ts.

Configuring code block controls

// Disable download only
<Streamdown controls={{ code: { download: false } }}>
  {markdown}
</Streamdown>

// Disable copy only
<Streamdown controls={{ code: { copy: false } }}>
  {markdown}
</Streamdown>

// Disable all code block controls
<Streamdown controls={{ code: false }}>
  {markdown}
</Streamdown>

Mermaid diagram controls

When the @streamdown/mermaid plugin is active, diagram blocks gain four controls:

Copy

Copies the raw Mermaid source code for easy sharing and editing.

Download

Downloads the rendered diagram as an SVG file named diagram.svg.

Fullscreen

Opens the rendered diagram in a modal overlay. Useful for complex diagrams that need more space. Close with Escape or by clicking outside.

Pan and zoom

Enables interactive panning and zooming inside the diagram container. Users can scroll to zoom and drag to pan for detailed inspection of large diagrams.

Configuring Mermaid controls

// Enable pan/zoom, disable fullscreen
<Streamdown
  controls={{
    mermaid: {
      panZoom: true,
      fullscreen: false,
    },
  }}
>
  {markdown}
</Streamdown>

// Disable all Mermaid controls
<Streamdown controls={{ mermaid: false }}>
  {markdown}
</Streamdown>

Disabling all controls

<Streamdown controls={false}>
  {markdown}
</Streamdown>
This disables every copy, download, fullscreen, and pan/zoom button across all block types.

Disabling controls during streaming

Copy and download buttons are automatically disabled when isAnimating={true}. This prevents users from copying incomplete content while a response is still generating.
<Streamdown controls isAnimating={isStreaming}>
  {markdown}
</Streamdown>

Custom icons

Replace any icon in the controls UI using the icons prop. Pass a partial IconMap — only the icons you provide override the defaults.
import { Streamdown } from "streamdown";
import { CopyIcon, DownloadIcon } from "./my-icons";

<Streamdown
  icons={{
    copy: <CopyIcon />,
    download: <DownloadIcon />,
  }}
>
  {markdown}
</Streamdown>
The icons prop accepts React nodes keyed by control name. The full list of overridable icon names is defined in the IconMap type exported from streamdown.

Translations

All control labels and ARIA text are localizable via the translations prop:
import { Streamdown, defaultTranslations } from "streamdown";

<Streamdown
  translations={{
    ...defaultTranslations,
    copyCode: "Copiar código",
    downloadCode: "Descargar",
  }}
>
  {markdown}
</Streamdown>

Build docs developers (and LLMs) love