Back to main page Traveling Coderman

Custom-themed Mermaid diagrams in Eleventy

Would you like to have custom-themed diagrams like this on your Eleventy blog?

%%{init: {'theme': 'base', 'themeVariables': {"darkMode":true,"background":"#003890","primaryColor":"#0063b1","fontFamily":"Montserrat, sans-serif","fontSize":"1rem","lineColor":"white"} }}%%
graph TD
    A(Add mermaid.js)-->B(Have diagrams)

Directly defining the snipped in the markdown file?

```mermaid-graph
graph TD
A(Add mermaid.js)-->B(Have diagrams)

```

I guide you through the steps to achieve that.

%%{init: {'theme': 'base', 'themeVariables': {"darkMode":true,"background":"#003890","primaryColor":"#0063b1","fontFamily":"Montserrat, sans-serif","fontSize":"1rem","lineColor":"white"} }}%%
flowchart TD
    A(1. Load mermaid.js)
    B(2. Configure markdown highlighter)
    C(3. Add custom theme)
    D(4. Add diagrams)
    A-->B
    B-->C
    C-->D

Load mermaid.js 🔗

Somewhere in a template file in the directory _includes, you define the head element of the page. In my case, this is the Nunjucks file _includes/page.njk.

<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
{% if mermaid %}
<script src="/node_modules/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({ startOnLoad: true, theme: "base" });
</script>
{% endif %}
</head>
<!-- ... -->
</html>

Install the npm package mermaid with npm install --save mermaid. Then you can load the file mermaid.min.js in the script tag.

With the call to mermaid.initialize, you tell mermaid to render all diagrams it can find with the class mermaid. We specify the theme base, as it is the best to customize.

By enclosing the script tags into an if block, we ensure that mermaid is only loaded when the template requests it via defining mermaid as true in the front-matter.

---
layout: page.njk
mermaid: true

---


# My page

Configure markdown highlighter 🔗

There is a post that introduces the idea of adding a markdown highlighter. We add such a highlighter to the eleventy config .eleventy.js.

module.exports = function (eleventyConfig) {
const highlighter = eleventyConfig.markdownHighlighter;
eleventyConfig.addMarkdownHighlighter((str, language) => {
if (language === "mermaid") {
return `<pre class="mermaid">${str}</pre>`;
}
return highlighter(str, language);
});
};

The rendering with mermaid can only happen in the browser due to its dynamic layouting. Hence, the graph code is wrapped in an element with the class mermaid for mermaid to pick it up at runtime.

Add custom theme 🔗

Custom theme variables can be overridden in individual diagrams. However, we don't want to replicate this custom theming in each diagram. Therefore, we prepend it in the markdown highlighter.

module.exports = function (eleventyConfig) {
const highlighter = eleventyConfig.markdownHighlighter;
eleventyConfig.addMarkdownHighlighter((str, language) => {
if (language === "mermaid") {
const themeVariables = JSON.stringify({
darkMode: true,
background: "#044965",
primaryColor: "#05668d",
fontFamily: "Montserrat, sans-serif",
fontSize: "1rem",
lineColor: "white",
});
const init = `%%{init: {'theme': 'base', 'themeVariables': ${themeVariables} }}%%`;
return `<pre class="mermaid">${init + "\n" + str}</pre>`;
}
return highlighter(str, language);
});
};

You can find information about the customization options in the mermaid documentation

Add diagrams 🔗

With these steps setup, you can add diagrams to your posts.

---
layout: page.njk
mermaid: true

---


# My page

```mermaid-graph
graph TD
A(Add mermaid.js)-->B(Have diagrams)

```