---
title: Configuration
description: Learn how to configure Streamdown in your project.
url: "https://streamdown.ai/docs/configuration"
docs_index: /llms.txt
lastUpdated: 2026-10-19
type: reference
summary: All available props and options for the Streamdown component.
prerequisites:
  - /docs/getting-started
related:
  - /docs/usage
  - /docs/plugins
---

> For an index of all documentation, see [/llms.txt](/llms.txt).

Streamdown can be configured to suit your needs. This guide will walk you through the available options and how to configure them.

## Core Props

| Property                   | Type                       | Description                                                                                                                                                    |
| -------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children`                 | `string`                   | The Markdown content to render                                                                                                                                 |
| `parseIncompleteMarkdown`  | `boolean`                  | Enable remend preprocessor for unterminated Markdown blocks                                                                                                    |
| `remend`                   | `RemendOptions`            | Configure which Markdown completions remend should perform                                                                                                     |
| `normalizeHtmlIndentation` | `boolean`                  | Normalize indentation in HTML blocks to prevent 4+ space indents from being treated as code blocks                                                             |
| `isAnimating`              | `boolean`                  | Indicates if content is currently streaming (disables copy buttons)                                                                                            |
| `className`                | `string`                   | CSS class for the container element                                                                                                                            |
| `mode`                     | `"streaming" \| "static"`  | Mode of the Streamdown component                                                                                                                               |
| `dir`                      | `"auto" \| "ltr" \| "rtl"` | Text direction. 'ltr'/'rtl' force a single direction. 'auto' detects per block (content-majority strong characters, first-strong on ties). Code is always LTR. |

### Text direction (`dir`)

Use `dir` when rendering RTL languages (Persian, Arabic, Hebrew, etc.) or mixed-script content:

```tsx title="app/page.tsx"
<Streamdown dir="auto" mode="static">
  {markdown}
</Streamdown>
```

| Value             | Behavior                                                            |
| ----------------- | ------------------------------------------------------------------- |
| `"ltr"` / `"rtl"` | Applies that direction to the root (static) or each streaming block |
| `"auto"`          | Detects direction independently per block                           |
| omitted           | No `dir` attribute is set                                           |

With `dir="auto"`:

- **Streaming mode** — direction is resolved once per parsed markdown block (same unit used for memoized streaming updates).
- **Static mode** — a rehype pass assigns `dir` on each semantic block (headings, paragraphs, list items, blockquotes, definition terms/descriptions, captions, and table cells) so mixed Persian/Hebrew/Arabic/English documents keep the correct base direction without splitting the document (footnotes and cross-block references still resolve).
- **Detection** — counts Unicode strong letters after stripping common markdown syntax. The majority wins; equal counts fall back to the first strong character. Fenced and inline code are excluded from the count so LTR identifiers do not skew surrounding RTL prose.
- **Code** — fenced code blocks and code-related elements are always LTR so line numbers and syntax highlighting stay correct inside RTL documents.

## Styling Props

| Property            | Type                                                        | Description                                                                                                                                                                                                            |
| ------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `shikiTheme`        | `[ThemeInput, ThemeInput]`                                  | Light and dark themes for code syntax highlighting. Accepts bundled theme names or custom theme objects (ThemeRegistrationAny).                                                                                        |
| `components`        | `object`                                                    | Custom component overrides for Markdown elements                                                                                                                                                                       |
| `fallbackComponent` | `React.ComponentType<Record<string, unknown> & ExtraProps>` | Fallback renderer for HTML tags or allowedTags entries that have no matching key in components. Built-in and explicit components entries always win — this is not a full unstyled mode. See Components.                |
| `allowedTags`       | `Record<string, string[]>`                                  | Custom HTML tags to allow through sanitization, with their permitted attributes. Use with 'components' or 'fallbackComponent' to render custom tags like \<ref> or \<mention>. Only works with default rehype plugins. |
| `literalTagContent` | `string[]`                                                  | Tags whose children are treated as plain text (no markdown parsing). Useful when tag children contain underscores or asterisks that would otherwise be formatted. Tags must also appear in allowedTags.                |
| `prefix`            | `string`                                                    | Tailwind CSS prefix prepended to all utility classes. Enables Tailwind v4 prefix() support. User-supplied className values are also prefixed.                                                                          |

## Plugin Props

| Property                   | Type          | Description                                                                                                                                                                                                                                                                                                                                                      |
| -------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rehypePlugins`            | `Pluggable[]` | Rehype plugins for HTML processing                                                                                                                                                                                                                                                                                                                               |
| `remarkPlugins`            | `Pluggable[]` | Remark plugins for Markdown processing                                                                                                                                                                                                                                                                                                                           |
| `disableAutolinkProtocols` | `string[]`    | Disable GFM / CommonMark autolinking for specific URL protocols (e.g. \['mailto'] stops bare email addresses from becoming links). Accepts protocol names with or without a trailing colon, case-insensitive. Only affects autolinks (bare URLs/emails and \<...> forms); explicit \[text]\(url) links are unaffected, even when the label reconstructs the URL. |

