Mermaid Diagram Configuration Guide
This comprehensive guide covers setup, implementation, and troubleshooting of Mermaid diagrams in Jekyll sites. Mermaid allows you to create diagrams and visualizations using simple text syntax.
Table of Contents
- Overview
- Installation & Setup
- Configuration
- Usage Examples
- Troubleshooting
- Performance Optimization
- References & Credits
Overview
Mermaid is a JavaScript-based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically. It supports:
- Flowcharts
- Sequence diagrams
- Class diagrams
- State diagrams
- Entity relationship diagrams
- User journey diagrams
- Gantt charts
- Pie charts
- Git graphs
- And more…
Why This Implementation?
Our Jekyll site uses a hybrid approach combining:
- jekyll-mermaid plugin for build-time processing
- Runtime JavaScript conversion for fenced code blocks
- CDN delivery for performance and reliability
This ensures compatibility across different content authoring methods while maintaining optimal performance.
Installation & Setup
1. Gemfile Configuration
Add the jekyll-mermaid plugin to your Gemfile:
# In docs/Gemfile
group :jekyll_plugins do
gem 'jekyll-mermaid', '~> 1.0.0'
# ... other plugins
end
2. Jekyll Configuration
Configure Mermaid in your _config.yml:
# Enable mermaid diagrams
mermaid:
src: https://cdn.jsdelivr.net/npm/mermaid@11.9.0/dist/mermaid.min.js
plugins:
- jekyll-mermaid
# ... other plugins
3. Layout Integration
Add Mermaid support to your layouts. For universal support, add to _layouts/default.html:
<!-- Mermaid support: convert fenced code blocks (```mermaid) and initialize -->
<script src="https://cdn.jsdelivr.net/npm/mermaid@11.9.0/dist/mermaid.min.js"></script>
<script>
(function () {
function convertMermaidCodeFences() {
try {
var codeBlocks = document.querySelectorAll("pre > code.language-mermaid, pre > code.mermaid");
codeBlocks.forEach(function (code) {
var pre = code.parentElement;
var container = pre.parentElement;
var div = document.createElement("div");
div.className = "mermaid";
div.textContent = code.textContent; // preserve raw diagram text
container.replaceChild(div, pre);
});
} catch (e) {
console.warn("Mermaid code fence conversion failed:", e);
}
}
function initMermaidNow() {
try {
if (!window.mermaid) return false;
convertMermaidCodeFences();
if (typeof mermaid.initialize === "function") {
mermaid.initialize({ startOnLoad: true });
}
if (typeof mermaid.run === "function") {
mermaid.run({ querySelector: ".mermaid" });
} else if (typeof mermaid.init === "function") {
mermaid.init(undefined, document.querySelectorAll(".mermaid"));
}
return true;
} catch (e) {
console.error("Mermaid initialization error:", e);
return false;
}
}
function whenReady(fn) {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", fn);
} else {
fn();
}
}
whenReady(function () {
if (initMermaidNow()) return;
var attempts = 0;
var timer = setInterval(function () {
attempts++;
if (initMermaidNow() || attempts > 50) {
clearInterval(timer);
}
}, 100);
});
})();
</script>
4. Install Dependencies
cd docs
bundle install
Configuration
Basic Configuration Options
In _config.yml, you can customize Mermaid settings:
mermaid:
src: https://cdn.jsdelivr.net/npm/mermaid@11.9.0/dist/mermaid.min.js
# Optional: Custom configuration
config:
theme: default
startOnLoad: true
flowchart:
htmlLabels: true
curve: basis
sequence:
diagramMarginX: 50
diagramMarginY: 10
actorMargin: 50
width: 150
height: 65
boxMargin: 10
boxTextMargin: 5
noteMargin: 10
messageMargin: 35
Advanced Layout-Specific Configuration
For specialized layouts (e.g., presentation slides), you can create custom configurations:
<!-- In _layouts/delivery-slides.html -->
<script>
mermaid.initialize({
theme: "dark",
startOnLoad: true,
flowchart: {
htmlLabels: true,
curve: "linear",
},
});
</script>
Usage Examples
Method 1: Fenced Code Blocks (Recommended)
This is the preferred method as it’s compatible with most Markdown processors and avoids build-time HTML wrapping issues:
```mermaid
graph TD
A[Start] --> B{Is it?}
B -->|Yes| C[OK]
B -->|No| D[End]
```
Method 2: Jekyll Liquid Tags
Note: This method can cause issues with <p> tag wrapping. Use fenced code blocks when possible.
<script src="https://cdn.jsdelivr.net/npm/mermaid@11.9.0/dist/mermaid.min.js"></script><div class="mermaid">
sequenceDiagram
participant A as Alice
participant B as Bob
A->>B: Hello Bob, how are you?
B-->>A: Great!
</div>
Example Diagram Types
Flowchart
```mermaid
graph LR
A[Square Rect] --> B((Circle))
A --> C(Round Rect)
B --> D{Rhombus}
C --> D
```
Sequence Diagram
```mermaid
sequenceDiagram
participant A as Client
participant B as Server
A->>B: Request
B-->>A: Response
```
Class Diagram
```mermaid
classDiagram
class Animal {
+String name
+int age
+makeSound()
}
class Dog {
+String breed
+bark()
}
Animal <|-- Dog
```
Troubleshooting
Common Issues and Solutions
1. Diagrams Render as Code Blocks
Symptoms: Mermaid syntax appears as plain text in <pre><code> blocks instead of rendered diagrams.
Causes:
- Missing JavaScript initialization
- Script loading after content render
- Incorrect layout configuration
Solutions:
// Check if Mermaid loaded
console.log("Mermaid loaded:", typeof window.mermaid !== "undefined");
// Manually trigger conversion
if (window.mermaid) {
mermaid.run();
}
2. “Syntax Error” Messages in Diagrams
Symptoms: Diagram container shows “Syntax error in graph” or similar error text.
Causes:
- HTML entities in diagram text (e.g.,
>instead of>) - Jekyll Liquid processing interference
- Invalid Mermaid syntax
Solutions:
- Use fenced code blocks instead of Liquid tags
- Verify diagram syntax at Mermaid Live Editor
- Check for HTML entity encoding in source
3. Mixed Content Warnings
Symptoms: Browser console shows mixed content warnings when loading Mermaid from CDN on HTTPS sites.
Solutions:
# In _config.yml - ensure HTTPS CDN URL
mermaid:
src: https://cdn.jsdelivr.net/npm/mermaid@11.9.0/dist/mermaid.min.js
4. Script Loading Race Conditions
Symptoms: Intermittent rendering failures, especially on slower connections.
Solutions:
// Improved initialization with polling
function initMermaidWithRetry() {
var attempts = 0;
var maxAttempts = 50;
function tryInit() {
if (window.mermaid && document.readyState === "complete") {
mermaid.run();
return true;
}
attempts++;
if (attempts < maxAttempts) {
setTimeout(tryInit, 100);
} else {
console.warn("Mermaid initialization timeout");
}
return false;
}
tryInit();
}
Debugging Tools
Browser Console Debugging
// Check Mermaid availability
console.log("Mermaid version:", mermaid?.version);
// List all mermaid elements
console.log("Mermaid elements:", document.querySelectorAll(".mermaid"));
// Test diagram parsing
try {
mermaid.parse("graph TD; A-->B");
console.log("Mermaid syntax valid");
} catch (e) {
console.error("Mermaid syntax error:", e);
}
E2E Testing Validation
Use Playwright tests to ensure reliable rendering:
// Example test validation
test("Mermaid diagram renders correctly", async ({ page }) => {
await page.goto("/docs/mermaid-example/");
// Wait for Mermaid to load and render
await page.waitForSelector(".mermaid svg", { timeout: 8000 });
// Verify no syntax errors
const errorCount = await page.locator('.mermaid:has-text("Syntax error")').count();
expect(errorCount).toBe(0);
// Verify SVG content
const svgCount = await page.locator(".mermaid svg").count();
expect(svgCount).toBeGreaterThan(0);
});
Performance Optimization
CDN Configuration
Use a reliable CDN with proper versioning:
# Recommended CDN sources (choose one)
mermaid:
# jsDelivr (recommended)
src: https://cdn.jsdelivr.net/npm/mermaid@11.9.0/dist/mermaid.min.js
# Alternative: unpkg
# src: https://unpkg.com/mermaid@11.9.0/dist/mermaid.min.js
# Alternative: cdnjs
# src: https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.9.0/mermaid.min.js
Lazy Loading
For pages with many diagrams, consider lazy loading:
// Intersection Observer for lazy loading
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const element = entry.target;
if (!element.dataset.rendered) {
mermaid.render("mermaid-" + Date.now(), element.textContent).then((result) => {
element.innerHTML = result.svg;
element.dataset.rendered = "true";
});
}
}
});
});
document.querySelectorAll(".mermaid").forEach((el) => observer.observe(el));
Bundle Size Optimization
Consider self-hosting for production:
# Download and serve locally
npm install mermaid
cp node_modules/mermaid/dist/mermaid.min.js assets/js/
References & Credits
Internal Documentation
- Mermaid Quick Start: Quick Setup Guide - Rapid setup and basic usage patterns for immediate productivity
- Mermaid Diagrams Sample: Mermaid Diagrams Showcase - Live examples of all supported diagram types
- Mermaid Examples: Comprehensive Mermaid Examples - Extended collection of real-world diagram patterns and use cases
- Quick Start Guide: Getting Started - Rapid setup guide for the complete development environment
- Testing Documentation: See our comprehensive E2E testing setup for Mermaid diagram validation
Official Documentation
- Mermaid Official Documentation: https://mermaid.js.org/
- Mermaid GitHub Repository: https://github.com/mermaid-js/mermaid
- Mermaid Live Editor: https://mermaid.live/
Jekyll Integration
- jekyll-mermaid Plugin: https://github.com/jasonbellamy/jekyll-mermaid
- Jekyll Official Plugins: https://jekyllrb.com/docs/plugins/
CDN Providers
- jsDelivr: https://www.jsdelivr.com/
- unpkg: https://unpkg.com/
- cdnjs: https://cdnjs.com/
Testing & Validation
- Playwright Testing: https://playwright.dev/
- Accessibility Testing: https://github.com/dequelabs/axe-core
- Internal E2E Tests: Our custom Mermaid testing suite validates diagram rendering across all supported browsers
Community Resources
- Mermaid Syntax Guide: https://mermaid.js.org/syntax/flowchart.html
- Jekyll Community: https://talk.jekyllrb.com/
MIJUG .NET Workspace Integration
- Performance Optimization: This implementation follows our workspace’s performance targets (< 12s builds, < 90s test suite)
- Accessibility Standards: WCAG 2.1 AA compliance enforced via automated testing
- Multi-Browser Support: Validated across Chromium, Firefox, and WebKit using our specialized test runner
- Conditional Loading: Optimized script loading only when
use_mermaid: trueis set in page front matter - Development Workflow: Integrated with FrontMatter CMS and Jekyll drafts workflow for streamlined content creation
Contributing
This implementation was developed for the MIJUG .NET workspace and incorporates best practices from:
- Mermaid.js community for syntax and rendering guidance
- Jekyll community for plugin integration patterns
- Playwright team for E2E testing methodologies
- jsDelivr team for CDN reliability recommendations
Version History
- v1.0 (2025-08-08): Initial implementation with hybrid approach
- v1.1 (2025-08-08): Added runtime fenced code block conversion
- v1.2 (2025-08-08): Enhanced error handling and debugging tools
License Acknowledgments
- Mermaid.js: MIT License - Copyright (c) 2014 - 2024 Knut Sveidqvist
- jekyll-mermaid: MIT License - Copyright (c) 2015 Jason Bellamy
- Jekyll: MIT License - Copyright (c) 2008-2015 Tom Preston-Werner
For the most current information, always refer to the official documentation links provided above.
My Info Just Under Glass