Mermaid quick start
Mermaid diagrams stream progressively in markstream-vue: as soon as the syntax becomes valid the chart renders, then refines as more tokens arrive. This page covers setup, a streaming example, and common fixes.
1. Install & import
pnpm add mermaidNo extra Mermaid CSS import is required. Keep markstream-vue/index.css after your reset and inside @layer components when using Tailwind/UnoCSS so utility layers do not override the renderer styles.
@import 'modern-css-reset';
@layer components {
@import 'markstream-vue/index.css';
}2. Streaming example
Mermaid renders as soon as the snippet is syntactically valid. The snippet below shows a gradual update (ideal for AI responses or long-running tasks):
<script setup lang="ts">
import MarkdownRender from 'markstream-vue'
import { ref } from 'vue'
const content = ref('')
const steps = [
'```mermaid\n',
'graph TD\n',
'A[Start]-->B{Is valid?}\n',
'B -- Yes --> C[Render]\n',
'B -- No --> D[Wait]\n',
'```\n',
]
let i = 0
const id = setInterval(() => {
content.value += steps[i] || ''
i++
if (i >= steps.length)
clearInterval(id)
}, 120)
</script>
<template>
<MarkdownRender :content="content" />
<!-- Diagram progressively appears as content streams in -->
</template>Quick try — paste this Markdown into a page or component:
\`\`\`mermaid
graph LR
A[Start]-->B
B-->C[End]
\`\`\`3. Advanced component: MermaidBlockNode
Need header controls, export buttons, or a pseudo-fullscreen modal? Use MermaidBlockNode or override the default renderer via setCustomComponents. A runnable playground demo lives at /mermaid-export-demo. Mermaid strict mode and SVG sanitization are enabled by default. Set :is-strict="false" only for trusted diagrams that require Mermaid HTML labels.
4. When strict mode changes rendering
Moving Mermaid from loose mode to strict mode can change trusted diagrams that depended on Mermaid HTML labels or looser SVG/URL handling.
Common symptoms after upgrading:
- Labels that relied on inline HTML such as
<br>,<span>, or richer HTML fragments stop rendering as before. - Links or interactions that depended on Mermaid's looser HTML handling disappear from the final SVG.
- Previously accepted diagram markup now falls back to plain text or renders a simpler label.
If the diagram source is fully trusted and you need the old loose behavior, opt out explicitly instead of changing the global default.
Vue 3: switch a trusted Markdown surface back to loose mode
<script setup lang="ts">
import MarkdownRender from 'markstream-vue'
const trustedMarkdown = `
\`\`\`mermaid
flowchart TD
A["<b>Trusted HTML label</b><br/>line 2"] --> B
\`\`\`
`
</script>
<template>
<MarkdownRender
:content="trustedMarkdown"
:mermaid-props="{ isStrict: false }"
/>
</template>Direct component usage
<MermaidBlockNode :node="node" :is-strict="false" />Other framework entrypoints
import MarkdownRender from 'markstream-react'
<MarkdownRender content={trustedMarkdown} mermaidProps={{ isStrict: false }} /><markstream-angular
[content]="trustedMarkdown()"
[mermaidProps]="{ isStrict: false }"
/><MarkdownRender :content="trustedMarkdown" :mermaid-props="{ isStrict: false }" />Keep the default strict mode for user content, AI output, or any mixed-trust Markdown stream.
5. Troubleshooting checklist
- Peer not installed — run
pnpm add mermaid. Without it the renderer falls back to showing source text. - Async errors — check the browser console for Mermaid logs. Versions prior to 11 are unsupported; upgrade to ≥ 11.
- SSR guard — Mermaid needs the DOM. Wrap the component in
<ClientOnly>for Nuxt or checktypeof window !== 'undefined'before mounting in SSR contexts. - Heavy graphs — consider pre-rendering server-side (mermaid CLI) or caching SVG output; the component exposes
svgStringwhen usingMermaidBlockNodeexport events.
Still stuck? Reproduce the issue in the playground (pnpm play) with a minimal Markdown sample and link it when opening a bug report.
CDN usage (no bundler)
If you load Mermaid via CDN and want progressive off-main-thread parsing, inject a CDN-backed worker:
import { createMermaidWorkerFromCDN, enableMermaid, setMermaidLoader, setMermaidWorker } from 'markstream-vue'
// use the CDN global (UMD) on the main thread
setMermaidLoader(() => (window as any).mermaid)
enableMermaid(() => (window as any).mermaid)
// optional: worker used for parse/prefix checks during streaming
const { worker } = createMermaidWorkerFromCDN({
mode: 'module',
mermaidUrl: 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs',
})
if (worker)
setMermaidWorker(worker)