Complete tutorial for integrating Mermaid diagrams in Jekyll sites with GitHub Pages support.
This tutorial covers the complete integration of Mermaid diagrams in Jekyll sites, including both the jekyll-mermaid plugin approach and custom implementation for GitHub Pages compatibility.
Best for: Local development, when you control the Jekyll build process.
Configuration:
# _config.yml
plugins:
- jekyll-mermaid
mermaid:
src: "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"
Usage:
```mermaid
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[Success]
B -->|No| D[Try Again]
```
### 2. Custom Implementation (GitHub Pages Compatible)
**Best for:** GitHub Pages, when you need full control over the implementation.
**Configuration:**
```yaml
# _config.yml
plugins:
- jekyll-mermaid # Still needed for configuration
mermaid:
src: 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js'
Include File: _includes/components/mermaid.html
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
mermaid.initialize({
startOnLoad: true,
theme: "forest",
});
});
</script>
Head Include: _includes/core/head.html
<!--
===================================================================
MERMAID DIAGRAM INTEGRATION (v2.1 - GitHub Pages Compatible)
===================================================================
File: mermaid.html
Path: _includes/components/mermaid.html
Purpose: Load and initialize Mermaid.js for diagram rendering
Usage (Two syntaxes supported):
1. Native Markdown Code Blocks (Recommended):
```mermaid
graph TD
A[Start] -> B[End]
```
2. HTML Div Syntax:
<div class="mermaid">
graph TD
A[Start] -- > B[End]
</div>
Requirements:
- Set 'mermaid: true' in page front matter
- Supports all Mermaid diagram types (flowcharts, sequence, gantt, etc.)
Configuration:
- Mermaid v10 via CDN (latest stable)
- Forest theme for dark mode compatibility
- Client-side code block conversion for GitHub Pages compatibility
GitHub Pages Compatibility:
- No custom plugins required (jekyll-mermaid is optional)
- All processing done client-side via JavaScript
- Works with remote_theme on GitHub Pages
Documentation:
- https://mermaid.js.org/
- https://github.com/mermaid-js/mermaid
===================================================================
-->
<!-- Load Mermaid.js from CDN (latest stable version) -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
<!-- Initialize Mermaid with custom configuration -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// ============================================================
// Step 1: Convert native markdown code blocks to mermaid divs
// This enables ```mermaid syntax to work with GitHub Pages
// ============================================================
// Find all code blocks with language-mermaid class (from ```mermaid)
var codeBlocks = document.querySelectorAll('pre > code.language-mermaid, code.language-mermaid');
codeBlocks.forEach(function(codeBlock) {
// Get the mermaid content (decode HTML entities)
var content = codeBlock.textContent || codeBlock.innerText;
// Create a new mermaid div
var mermaidDiv = document.createElement('div');
mermaidDiv.className = 'mermaid';
mermaidDiv.textContent = content;
// Replace the pre/code block with the mermaid div
var preElement = codeBlock.closest('pre');
if (preElement && preElement.parentNode) {
preElement.parentNode.replaceChild(mermaidDiv, preElement);
} else if (codeBlock.parentNode) {
codeBlock.parentNode.replaceChild(mermaidDiv, codeBlock);
}
});
// Also handle pre elements that might have data-language="mermaid"
var preBlocks = document.querySelectorAll('pre[data-language="mermaid"]');
preBlocks.forEach(function(preBlock) {
var content = preBlock.textContent || preBlock.innerText;
var mermaidDiv = document.createElement('div');
mermaidDiv.className = 'mermaid';
mermaidDiv.textContent = content;
if (preBlock.parentNode) {
preBlock.parentNode.replaceChild(mermaidDiv, preBlock);
}
});
// ============================================================
// Step 2: Initialize Mermaid with custom configuration
// ============================================================
mermaid.initialize({
startOnLoad: false, // We'll manually run after conversion
theme: 'forest', // Options: default, forest, dark, neutral, base
themeVariables: {
primaryColor: '#007bff',
primaryTextColor: '#fff',
primaryBorderColor: '#0056b3',
lineColor: '#6c757d',
secondaryColor: '#6c757d',
tertiaryColor: '#f8f9fa'
},
flowchart: {
useMaxWidth: true,
htmlLabels: true,
curve: 'basis'
},
sequence: {
diagramMarginX: 50,
diagramMarginY: 10,
actorMargin: 50,
width: 150,
height: 65,
boxMargin: 10,
boxTextMargin: 5,
noteMargin: 10,
messageMargin: 35,
mirrorActors: true,
bottomMarginAdj: 1,
useMaxWidth: true
},
gantt: {
titleTopMargin: 25,
barHeight: 20,
barGap: 4,
topPadding: 50,
leftPadding: 75,
gridLineStartPadding: 35,
fontSize: 11,
numberSectionStyles: 4,
axisFormat: '%Y-%m-%d'
},
securityLevel: 'loose' // Required for some advanced features
});
// ============================================================
// Step 3: Render all mermaid diagrams
// ============================================================
// Run mermaid to render all .mermaid divs
mermaid.run().then(function() {
console.log('Mermaid.js: All diagrams rendered successfully');
}).catch(function(error) {
console.warn('Mermaid.js: Some diagrams failed to render', error);
});
});
</script>
<!-- FontAwesome for Mermaid icon support (optional) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" crossorigin="anonymous">
<!-- Custom CSS for Mermaid diagrams -->
<style>
/* Mermaid container styling */
.mermaid {
text-align: center;
margin: 2rem auto;
background-color: transparent;
overflow-x: auto;
}
/* Ensure diagrams are responsive */
.mermaid svg {
max-width: 100%;
height: auto;
}
/* Hide code blocks before conversion (prevent flash of unstyled content) */
pre > code.language-mermaid,
code.language-mermaid {
display: block;
opacity: 0;
transition: opacity 0.2s;
}
/* Dark mode compatibility */
@media (prefers-color-scheme: dark) {
.mermaid {
filter: brightness(0.9);
}
}
/* Print styles */
@media print {
.mermaid svg {
max-width: 100% !important;
page-break-inside: avoid;
}
}
</style>
Usage:
<div class="mermaid">
graph TD A[Start] --> B{Decision} B -->|Yes| C[Success] B -->|No| D[Try Again]
</div>
_includes/
└── components/
└── mermaid.html # Mermaid configuration
└── core/
└── head.html # Conditional include
_config.yml # Plugin configuration
For custom implementation, add to your page front matter:
---
title: "My Page"
mermaid: true
---
<div class="mermaid">
graph TD A[Christmas] -->|Get money| B(Go shopping) B --> C{Let me think} C
-->|One| D[Laptop] C -->|Two| E[iPhone] C -->|Three| F[Car]
</div>
<div class="mermaid">
sequenceDiagram Alice->>John: Hello John, how are you? John-->>Alice: Great!
Alice-)John: See you later!
</div>
<div class="mermaid">
classDiagram Animal <|-- Duck Animal <|-- Fish Animal : +int age Animal :
+String gender Animal: +isMammal() class Duck{ +String beakColor +swim()
+quack() }
</div>
GitHub Pages has limitations on Jekyll plugins. While jekyll-mermaid works locally, it may not render diagrams on GitHub Pages due to:
Our implementation uses both approaches:
| Issue | Solution |
|---|---|
| Diagrams not rendering | Check mermaid: true in front matter |
| Plugin not working | Verify jekyll-mermaid is in plugins list |
| GitHub Pages issues | Use custom implementation with <div class="mermaid"> |
| Styling problems | Check theme configuration in mermaid.html |
bundle exec jekyll servepage.mermaidNext Steps: See the complete Mermaid guide for comprehensive examples and reference.