Rendering Mermaid Diagrams on a Hugo Website Using Quarto

We all deserve to draw fancy-looking diagrams without suffering severe emotional trauma.

Mermaid
Hugo
Quarto
Markdown
Author

Paul Johnson

Published

September 17, 2022

Modified

February 19, 2024

Note

Having ported my site over to Quarto in entirety, this blog post no longer applies to the site as is. There are some inconsistencies with some of the issues it talks about and how the site looks now (for example, there is no longer an option to toggle a dark theme), but the advice in this post should hopefully still work for anyone that is using Quarto with Hugo!

I find a lot of the methods for drawing diagrams and flow charts using code to be a bit of a nightmare. I’m not sure what it is, perhaps I’m just a bit stupid, but they always seem a little more convoluted than I can handle. It’s possible that the design is actually of some value when it comes to drawing diagrams that are much larger and more complicated than I am generally dealing with, but in my case, it always seems to be a lot of work for what little I’m trying to do.

The easiest, most intuitive way that I’ve come across is using a JavaScript library called Mermaid. It’s just very easy, and the diagrams look great. Even better is the fact that it works with a lot of Markdown formats, and it’s even one of the diagram formats that Quarto can handle.

One issue that I came across, however, is that Mermaid diagrams don’t render when you’re using Quarto to create Hugo Markdown files for a Hugo website. You do have some simple options to resolve this, such as setting the mermaid-format to PNG or SVG in the article front matter, but with just a little extra work, you can get Mermaid working perfectly on your Hugo website.

Setting up Hugo to Support Mermaid

Steps for setting up Hugo to support Mermaid are detailed in the Hugo documentation, however that didn’t seem to work for me (producing errors when Netlify tries to publish the site). Instead, I had to take a slightly different approach, which was inspired by Kevin Wu’s blog post about using Mermaid with Hugo. This should work for others, but if it doesn’t, please lets just assume that it is either Kevin’s fault, or your fault, but definitely not my fault.

First, create a HTML file /layours/partials/mermaid.html, and add the following code, which specifies where to find Mermaid and how it should be loaded (in this case I’ve specified the dark theme, but there’s a few different options):

<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true, theme:"neutral" });</script>

Following this, a snippet needs to be added to one of the partial layouts that will be used in your content pages. I added it to the extend_head.html file (which, as the name helpfully suggests, is just an extension of head.html). This snippet just tells Hugo that, when Mermaid is called in the frontmatter, it needs to use the mermaid.html partial you just created.

{{ if .Page.Params.mermaid }}
{{ partial "mermaid.html" . }}
{{ end }}

This can either be added to the existing theme partial, located in themes/<theme-name>/layouts/partials, or it can be in the global layouts/partials directory, which will override your theme.

Now, you just have to add mermaid: true to the YAML frontmatter for any page that contains a Mermaid code block, and you’re good to go!

Rendering Mermaid Using Quarto

Once you’ve set Hugo up to handle Mermaid code blocks, you would think it should then render like other code chunks in Quarto, and you would be right. Mermaid is very good.

I find that I sometimes have to render the Quarto document a couple times for Mermaid diagrams to show up, or for changes to render properly, but that’s about the only issue that I’ve come up against.

Flowcharts

The diagram I will get the most use out of is flowcharts, and Mermaid makes them really easy.

```{mermaid}
%%| label: fig-mermaid-flowchart
%%| fig-cap: Wow look how it flows.
%%| fig-alt: An example flowchart, drawn using Mermaid.

graph LR
    A([Oooh]) --> B([Would You])
    B --> C([Look at This])
    C --> D[Very]
    C --> E[Fancy]
    C --> F[Flowchart]
```
graph LR
    A([Oooh]) --> B([Would You])
    B --> C([Look at This])
    C --> D[Very]
    C --> E[Fancy]
    C --> F[Flowchart]
Figure 1: Wow look how it flows.

Gantt Charts

If Figure 1 isn’t enough to convince you, how about some Gantt charts?

```{mermaid}
%%| label: fig-mermaid-gantt
%%| fig-cap: Oh you real fancy huh?
%%| fig-alt: An example Gantt chart, drawn using Mermaid.

%%{init: {'theme': 'default', 'themeVariables': { 'textColor': '#798189'}}}%%
gantt
    title Big Ol' Gantts
    dateFormat  YYYY-MM-DD
    section Section
    Some Normal Tasks : done, a1, 2022-09-01, 15d
    But Wait, There's More! :after a1, 20d
    section And ANOTHER
    Deary Me, It's Never Ending : crit, 2022-10-01, 20d
    I Hate This Project : 14d
```
%%{init: {'theme': 'default', 'themeVariables': { 'textColor': '#798189'}}}%%
gantt
    title Big Ol' Gantts
    dateFormat  YYYY-MM-DD
    section Section
    Some Normal Tasks : done, a1, 2022-09-01, 15d
    But Wait, There's More! :after a1, 20d
    section And ANOTHER
    Deary Me, It's Never Ending : crit, 2022-10-01, 20d
    I Hate This Project : 14d
Figure 2: Oh you real fancy huh?

The dark and light theme my Hugo site uses doesn’t handle the Gantt chart as well as the other Mermaid diagrams. If I use the neutral Mermaid theme, it doesn’t show as clearly when using the dark Hugo theme, and vice versa with the dark Mermaid theme and light Hugo theme. This isn’t ideal, but you can customise the appearance of your Mermaid diagrams too.

I’ve stuck with the neutral Mermaid theme for the rest of the site because it seems to be the best fit for flowcharts with the two different Hugo themes, and flowcharts are the diagrams I’m going to be using Mermaid for most often on this site. However, for Figure 2 I’ve customised the appearance a little, using %%init%%, specifying the default theme and a grey text colour that works slightly better (though it’s still not brilliant).

Git Graphs

So you’ve got Figure 1 to wow people with your idea and Figure 2 to manage the project, but now you need some git graphs to show how you broke everything.

```{mermaid}
%%| label: fig-mermaid-git
%%| fig-cap: Git a load of this!
%%| fig-alt: An example Git graph, drawn using Mermaid.

gitGraph
  commit
  commit
  branch develop
  checkout develop
  commit
  commit
  checkout main
  merge develop
  commit
  commit
```
gitGraph
  commit
  commit
  branch develop
  checkout develop
  commit
  commit
  checkout main
  merge develop
  commit
  commit
Figure 3: Git a load of this!

Summary

And that’s about all you need to do. Think of all the amazing diagrams you’re going to create and show the world? I, on the other hand, am going to continue to make minimal diagrams that are completely uninspiring. Have fun!

Acknowledgments

Preview image by Daniella Garcia on Unsplash.

Support

If you enjoyed this blog post and would like to support my work, you can buy me a coffee or a beer or give me a tip as a thank you.

Reuse

Citation

For attribution, please cite this work as:
Johnson, Paul. 2022. “Rendering Mermaid Diagrams on a Hugo Website Using Quarto.” September 17, 2022. https://paulrjohnson.net/blog/2022-09-17-rendering-mermaid-diagrams-using-quarto-and-hugo/.