Skip to main content

Jekyll Mermaid Integration Tutorial

Complete tutorial for integrating Mermaid diagrams in Jekyll sites with GitHub Pages support.

Overview

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.

Two Implementation Approaches

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>

Implementation Details

File Structure

_includes/
  └── components/
      └── mermaid.html          # Mermaid configuration
  └── core/
      └── head.html             # Conditional include

_config.yml                     # Plugin configuration

Page Front Matter

For custom implementation, add to your page front matter:

---
title: "My Page"
mermaid: true
---

Diagram Examples

Flowchart

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

Sequence Diagram

<div class="mermaid">
  sequenceDiagram Alice->>John: Hello John, how are you? John-->>Alice: Great!
  Alice-)John: See you later!
</div>

Class Diagram

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

Why Custom Implementation?

GitHub Pages has limitations on Jekyll plugins. While jekyll-mermaid works locally, it may not render diagrams on GitHub Pages due to:

  1. Plugin Restrictions: GitHub Pages only supports specific plugins
  2. Build Process: Different build environment
  3. Security Policies: Limited JavaScript execution

Solution: Hybrid Approach

Our implementation uses both approaches:

  1. Plugin Configuration: For local development and configuration
  2. Custom Include: For GitHub Pages compatibility
  3. Conditional Loading: Only loads when needed

Troubleshooting

Common Issues

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

Testing

  1. Local Testing: Use bundle exec jekyll serve
  2. GitHub Pages: Push to repository and check live site
  3. Validation: Use Mermaid Live Editor

Best Practices

1. Choose the Right Approach

2. Performance Optimization

3. Maintenance

Resources


Next Steps: See the complete Mermaid guide for comprehensive examples and reference.