How to Embed Mermaid Diagrams in HTML Pages
Step-by-step guide to adding Mermaid.js diagrams to any HTML page using CDN, auto-init, and manual rendering — with copy-paste examples.
# How to Embed Mermaid Diagrams in HTML Pages
Mermaid diagrams render inside any web page with just a few lines of code. No build tools, no frameworks, no server-side rendering required. If you have an HTML file, you can have a working diagram in under a minute.
This guide covers every method — from the simplest CDN drop-in to custom rendering workflows — with real code you can copy and paste.
The Fastest Method: CDN + Auto-Init
Add two lines to your HTML and Mermaid renders every block automatically:
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({ startOnLoad: true });</script>Then add a diagram anywhere in the page:
<pre class="mermaid">
graph TD
A[User Login] --> B{Valid Credentials?}
B -->|Yes| C[Dashboard]
B -->|No| D[Error Message]
</pre>When the page loads, Mermaid scans for all elements with the class mermaid and renders them. That is the entire integration for most use cases.
Important: Mermaid 10+ uses You can set the theme globally during initialization: Available built-in themes: Mermaid renders every Each diagram is rendered independently, so a syntax error in one does not break the others. If you need control over when diagrams render — for example, when content loads dynamically — skip This is essential for single-page applications, content loaded via AJAX, or diagrams added after the initial page load. For more control, render a diagram string into a target element: The In single-page apps, diagrams added after navigation will not auto-render. Re-run Mermaid after each route change: Framework-specific notes: Mermaid SVGs use a fixed viewBox by default. To make diagrams responsive, wrap them in a container: For very wide diagrams, horizontal scrolling via Here is a complete file you can save and open directly in a browser: Save this as 1. Special characters in node labels Mermaid uses brackets and parentheses as syntax. Wrap text in quotes if it contains these characters: 2. HTML inside diagrams If you have unescaped 3. Content Security Policy (CSP) If your site has a strict CSP, the CDN script may be blocked. Whitelist 4. Older Mermaid versions The CDN URL If you are building static HTML with Mermaid diagrams that need to look correct in social previews or SEO crawlers, Mermaid alone will not work — crawlers do not execute JavaScript. For those cases, render diagrams at build time using Then paste the SVG inline in your HTML. This gives you diagrams that render for everyone, including search engines and social link previews. For testing diagrams before embedding them, paste your Mermaid code into MermaidEditor.lol. You can preview live, try different themes, and export as SVG or PNG for situations where you need a static image. Embedding Mermaid in HTML is a two-line integration that works in any static page, blog, or documentation site. Use the CDN approach for quick setups, The key decision is whether your diagrams are static (auto-init is fine) or dynamic (you need manual Do I need Node.js to use Mermaid in HTML? No. Mermaid is a client-side library. Include the CDN script and it runs entirely in the browser. Node.js is only needed if you want to pre-render diagrams to SVG. Can I use Mermaid in an email? No. Email clients do not execute JavaScript. Export your diagram as a PNG from MermaidEditor.lol and embed the image instead. Which browsers support Mermaid? All modern browsers — Chrome, Firefox, Safari, and Edge. Internet Explorer is not supported. How do I change the diagram size? Mermaid SVGs scale naturally with their container. Set the container width with CSS and the diagram follows. For specific sizing, use as the default selector. Earlier versions used Controlling the Theme
<script>
mermaid.initialize({
startOnLoad: true,
theme: 'dark',
themeVariables: {
primaryColor: '#4f46e5',
primaryTextColor: '#fff',
lineColor: '#6b7280'
}
});
</script>default, forest, dark, neutral, base. The base theme gives you full control through themeVariables without inheriting preset colors.Multiple Diagrams on One Page
block independently. You can mix diagram types freely:<h2>System Architecture</h2>
<pre class="mermaid">
graph LR
Client --> API --> Database
</pre>
<h2>Deployment Pipeline</h2>
<pre class="mermaid">
sequenceDiagram
participant Dev
participant CI
participant Deploy
Dev->>CI: Push to main
CI->>Deploy: Trigger deploy
Deploy-->>CI: Health check OK
</pre>
<h2>Database Schema</h2>
<pre class="mermaid">
erDiagram
USER ||--o{ ORDER : places
ORDER ||--|{ LINE_ITEM : contains
</pre>Manual Rendering (No Auto-Init)
startOnLoad and call the render function yourself:<pre id="my-diagram" class="mermaid">
graph TD
A[Start] --> B[End]
</pre>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({ startOnLoad: false });
mermaid.run({
querySelector: '#my-diagram'
});
</script>Rendering Into a Specific Container
<div id="diagram-output"></div>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
async function renderDiagram(code) {
const { svg } = await mermaid.render('diagram-id', code);
document.getElementById('diagram-output').innerHTML = svg;
}
renderDiagram('graph TD\n A[Hello] --> B[World]');
</script>mermaid.render() function takes a unique ID and a Mermaid code string, and returns an SVG element. This approach lets you generate diagrams from user input, databases, or any dynamic source.Handling Dynamic Content (SPA / Router)
// After each route transition
function onRouteChange() {
mermaid.initialize({ startOnLoad: false });
meragram.run({ querySelector: '.mermaid' });
}
// Example: listen to popstate
window.addEventListener('popstate', onRouteChange); inside useEffect after the component mounts, then call mermaid.run().nextTick after updating the DOM, then run Mermaid.dynamic(() => ..., { ssr: false }) in Next.js or in Nuxt.Responsive Diagrams
<style>
.mermaid-container {
width: 100%;
overflow-x: auto;
}
.mermaid-container svg {
max-width: 100%;
height: auto;
}
</style>
<div class="mermaid-container">
<pre class="mermaid">
graph LR
A[Long Node Label] --> B[Another Node] --> C[Third Node] --> D[Fourth Node]
</pre>
</div>overflow-x: auto is better than scaling down to unreadable text.Full Working HTML Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mermaid Diagram Example</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
max-width: 900px;
margin: 2rem auto;
padding: 0 1rem;
line-height: 1.6;
}
h1 { color: #1f2937; }
pre.mermaid {
background: #f9fafb;
padding: 1.5rem;
border-radius: 8px;
border: 1px solid #e5e7eb;
overflow-x: auto;
}
pre.mermaid svg { max-width: 100%; height: auto; }
</style>
</head>
<body>
<h1>My Documentation</h1>
<p>Below is a live Mermaid diagram rendered entirely in the browser.</p>
<pre class="mermaid">
flowchart TD
A[Write Code] --> B[Run Tests]
B --> C{Pass?}
C -->|Yes| D[Deploy]
C -->|No| E[Fix Bug]
E --> A
</pre>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({ startOnLoad: true, theme: 'default' });</script>
</body>
</html>index.html and open it in any browser. The diagram renders instantly with no server required.Common Gotchas
Try in Editor →graph TD
A["Node with (parens) & symbols"]< or > in your Mermaid code, the browser may interpret them as HTML tags before Mermaid sees them. The tag prevents most of this, but be cautious with blocks near Mermaid code.cdn.jsdelivr.net or self-host the Mermaid bundle:<!-- Download mermaid.min.js and serve locally -->
<script src="/js/mermaid.min.js"></script>mermaid/dist/mermaid.min.js loads the latest version. For stability, pin a specific version:<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>Server-Side Rendering Considerations
@mermaid-js/mermaid-cli and embed the resulting SVGs directly:npx mmdc -i diagram.mmd -o diagram.svgPreview and Export
Final Thoughts
mermaid.render() for dynamic content, and the CLI for server-side rendering when you need diagrams to work without JavaScript.mermaid.run() after DOM updates). Get that right and everything else is configuration.FAQ
style attributes on the SVG element after rendering.