# Markstream Custom Components

> Override built-in Markstream node renderers and add trusted custom tags across Vue, React, Svelte, and Angular. Use when Codex needs scoped `setCustomComponents`, renderer-local React `streamingComponents` or `htmlComponents`, Angular/Svelte `customComponents`, Vue app-scoped components, node override keys such as `image`, `code_block`, `mermaid`, or `link`, or nested renderers for tags such as `thinking`.

- Skill: `cabinet-fe/markstream-custom-components` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add cabinet-fe/markstream-custom-components`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cabinet-fe/markstream-custom-components/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: cabinet-fe (https://skillmd.com/u/cabinet-fe)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cabinet-fe/markstream-custom-components

---


# Markstream Custom Components

Use this skill when the task is to change how Markstream renders specific nodes or custom tags.

Read [references/patterns.md](references/patterns.md) before choosing an override strategy.

## Workflow

1. Classify the request.
   - `built-in override`: replace an existing renderer such as `image`, `link`, `code_block`, `mermaid`, `d2`, or `inline_code`.
   - `custom tag`: support trusted HTML-like tags such as `thinking`.
   - `parser-level`: requires token transforms or AST reshaping. Only then should you leave this skill and use low-level parser hooks.
2. Prefer scoped mappings.
   - Vue, Vue 2, Svelte, and shared Angular registration: use `setCustomComponents(customId, mapping)` instead of global mappings whenever practical, and pass the same `customId` / `custom-id`.
   - React custom tags: prefer renderer-local `streamingComponents` for parser-backed nodes or `htmlComponents` for sanitized HTML props plus `children`. Use `defineStreamingComponents(...)` / `defineHtmlComponents(...)` for typed maps. Keep `setCustomComponents` for built-in node overrides or shared legacy registration.
   - Svelte and Angular can also pass a renderer-local `customComponents` map when the override should not enter the shared registry.
   - In Vue 3 app/plugin setup, import `{ VueRendererMarkdown }` from `markstream-vue` and install it with `{ components }` when the override should be scoped to the Vue app instance.
3. Start with the smallest safe override.
   - Leaf-like nodes (`image`, `link`, `inline_code`, `mermaid`) are easier than container nodes (`heading`, `paragraph`, `list_item`).
   - If the request only changes Mermaid, use `mermaid`, not `code_block`.
4. Preserve nested Markdown when needed.
   - For trusted custom tags with inner Markdown, render `node.content` with a nested renderer.
   - Pass the same custom-tag allowlist to nested renderers.
   - Nested renderers inside a smooth-streaming parent are automatically suppressed from double pacing — do not add `smooth-streaming` to child renderers.
   - In React, `streamingComponents` automatically contributes its keys to the effective custom-tag list; do not duplicate those keys in `customHtmlTags` unless another parser path needs them.
5. Keep props and cleanup intact.
   - Preserve `node`, `loading`, `indexKey`, `customId`, and `isDark`.
   - For `mermaid` and `infographic` overrides, preserve `estimatedPreviewHeightPx` so async preview shells keep stable height during remounts.
   - Remove temporary scoped mappings with `removeCustomComponents(customId)` when the scope is no longer needed.
6. Validate with the smallest useful check.
   - Prefer a local demo, targeted test, or docs build.
   - Call out whether the implementation is safe for repeated and nested custom tags.

## Default Decisions

- Scoped overrides first, global overrides only when the whole app truly needs them.
- Leaf-node overrides before container-node overrides.
- `customHtmlTags` plus scoped custom components before parser hooks.
- In React, renderer-local component maps before registry mutation.
- Nested renderers for tag bodies that contain Markdown.

## Useful Doc Targets

- `docs/guide/component-overrides.md`
- `docs/guide/custom-components.md`
- `docs/guide/react-components.md`
- `docs/guide/components.md`
- `docs/guide/advanced.md`

