By·

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.

Rendered Mermaid diagram example for How to Embed Mermaid Diagrams in HTML Pages
Rendered Mermaid diagram example from this tutorial.

# 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

 as the default selector. Earlier versions used 
which still works but is deprecated.

Controlling the Theme

You can set the theme globally during initialization:

<script>
  mermaid.initialize({
    startOnLoad: true,
    theme: 'dark',
    themeVariables: {
      primaryColor: '#4f46e5',
      primaryTextColor: '#fff',
      lineColor: '#6b7280'
    }
  });
</script>

Available built-in themes: default, forest, dark, neutral, base. The base theme gives you full control through themeVariables without inheriting preset colors.

Multiple Diagrams on One Page

Mermaid renders every

 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>

Each diagram is rendered independently, so a syntax error in one does not break the others.

Manual Rendering (No Auto-Init)

If you need control over when diagrams render — for example, when content loads dynamically — skip 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>

This is essential for single-page applications, content loaded via AJAX, or diagrams added after the initial page load.

Rendering Into a Specific Container

For more control, render a diagram string into a target element:

<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>

The 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)

In single-page apps, diagrams added after navigation will not auto-render. Re-run Mermaid after each route change:

// After each route transition
function onRouteChange() {
  mermaid.initialize({ startOnLoad: false });
  meragram.run({ querySelector: '.mermaid' });
}

// Example: listen to popstate
window.addEventListener('popstate', onRouteChange);

Framework-specific notes:

  • React — Render
     inside useEffect after the component mounts, then call mermaid.run().
  • Vue — Use nextTick after updating the DOM, then run Mermaid.
  • Next.js / Nuxt — Diagrams must be client-only. Wrap the diagram component with dynamic(() => ..., { ssr: false }) in Next.js or in Nuxt.

Responsive Diagrams

Mermaid SVGs use a fixed viewBox by default. To make diagrams responsive, wrap them in a container:

<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>

For very wide diagrams, horizontal scrolling via overflow-x: auto is better than scaling down to unreadable text.

Full Working HTML Template

Here is a complete file you can save and open directly in a browser:

<!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>

Save this as index.html and open it in any browser. The diagram renders instantly with no server required.

Common Gotchas

1. Special characters in node labels

Mermaid uses brackets and parentheses as syntax. Wrap text in quotes if it contains these characters:

graph TD
    A["Node with (parens) &amp; symbols"]
Try in Editor →

2. HTML inside diagrams

If you have unescaped < 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