Main steps
- Create a layout
- Adding Mermaid to a content template
- Maintaining content and theme styles
- Rendering an example diagram
Mermaid diagram
This post outlines how to add Mermaid support with Hugo to render the diagram below, as I found the docs a bit lacking.
When pasting, make sure to move the closing code fence to a new line to see the diagram
```mermaid
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts <br/>prevail!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!```
Creating a layout
While Mermaid markdown diagrams aren’t supported natively by Hugo, it’s easy to add.
As the docs mention the first step is to create layouts/_default/_markup/render-codeblock-mermaid.html
:
<pre class="mermaid">
{{- .Inner | safeHTML }}
</pre>
{{ .Page.Store.Set "hasMermaid" true }}
Adding Mermaid to a content template
The next step is less obvious, while the docs mention to add a code block to a content template it needs a bit of clarification.
A content template template is what Hugo uses to render types of pages: list, single, summary.
- List: the list view of your posts
- Summary: the small section in visible before clicking into a post
- Single: the content of your post
We’ll focus on the ‘single’ as this is where the diagrams will be rendered. So under layouts/_default/
you can create a single.html
file to then add the code snippet to handle the Mermaid diagrams.
{{ if .Page.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 }}
Maintaining content and theme styles
Adding the code above on it’s own will make all your ‘single’ posts 404 as we haven’t told Hugo to render any content because omitted a .Content
block. The reason for this is because of the render order Hugo has. As such, the default behaviour of the template was overridden and we removed the content and styles.
Hugo uses the following lookup order for content views:
/layouts/<TYPE>/<VIEW>.html
/layouts/_default/<VIEW>.html
/themes/<THEME>/layouts/<TYPE>/<VIEW>.html
/themes/<THEME>/layouts/_default/<VIEW>.html
To update and maintain your changes, go to your theme provider’s layout folder copy the layout and then create a new file in your own layouts folder.
I’m using the PaperMod theme and my version would be:
/themes/PaperMod/layouts/single.html
and then copy the entire file to:
/layouts/_default/single.html
Now, we’re able to override the PaperMod theme and subsequent updates won’t change our configuration.
…But we’re still not seeing a Mermaid diagram. To do this, we need to find the .Content
block and add the Mermaid script for Hugo to render diagrams.
In the ‘single’ file, find the .Content
block and update it to use the Mermaid script from the Hugo docs. My layout Content block looks something like this:
{{- if .Content }}
<div class="post-content">
{{- if not (.Param "disableAnchoredHeadings") }}
{{- partial "anchored_headings.html" .Content -}}
{{- else }}{{ .Content }}{{ end }}
</div>
{{ if .Page.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 }}
Notice that the script is inside the if .Content
block.
Rendering an example diagram
If you now run hugo new posts/diagrams.md
to create a new post, add the example Mermaid diagram at the top and execute hugo server -D
(‘D’ to render drafts), it should now render.
FYI, if you don’t have a posts
directory, just switch it to wherever you keep your .md
files.
The diagram:
sequenceDiagram participant Alice participant Bob Alice->>John: Hello John, how are you? loop Healthcheck John->>John: Fight against hypochondria end Note right of John: Rational thoughts
prevail! John-->>Alice: Great! John->>Bob: How about you? Bob-->>John: Jolly good!
Links