**Default Rehype Plugins:**

- `rehype-raw` - HTML support
- `rehype-sanitize` - XSS protection and safe HTML rendering
- `rehype-harden` - Security hardening (permissive by default: allows all image and link prefixes, data images enabled; see [Security](/docs/security) to restrict image origins for AI chat apps)

**Default Remark Plugins:**

- `remark-gfm` - GitHub Flavored Markdown

Math rendering and CJK support require installing separate plugins. See [Mathematics](/docs/plugins/math) and [CJK Language Support](/docs/plugins/cjk).

## Feature-Specific Props

| Property                | Type                                                 | Description                                                                                                                                                                                                                                                                                                              |
| ----------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `mermaid`               | `MermaidOptions`                                     | Mermaid diagram configuration and error handling                                                                                                                                                                                                                                                                         |
| `controls`              | `ControlsConfig`                                     | Control visibility of interactive buttons, custom download filenames, and copy callbacks (\`onCopy\` / \`onError\`) for code, tables, and mermaid diagrams.                                                                                                                                                              |
| `lineNumbers`           | `boolean`                                            | Show line numbers in code blocks. Can be overridden per block with the noLineNumbers meta string.                                                                                                                                                                                                                        |
| `codeBlockRawLanguages` | `string[]`                                           | Code fence languages rendered verbatim as plain monospace text (no syntax highlighting, line numbers or controls). Useful for ASCII / Unicode box-drawing diagrams. See \[Code Blocks]\(/docs/code-blocks#raw-languages).                                                                                                |
| `codeBlockMaxHeight`    | `number \| string`                                   | Max height for fenced code blocks. Numbers are treated as px. Strings pass through as CSS values (e.g. \`50vh\`). Set to \`0\` or \`Infinity\` to disable. While streaming (\`isAnimating\`), the block auto-scrolls to the bottom and unpins if the user scrolls up. See \[Code Blocks]\(/docs/code-blocks#max-height). |
| `tableMaxHeight`        | `number \| string`                                   | Max height for tables. Numbers are treated as px. Strings pass through as CSS values (e.g. \`50vh\`). Set to \`0\` or \`Infinity\` to disable. While streaming (\`isAnimating\`), the table body auto-scrolls to the bottom and unpins if the user scrolls up. See \[GitHub Flavored Markdown]\(/docs/gfm#max-height).   |
| `animated`              | `boolean \| AnimateOptions`                          | Enable character-by-character animation for streaming content. See \[Animation]\(/docs/animation).                                                                                                                                                                                                                       |
| `linkSafety`            | `LinkSafetyConfig`                                   | Configure link safety modals for external URLs. See \[Link Safety]\(/docs/link-safety).                                                                                                                                                                                                                                  |
| `portal`                | `HTMLElement \| null \| (() => HTMLElement \| null)` | DOM node (or getter) used as the portal target for built-in overlays. Useful for micro-frontends and scoped or prefixed CSS.                                                                                                                                                                                             |
| `plugins`               | `PluginConfig`                                       | Plugin configuration for math, mermaid, code highlighting, and CJK support. See \[Plugins]\(/docs/plugins).                                                                                                                                                                                                              |
| `icons`                 | `Partial<IconMap>`                                   | Custom icons to override the defaults used in controls. See the IconMap interface for available keys.                                                                                                                                                                                                                    |
| `translations`          | `Partial<StreamdownTranslations>`                    | Override default English labels for controls and modals. See \[Internationalization]\(/docs/internationalization).                                                                                                                                                                                                       |
| `caret`                 | `"block" \| "circle"`                                | Show a caret indicator at the end of streaming content. See \[Carets]\(/docs/carets).                                                                                                                                                                                                                                    |
| `onAnimationStart`      | `() => void`                                         | Called when isAnimating transitions from false to true. Suppressed in static mode. Memoize with useCallback. See \[Animation]\(/docs/animation).                                                                                                                                                                         |
| `onAnimationEnd`        | `() => void`                                         | Called when isAnimating transitions from true to false. Suppressed in static mode. Memoize with useCallback. See \[Animation]\(/docs/animation).                                                                                                                                                                         |

### Portal Target

By default, Mermaid fullscreen, table fullscreen, and the built-in link safety modal render into `document.body`. Use `portal` to keep these overlays inside a micro-frontend or another subtree that provides scoped CSS, prefixed Tailwind utilities, or a specific stacking context.

```tsx title="app/page.tsx"
const portalRef = useRef<HTMLDivElement>(null);

return (
  <div className="my-app">
    <div ref={portalRef} />
    <Streamdown portal={() => portalRef.current}>{markdown}</Streamdown>
  </div>
);
```

The getter form is useful when the portal element is assigned after the first render. Returning `null` falls back to `document.body`. A custom `linkSafety.renderModal` controls its own placement and is not moved by this prop. Like `urlTransform` and `allowElement`, `portal` is an initializing prop: swapping it for a different target alone does not re-render, so prefer the getter form — it is resolved each time an overlay opens.

### Mermaid Options

The `mermaid` prop accepts an object with the following properties:

| Property         | Type                                              | Description                                                  |
| ---------------- | ------------------------------------------------- | ------------------------------------------------------------ |
| `config`         | `MermaidConfig`                                   | Custom configuration for Mermaid diagrams                    |
| `errorComponent` | `React.ComponentType<MermaidErrorComponentProps>` | Custom React component for handling Mermaid rendering errors |

## Element Filtering Props

These props match the [react-markdown](https://github.com/remarkjs/react-markdown) API, making Streamdown a drop-in replacement.

| Property             | Type                                                                        | Description                                                                                                                                                                                                     |
| -------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowedElements`    | `string[]`                                                                  | Tag names to allow (all others are removed). Cannot combine with disallowedElements.                                                                                                                            |
| `disallowedElements` | `string[]`                                                                  | Tag names to disallow (all others are kept). Cannot combine with allowedElements.                                                                                                                               |
| `allowElement`       | `(element: Element, index: number, parent: Parent \| undefined) => boolean` | Custom filter function called for each element. Return false to remove. Applied after allowedElements/disallowedElements.                                                                                       |
| `unwrapDisallowed`   | `boolean`                                                                   | When true, disallowed elements are replaced by their children instead of being removed entirely.                                                                                                                |
| `skipHtml`           | `boolean`                                                                   | Ignore raw HTML in Markdown completely (removes raw HTML nodes from the tree).                                                                                                                                  |
| `urlTransform`       | `(url: string, key: string, node: Element) => string \| null \| undefined`  | Transform all URLs in the Markdown (links, images, etc). Return an empty string to remove the URL. Defaults to defaultUrlTransform (passthrough). URL security is handled by rehype-sanitize and rehype-harden. |

### Element filtering example

```tsx title="app/page.tsx"
// Only allow paragraphs, links, and emphasis
<Streamdown allowedElements={["p", "a", "em"]}>
  {markdown}
</Streamdown>

// Remove images but keep everything else
<Streamdown disallowedElements={["img"]}>
  {markdown}
</Streamdown>

// Remove images but keep their alt text
<Streamdown disallowedElements={["img"]} unwrapDisallowed>
  {markdown}
</Streamdown>

// Custom filter: remove all h3+ headings
<Streamdown
  allowElement={(element) =>
    !["h3", "h4", "h5", "h6"].includes(element.tagName)
  }
>
  {markdown}
</Streamdown>
```

### URL transform example

```tsx title="app/page.tsx"
import { Streamdown, defaultUrlTransform } from 'streamdown';

// Proxy all image URLs through your CDN
<Streamdown
  urlTransform={(url, key, node) => {
    if (key === 'src') {
      return `https://your-cdn.com/proxy?url=${encodeURIComponent(url)}`;
    }
    return defaultUrlTransform(url, key, node);
  }}
