diff --git a/pages/src/components/MarkdownRenderer.tsx b/pages/src/components/MarkdownRenderer.tsx index c3d6899..0a59ed1 100644 --- a/pages/src/components/MarkdownRenderer.tsx +++ b/pages/src/components/MarkdownRenderer.tsx @@ -10,6 +10,10 @@ import { generateHeadingId } from '../utils/headingId'; // Initialize mermaid with dark theme mermaid.initialize({ startOnLoad: false, + // 'strict' makes mermaid sanitize its own SVG output (DOMPurify internally): + // safe label HTML like / is kept, scripts/handlers are stripped. + // This is why we can inject the returned SVG directly below without re-sanitizing. + securityLevel: 'strict', theme: 'dark', themeVariables: { primaryColor: '#1a1a2e', @@ -131,9 +135,16 @@ const MarkdownRenderer: React.FC = ({ content }) => { const id = `mermaid-diagram-${crypto.randomUUID()}`; const { svg } = await mermaid.render(id, code); if (cancelled) return; - // Replace the
 with rendered SVG
+        // Replace the 
 with rendered SVG. The SVG is produced by mermaid with
+        // securityLevel:'strict' (see initialize above), which already sanitizes its
+        // output. Re-running DOMPurify over the whole SVG breaks it (namespaces,
+        // inline