Docs Site & VitePress
Use this path when you are building a docs site, knowledge base, or content-heavy app where Markdown is mostly rendered as stable page content rather than a live token stream.
This is the shortest route for VitePress users who need to answer all of these together:
- should I use
contentornodes - where should
MarkdownRenderand custom nodes be registered - how should
enhanceAppbe used - where should
markstream-vue/index.cssbe imported - how do trusted tags such as
thinkingwork in docs pages
1. Prefer content unless you already own the AST
For docs sites, content is usually the right default:
| Situation | Recommended input |
|---|---|
| Markdown comes from page content, CMS fields, or normal docs pages | content |
| You pre-parse on the server or in a content pipeline | nodes |
| You are building a live stream or AI chat inside the docs site | Use AI Chat & Streaming instead |
2. Install the smallest docs-friendly set
pnpm add markstream-vue shiki stream-markdownThat gives you a good default for docs sites: regular Markdown rendering plus lightweight highlighted code blocks.
Add more peers only if your docs actually need them:
mermaidfor Mermaid fenceskatexfor mathstream-monacofor Monaco-powered code blocks
3. Register renderer and custom nodes in enhanceApp
For VitePress, the safest place to wire global docs-only behavior is docs/.vitepress/theme/index.ts.
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import MarkdownRender, { setCustomComponents } from 'markstream-vue'
import ThinkingNode from './components/ThinkingNode.vue'
import './style.css'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('MarkdownRender', MarkdownRender)
setCustomComponents('docs', {
thinking: ThinkingNode,
})
},
}Why this setup helps:
MarkdownRenderbecomes available in Markdown pages without local imports- your docs-specific overrides stay scoped to
custom-id="docs" - theme wiring is kept in one place instead of being repeated in every page
4. Render Markdown in a docs page
<script setup lang="ts">
const source = `
# Hello docs
<thinking>
This block is rendered by a custom Vue component.
</thinking>
`
</script>
<MarkdownRender
custom-id="docs"
:content="source"
:custom-html-tags="['thinking']"
/>Key points:
custom-id="docs"is what keeps overrides local to the docs sitecustom-html-tagstells the parser to emit a real custom node instead of leaving the tag as raw HTML- if the source is ordinary docs content,
contentis simpler than manually managingnodes
5. Put CSS in a predictable place
If your docs theme uses custom CSS, import markstream-vue/index.css in the theme stylesheet, after your reset or base layer.
/* docs/.vitepress/theme/style.css */
@layer components {
@import 'markstream-vue/index.css';
}
[data-custom-id='docs'] .prose {
max-width: 72ch;
}Practical rules:
- if your site has a reset, load it before this import
- if you use Tailwind or UnoCSS, keep the import inside
@layer components - if you use KaTeX, also import
katex/dist/katex.min.css
Go deeper: Tailwind Integration & Style Ordering
6. Trusted tags such as thinking
For docs pages, the recommended flow is still:
- allowlist the tag with
custom-html-tags - register the node renderer with
setCustomComponents('docs', mapping) - keep the page renderer on
custom-id="docs"
That is usually enough. Reach for parser hooks only when the source format needs AST reshaping, not just a different renderer.
Go deeper: Custom Tags & Advanced Components, API Reference
7. Common docs-site mistakes
- The custom tag renders as raw HTML: you forgot
custom-html-tags - The component never appears: it was not registered in
enhanceApp, or the mapping key does not match the tag name - Styles look broken: CSS import order is wrong, or utility layers override the renderer
- Overrides leak into other pages: use a scoped
custom-idinstead of a global mapping - Mermaid or Monaco fails in SSR-like environments: check the relevant feature page and client-only boundaries
Start here when layout or CSS still looks off: Troubleshooting
Next pages
- Installation for peer choices
- Usage & Streaming for
contentvsnodes - Custom Tags & Advanced Components for nested custom-tag patterns
- Tailwind Integration & Style Ordering for utility CSS stacks
- Troubleshooting when styles or peers behave unexpectedly