Post

Adding Mermaid Diagrams

I just added support for Mermaid diagrams to my site and I’m so pleased with how it turned out! Mermaid is a JavaScript tool for making all sorts of charts and diagrams in code, but having them render beautifully on websites. I’ve been using it to make graphics for slides and documentation. In talking at BSides Boulder about threat modeling last week, I’d made some nice diagrams to use instead of uploaded static images.

GitHub renders these diagrams natively in Markdown1. Pages is a bit of a different beast, though - it builds my website and then deploys the finished site.2 There’s a great Jekyll plugin to do this already called jekyll-mermaid but it doesn’t support theming. Since this website is in dark mode, the diagrams were impossible to read.3 Here’s a screenshot example that may or may not scale well depending on your browser:

default-mode

This seemed like a good opportunity to learn some web things while assembling the website version of the slides.

How

This was simultaneously disappointing and marvelous. First, add the following header for the YAML front matter in _includes/head.html:

1
2
3
{% if page.mermaid %}
    {% include mermaid.html %}
{% endif %}

This will tell browsers to load the rather large JavaScript module only where needed, preserving the speed and simplicity of static websites wherever possible. I’ll indicate this need by setting a front matter key on each post that needs Mermaid diagrams using mermaid: true, same as other page settings like table of contents, tags, post titles, etc.

Then, import the Mermaid module from the NPM CDN with a new file called _includes/mermaid.html with the following contents. I went with this approach to be able to document configuration settings site-wide in one file, as there may be more than just the theme that I’d like to change moving forward.

1
2
3
4
5
6
7
8
9
10
11
12
<script type="module">
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
    let config = { 
        startOnLoad: true,
        theme: "dark", 
        flowchart: { 
            useMaxWidth: true, 
            htmlLabels: true 
        } 
    };
    mermaid.initialize(config);
</script>

This should be reasonably reusable for other JS libraries too, such as MathJax. Define the YAML front matter to toggle loading it in the first file, then import and configure the JavaScript in another.

✨ ✨ Now look this readable diagram! ✨ ✨

flowchart LR
    A(fa:fa-laptop-code Developer) --> B(fab:fa-github GitHub\ncode/issues/etc)
    B --> C(fa:fa-server Build)
    C --> D(fa:fa-server Deploy)
    D --> E(fa:fa-user Environment)

And here’s how it was made in the markdown that defines this post. There’s new line characters and FontAwesome icons too!

1
2
3
4
5
6
7
<div class="mermaid">
flowchart LR
    A(fa:fa-laptop-code Developer) --> B(fab:fa-github GitHub\ncode/issues/etc)
    B --> C(fa:fa-server Build)
    C --> D(fa:fa-server Deploy)
    D --> E(fa:fa-user Environment)
</div>

I’m still working on assembling a much longer post of my slides, talk, and how much fun BSides Boulder was, but for now …

genius


Resources

Footnotes

  1. Include diagrams in markdown 

  2. Example build pipeline here, execution logs here 

  3. Accessibility feedback issue tracking this 

This post is licensed under CC BY 4.0 by the author.