Overview
The components property is the primary extension point in @ant-design/x-markdown. It lets you map Markdown/HTML nodes to your own React components so you can control rendering, streaming behavior, and business data interaction in one place. To extend further, see Plugins and custom renderers.
import React from 'react';import { Mermaid, Think, XMarkdown } from '@ant-design/x';<XMarkdowncomponents={{think: Think,mermaid: Mermaid,}}/>;
| Property | Description | Type | Default |
|---|---|---|---|
| domNode | Component DOM node from html-react-parser, containing parsed DOM node information | DOMNode | - |
| streamStatus | Streaming rendering supports two states: loading indicates content is being loaded, done indicates loading is complete. Currently only supports HTML format and fenced code blocks. Since indented code has no clear end marker, it always returns done status | 'loading' | 'done' | - |
| children | Content wrapped in the component, containing the text content of DOM nodes | React.ReactNode | - |
| rest | Component properties, supports all standard HTML attributes (such as href, title, className, etc.) and custom data attributes | Record<string, any> | - |
Custom components often need business data (theme, callbacks, etc.). Passing it via an inline function creates a new component reference on every render, so React unmounts and remounts the whole subtree — losing internal state and hurting performance in streaming scenarios. Use componentsProps to pass extra props while keeping component references stable:
import React from 'react';import { XMarkdown } from '@ant-design/x';// ❌ Inline function: a new component type every render, the subtree is rebuilt<XMarkdowncomponents={{'custom-chart': (props) => <CustomChart {...props} theme={theme} onSelect={onSelect} />,}}/>;// ✅ Stable component reference; extra data flows through componentsProps<XMarkdowncomponents={{ 'custom-chart': CustomChart }}componentsProps={{ 'custom-chart': { theme, onSelect } }}/>;
componentsProps is keyed by tag name. Its props are merged with the parsed HTML attributes and passed to the component (componentsProps wins on conflicts). When componentsProps changes, the component receives a normal props update without being remounted.
components; use componentsProps to pass extra data.streamStatus to separate loading UI (loading) from finalized UI (done).streamStatus === 'done'.If block-level custom tags contain unexpected blank lines, Markdown parsers may end the HTML block early and convert trailing content into paragraphs. To avoid this: