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 mermaidMermaid 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 stateTry 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
computedorshallowRef. - Lazy-load Mermaid — use dynamic import (
import('mermaid')) insideonMountedto keep initial bundle size down. - One
mermaid.initializecall — 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.