Add Mermaid to Hugo with Dark Mode
Recently, I was revisiting materials in Deep Learning. I need tools that generate diagrams easily. Drawing the graphs from scratch and upload them individually to the image hosting platform is a daunting process. This is when Mermaid comes into rescue. Now I can generate diagrams directly using Markdown. Here’s how to do it inside a Hugo site.
I use the etch theme, but this process should apply to all sites using Hugo. First, we create a new file /layouts/shortcodes/mermaid.html
. We fill up mermaid.html
with:
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
let isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
let mermaidTheme = (isDark) ? 'dark' : 'default';
let mermaidConfig = {
theme: mermaidTheme,
logLevel: 'fatal',
securityLevel: 'strict',
startOnLoad: true,
arrowMarkerAbsolute: false,
er: {
diagramPadding: 20,
layoutDirection: 'TB',
minEntityWidth: 100,
minEntityHeight: 75,
entityPadding: 15,
stroke: 'gray',
fill: 'honeydew',
fontSize: 12,
useMaxWidth: true,
},
flowchart: {
diagramPadding: 8,
htmlLabels: true,
curve: 'basis',
},
sequence: {
diagramMarginX: 50,
diagramMarginY: 10,
actorMargin: 50,
width: 150,
height: 65,
boxMargin: 10,
boxTextMargin: 5,
noteMargin: 10,
messageMargin: 35,
messageAlign: 'center',
mirrorActors: true,
bottomMarginAdj: 1,
useMaxWidth: true,
rightAngles: false,
showSequenceNumbers: false,
},
gantt: {
titleTopMargin: 25,
barHeight: 20,
barGap: 4,
topPadding: 50,
leftPadding: 75,
gridLineStartPadding: 35,
fontSize: 11,
fontFamily: '"Open-Sans", "sans-serif"',
numberSectionStyles: 4,
axisFormat: '%Y-%m-%d',
topAxis: false,
},
};
mermaid.initialize(mermaidConfig);
</script>
This setup allows us to change Mermaid-generated diagrams’ theme based on the website’s current (light/dark) theme. This configuration is borrowed from the Setup.md from mermaid-js (except the theme
part). You can find more information there about configuring mermaid.
You can also do this in /partials
, but it will slow down the loading time because the mermaid js file is always loaded, regardless whether you are actually using mermaid.
Next, we add the follow lines to the file /layouts/shortcodes/mermaid.html
:
<center>
<div class="mermaid">
{{.Inner}}
</div>
</center>
Feel free to remove the <center>
tag if you want to customize the diagram’s layout. And… we are done!
Here is an example sequenceDiagram. You should see that this diagram will adjust its theme accordingly based on light/dark mode. We use the example code from mermaid doc (just uncomment mermaid
in the shortcode {{/*< mermaid >*/}}
):
{{/*< 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!
{{/*< /mermaid >*/}}
prevail! John-->>Alice: Great! John->>Bob: How about you? Bob-->>John: Jolly good!
This diagram will adjust its theme based on light/dark theme. You can find more features from the Mermaid website.