>
  {markdown}
</Streamdown>
```

## Advanced Props

| Property                    | Type                              | Description                                                     |
| --------------------------- | --------------------------------- | --------------------------------------------------------------- |
| `BlockComponent`            | `React.ComponentType<BlockProps>` | Custom block component for rendering individual markdown blocks |
| `parseMarkdownIntoBlocksFn` | `(markdown: string) => string[]`  | Custom function to parse markdown into blocks                   |

The `controls` prop can be configured granularly. Set a block type to `false` to hide all of its buttons, or pass an object to toggle individual actions. For downloads, pass `{ filename: "customName" }` to set a custom base filename — the file extension is added automatically. For code and Mermaid copy buttons, pass `{ onCopy, onError }` to hook into the default copy flow without replacing the button.

```tsx title="app/page.tsx"
<Streamdown
  controls={{
    table: {
      copy: true, // Show table copy button
      download: { filename: "report" }, // Download as report.csv / report.md
      fullscreen: true, // Show table fullscreen button
      csvSeparator: ",", // "," | ";" | "\t" | "auto"
    },
    code: {
      copy: {
        onCopy: () => console.log("copied"), // optional success callback
        onError: (error) => console.error(error), // optional error callback
      },
      download: { filename: "myScript" }, // Download as myScript.js, myScript.py, etc.
    },
    mermaid: {
      download: { filename: "flowchart" }, // Download as flowchart.svg / flowchart.png / flowchart.mmd
      copy: {
        onCopy: () => console.log("copied"),
        onError: (error) => console.error(error),
      },
      fullscreen: true, // Show mermaid fullscreen button
      panZoom: true, // Show mermaid pan/zoom controls
    },
  }}
