) {
return {String(props.node?.code || '')}
}
setCustomComponents('docs', {
echarts: EChartsBlockNode,
})
```
Notes:
- `echarts` only catches fences whose language is `echarts`.
- Code block routing priority is exact language key -> built-in `mermaid` / `d2` / `infographic` routes -> `code_block`.
- Custom `mermaid` / `d2` / `infographic` overrides keep their specialized top-level props; other custom language keys use the normal custom component contract (`node`, `ctx`, `renderNode`, and friends).
## Mermaid tuning
Common `mermaidProps` keys for streaming scenarios:
- `renderDebounceMs`: delay progressive work during rapid token bursts.
- `contentStableDelayMs`: how long source mode waits before auto-switching back to preview when content stabilizes.
- `previewPollDelayMs`: initial delay before preview polling tries to upgrade a partial preview into a full render.
- `previewPollMaxDelayMs`: cap for preview polling backoff.
- `previewPollMaxAttempts`: maximum retry count while the Mermaid source is still incomplete.
## Bundle size notes
- Optional peers are not bundled; install only what you use (`stream-monaco`, `stream-markdown`, `mermaid`, `katex`, etc.).
- Infrequent language icons are split into an async chunk and loaded on demand.
- To avoid first-hit fallback icons, preload once when the app is idle:
```tsx
import { preloadExtendedLanguageIcons } from 'markstream-react'
if (typeof window !== 'undefined')
void preloadExtendedLanguageIcons()
```
## Tailwind
- Non-Tailwind projects: keep importing `markstream-react/index.css` (includes precompiled utilities for the renderer).
- Tailwind projects (avoid duplicate utilities): import `markstream-react/index.tailwind.css` and add `require('markstream-react/tailwind')` to your `tailwind.config.js` `content`.
## Custom components (e.g. ``)
Custom tag-like blocks are exposed as nodes with `type: 'thinking'` (the tag name, no angle brackets) when you register the tag in `customHtmlTags` or register a custom component mapping for it.
```tsx
import type { NodeComponentProps } from 'markstream-react'
import NodeRenderer, { setCustomComponents } from 'markstream-react'
function ThinkingNode(props: NodeComponentProps<{ type: 'thinking', content: string }>) {
const { node, ctx } = props
return (
)
}
setCustomComponents('chat', { thinking: ThinkingNode })
```
## Type exports
`markstream-react` now exposes the core public types directly from the package root, including:
- `NodeRendererProps`
- `NodeComponentProps`
- `RenderContext`
- `RenderNodeFn`
- `CustomComponentMap`
- `CodeBlockMonacoOptions`