Gagan Thakur·

Mermaid.js Vue Integration: Add Diagrams to Your Vue 3 App

Step-by-step guide to integrating Mermaid.js with Vue 3. Learn how to render flowcharts, sequence diagrams, and more inside Vue components with live examples.

# Mermaid.js Vue Integration: Add Diagrams to Your Vue 3 App

Mermaid.js is one of the most popular ways to render text-based diagrams in the browser. If you're building a Vue 3 application and need flowcharts, sequence diagrams, ER diagrams, or Gantt charts — integrating Mermaid is straightforward and powerful.

This guide walks you through everything: installation, a reusable component, and real examples you can drop into any Vue 3 project.

Why Use Mermaid.js in Vue?

Mermaid lets you define diagrams as plain text strings, then renders them as SVG in the browser. No image exports, no drag-and-drop editors — just code that produces clean, scalable diagrams.

Use cases in Vue apps:

- Documentation portals and wikis

- Technical dashboards showing system flows

- Admin panels with workflow visualizations

- Developer tools with live diagram previews

Installation

Install Mermaid via npm or yarn:

npm install mermaid
# or
yarn add mermaid

Mermaid v10+ is fully ESM-compatible and works great with Vite (the default Vue 3 build tool).

Creating a Reusable MermaidDiagram Component

The cleanest approach is a single reusable component that accepts a diagram definition string as a prop.

<!-- components/MermaidDiagram.vue -->
<template>
  <div ref="container" class="mermaid-container"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import mermaid from 'mermaid'

const props = defineProps<{
  diagram: string
  theme?: string
}>()

const container = ref<HTMLDivElement | null>(null)

mermaid.initialize({
  startOnLoad: false,
  theme: props.theme ?? 'default',
  securityLevel: 'loose'
})

async function render() {
  if (!container.value) return
  container.value.innerHTML = ''
  const id = 'mermaid-' + Math.random().toString(36).slice(2)
  const { svg } = await mermaid.render(id, props.diagram)
  container.value.innerHTML = svg
}

onMounted(render)
watch(() => props.diagram, render)
watch(() => props.theme, () => {
  mermaid.initialize({ theme: props.theme ?? 'default', startOnLoad: false })
  render()
})
</script>

<style scoped>
.mermaid-container {
  width: 100%;
  overflow-x: auto;
}
</style>

Using the Component

Once created, use it anywhere in your Vue app:

<template>
  <MermaidDiagram :diagram="flowchart" />
</template>

<script setup lang="ts">
import MermaidDiagram from '@/components/MermaidDiagram.vue'

const flowchart = `
flowchart TD
    A[User visits page] --> B{Logged in?}
    B -- Yes --> C[Show Dashboard]
    B -- No --> D[Redirect to Login]
    D --> E[User logs in]
    E --> C
`
</script>

This renders a fully interactive SVG flowchart inside your Vue component.

Sequence Diagram Example

Sequence diagrams are perfect for illustrating API call flows:

sequenceDiagram
    participant Browser
    participant Vue App
    participant API Server
    participant Database

    Browser->>Vue App: User clicks "Load Data"
    Vue App->>API Server: GET /api/data
    API Server->>Database: SELECT * FROM records
    Database-->>API Server: Return rows
    API Server-->>Vue App: JSON response
    Vue App-->>Browser: Update reactive state
Try in Editor →

Pass this string as the diagram prop and the component handles the rest.

Dynamic Diagrams with Reactive Data

One of Mermaid's best features in Vue is reactivity. Because the component watches the diagram prop, you can generate diagrams dynamically from your app state:

<template>
  <div>
    <select v-model="selectedView">
      <option value="flowchart">Flowchart</option>
      <option value="sequence">Sequence</option>
    </select>
    <MermaidDiagram :diagram="currentDiagram" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import MermaidDiagram from '@/components/MermaidDiagram.vue'

const selectedView = ref('flowchart')

const diagrams: Record<string, string> = {
  flowchart: `flowchart LR
    A[Start] --> B[Process] --> C[End]`,
  sequence: `sequenceDiagram
    Alice->>Bob: Hello
    Bob-->>Alice: Hi there`
}

const currentDiagram = computed(() => diagrams[selectedView.value])
</script>

Switching the dropdown instantly re-renders the diagram — no page reload needed.

Dark Mode Support

Mermaid has built-in themes including dark. Pass the theme prop to switch:

<MermaidDiagram :diagram="myDiagram" theme="dark" />

Available themes: default, dark, forest, neutral, base.

You can also detect the user's system preference and pass it automatically:

const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
const theme = prefersDark ? 'dark' : 'default'

Server-Side Rendering (SSR / Nuxt)

Mermaid relies on browser APIs (document, window) and cannot run during SSR. In Nuxt 3 or Vite SSR mode, use a client-only wrapper:

<!-- Nuxt 3 -->
<ClientOnly>
  <MermaidDiagram :diagram="myDiagram" />
</ClientOnly>

Or in Vue Router / Vite SSR, use onMounted and check typeof window !== 'undefined' before initializing Mermaid.

Performance Tips

  • Memoize diagram strings — if your diagram doesn't change, avoid triggering re-renders by using computed or shallowRef.
  • Lazy-load Mermaid — use dynamic import (import('mermaid')) inside onMounted to keep initial bundle size down.
  • One mermaid.initialize call — calling it multiple times can cause flickering. Initialize once at app level or inside a singleton composable.

Quick Lazy-Load Pattern

onMounted(async () => {
  const mermaid = (await import('mermaid')).default
  mermaid.initialize({ startOnLoad: false, theme: 'default' })
  const { svg } = await mermaid.render('diagram-id', props.diagram)
  container.value!.innerHTML = svg
})

This keeps Mermaid out of your main bundle entirely.

Summary

Integrating Mermaid.js into Vue 3 takes about 20 lines of component code. Key points:

- Install via npm install mermaid

- Create a reusable component with a diagram string prop

- Use mermaid.render() (async, v10+) instead of the deprecated init()

- Watch the prop to re-render on changes

- Use ClientOnly in SSR/Nuxt environments

- Lazy-load Mermaid for better bundle performance

Want to try Mermaid diagrams without any setup? Use MermaidEditor.lol — a free online editor with live preview, multiple themes, and instant PNG/SVG export.