>
  {markdown}
</Streamdown>
```

You can still use `copy: true` / `copy: false` to show or hide the button, and `download: true` (or omit it) to keep the default filenames: `file.<ext>` for code, `table.csv` / `table.md` for tables, and `diagram.svg` / `diagram.png` / `diagram.mmd` for mermaid.

### Remend Options

The `remend` prop configures which Markdown completions are performed during streaming. All options default to `true` when not specified. Set an option to `false` to disable that completion:

| Property              | Type                        | Description                                                                                        |
| --------------------- | --------------------------- | -------------------------------------------------------------------------------------------------- |
| `links`               | `boolean`                   | Complete incomplete links                                                                          |
| `images`              | `boolean`                   | Complete incomplete images                                                                         |
| `bold`                | `boolean`                   | Complete bold formatting (\*\*)                                                                    |
| `italic`              | `boolean`                   | Complete italic formatting (\* and \_)                                                             |
| `boldItalic`          | `boolean`                   | Complete bold-italic formatting (\*\*\*)                                                           |
| `inlineCode`          | `boolean`                   | Complete inline code formatting (\`)                                                               |
| `strikethrough`       | `boolean`                   | Complete strikethrough formatting (\~\~)                                                           |
| `katex`               | `boolean`                   | Complete block KaTeX math (\$\$)                                                                   |
| `setextHeadings`      | `boolean`                   | Handle incomplete setext headings                                                                  |
| `comparisonOperators` | `boolean`                   | Escape > as comparison operators in list items                                                     |
| `htmlTags`            | `boolean`                   | Strip incomplete HTML tags at end of streaming text                                                |
| `linkMode`            | `"protocol" \| "text-only"` | How to handle incomplete links: 'protocol' uses a placeholder URL, 'text-only' displays plain text |
| `handlers`            | `RemendHandler[]`           | Custom handlers to extend remend with your own completion logic                                    |

```tsx title="app/page.tsx"
<Streamdown
  remend={{
    links: false, // Disable link completion
    katex: false, // Disable KaTeX completion
  }}
>
  {markdown}
</Streamdown>
```

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)