Goal
Render ```mermaid fenced code blocks as actual SVG diagrams using Mermaid, fully offline, no CDN.
Why
Mermaid is the dominant diagram-as-code language for Markdown docs. GitHub renders these natively, so users expect to see diagrams when reading the same files locally.
Proposed approach
npm install --save-dev mermaid — heads-up: Mermaid is the heaviest dependency (~2 MB minified). Tree-shaking via Rollup will help but the bundle will still grow significantly.
- Import and initialise in
src/content.ts:
import mermaid from 'mermaid';
Rollup bundles it into content.bundle.js. Consider lazy-loading (see Optimizations).
- After
marked.parse(), post-process the DOM: find every pre code.language-mermaid, pass the source to mermaid.render(), replace the <pre> with the resulting SVG.
- Theme: call
mermaid.initialize({ theme: 'default' | 'dark' }) based on window.matchMedia('(prefers-color-scheme: dark)').
Optimizations to consider
- Lazy load. Only import Mermaid when the parsed output contains a
language-mermaid block — avoids the ~2 MB cost on docs without diagrams. With Rollup, this means a dynamic import('mermaid') call.
- Cache rendered SVGs keyed by source hash to avoid re-rendering on every toggle.
Constraints
- No CDN. Mermaid bundled and shipped locally.
- Watch for CSP violations — Mermaid uses runtime
<style> injection. May need content_security_policy adjustments in both manifests.
Acceptance criteria
Goal
Render
```mermaidfenced code blocks as actual SVG diagrams using Mermaid, fully offline, no CDN.Why
Mermaid is the dominant diagram-as-code language for Markdown docs. GitHub renders these natively, so users expect to see diagrams when reading the same files locally.
Proposed approach
npm install --save-dev mermaid— heads-up: Mermaid is the heaviest dependency (~2 MB minified). Tree-shaking via Rollup will help but the bundle will still grow significantly.src/content.ts:content.bundle.js. Consider lazy-loading (see Optimizations).marked.parse(), post-process the DOM: find everypre code.language-mermaid, pass the source tomermaid.render(), replace the<pre>with the resulting SVG.mermaid.initialize({ theme: 'default' | 'dark' })based onwindow.matchMedia('(prefers-color-scheme: dark)').Optimizations to consider
language-mermaidblock — avoids the ~2 MB cost on docs without diagrams. With Rollup, this means a dynamicimport('mermaid')call.Constraints
<style>injection. May needcontent_security_policyadjustments in both manifests.Acceptance criteria
```mermaid\nflowchart LR\nA --> B\n```block renders as an SVG diagram