Rendering Mermaid Graphs in Hugo Blog

Rendering Mermaid Graphs in Hugo Blog

March 6, 2025

Currently, my tech blog uses a template engine called Hugo. Hugo is a static site generator that converts Markdown files into HTML.

In Markdown, which we commonly use, there is a feature called code block.

The Go code below is nicely highlighted syntax-wise:

func main() {
	fmt.Println("Hello, World!")
}

Java code is likewise displayed with syntax highlighting through a code block:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
}

In fact, code blocks are quite a common feature, and most Markdown processors support it, but sometimes there is a need to draw diagrams.

In such cases, the commonly used tools include traditional favorites like draw.io and tools that give a hand-drawn feel, such as excalidraw.

I personally enjoy the hand-drawn feel, so I tend to use excalidraw a lot.

For developers who are used to coding, there are many tools that allow you to create diagrams based on code, such as Mermaid, graphviz, and D2.

Among these, the most popular tool is arguably Mermaid. Mermaid is a tool that allows you to draw diagrams using its unique syntax.

For example, using the syntax below:

graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;

You can create a graph like this:

A

B

C

D

The theme applied to my blog, called Hextra, natively supports Mermaid. However, not all blog themes support Mermaid.

Therefore, in this instance, I want to explore how to enable Mermaid on any Hugo blog.

Adding Code Block Rendering for Layouts

First, we need to add code to render Mermaid code blocks in layouts.

layouts/_default/_markup/render-codeblock-mermaid.html
<pre class="mermaid">
  {{ .Inner | htmlEscape | safeHTML }}
</pre>
{{ .Page.Store.Set "hasMermaid" true }}

This file just needs to be added according to the path.

Adding Mermaid Script to baseof.html

Typically, Hugo has the layouts/_default/baseof.html file. This HTML is applied universally to all pages in Hugo.

So, before the closing of the body tag in the existing baseof.html, add the following code:

layouts/_default/baseof.html
<!-- ... -->
{{ if .Store.Get "hasMermaid" }}
  <script type="module">
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
    mermaid.initialize({ startOnLoad: true });
  </script>
{{ end }}
</body>

Usage

Now, by adding a class of mermaid to the Markdown code block that you want to use, that code block will be rendered using Mermaid.

```mermaid
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```

A

B

C

D

Reference