(Updated: )
/ #meta #jamstack #hugo 

Add Diagrams to your Jekyll/Hugo/Gatsby blog with Mermaid JS

Add diagrams to your JAMStack (Jekyll/Hugo/Gatsby) blog with Mermaid JS

Update 17th January 2024: Hugo now has native hooks for diagrams, so that code-fences using ```mermaid [content]``` can have a custom template, see the Content Management > Diagrams > Mermaid diagrams docs.

The following post will go through how to integrate Mermaid JS, a “simple markdown-like language for generating charts”.

It will initially go through the benefits of MermaidJS, followed by a generic (cross-technology) integration, finally it will tackle the Hugo-way of dealing with this issue.

Table of Contents

Why MermaidJS?

Mermaid is a “a simple markdown-like script[ing] language for generating charts from text via javascript”, it fits very well within a text-driven workflow on top of the JAMStack.

This is because Markdown is one of the top options of the M (Markdown) component of JAMStack, so it makes sense to add a “markdown-like” language to create diagrams within your Hugo/Gatsby/Hexo/Jekyll posts.

Mermaid allows you to defined charts using text like the following:

graph LR;
  A-->B;

Which looks like the following (see it here if you have JS disabled):

graph LR; A-->B;

The simplest/most generic MermaidJS integration

No Hugo required, this approach will work for any site where you can edit the posts as HTML/Markdown (where HTML div-s are allowed) and you can add <script> tags

This is the simplest integration:

<div class="mermaid">graph LR; A-->B;</div>
<script
  async
  src="https://unpkg.com/[email protected]/dist/mermaid.min.js"
></script>

Feel free to include the script tag anywhere on the page, it’s marked as async so should not render blocking regardless. For more information about async, see the script tag MDN documentation

We’re leveraging unpkg.com, “a fast, global content delivery network for everything on npm”.

Unfortunately for users of Hugo, this breaks out of the Hugo paradigm since it just injects HTML into pages.

Integrating MermaidJS as a Hugo shortcode

Out of date Notice

As of Hugo 0.93, there are now native hooks for diagrams, so that code-fences using ```mermaid [content]``` can have a custom template, see the Content Management > Diagrams > Mermaid diagrams docs.

By applying that guide to codewithhugo.com, the following fenced code block

```mermaid
  flowchart-elk LR
    A-->B
```

Displays as a mermaid diagram.

  flowchart-elk LR
    A-->B

What is a Hugo shortcode?

Often, content authors are forced to add raw HTML (e.g., video <iframes>) to Markdown content. We think this contradicts the beautiful simplicity of Markdown’s syntax.

Hugo created shortcodes to circumvent these limitations.

A shortcode is a simple snippet inside a content file that Hugo will render using a predefined template. Note that shortcodes will not work in template files.

Hugo Shortcodes documentation - What a Shortcode is

In other words: shortcodes are ways to abstract functionality that you would interact with in your content (Markdown) files.

Usage example would be with the tweet built-in shortcode example from the Hugo docs:

{{< tweet user="SanDiegoZoo" id="1453110110599868418" >}}

Which renders as:

Shortcodes with a body using .Inner

Add the following shortcode to layouts/shortcodes/mermaid.html:

<div class="mermaid">{{.Inner}}</div>

By using .Inner, our shortcode can be used as follows:

{{<mermaid>}}
graph TD;
  A-->B;
  A-->C;
  B-->D;
  C-->D;
{{</mermaid>}}

Which is handier than the alternative which is passing parameters into the shortcode in a way akin to React/Vue/Angular props or HTML attributes (see the tweet example earlier in the post).

Loading the MermaidJS script only on pages that need it

Add the following conditionals around the script:

{{ if (.Params.mermaid) }}
<!-- MermaidJS support -->
<script
  async
  src="https://unpkg.com/[email protected]/dist/mermaid.min.js"
></script>
{{ end }}

This is will make sure that mermaid.min.js does not get loaded unless the post specifically says that it needs it.

In your post (or other) frontmatter:

mermaid: true

In your post content you can now write Mermaid diagrams:

{{<mermaid>}}
graph TD;
  A-->B;
  A-->C;
  B-->D;
  C-->D;
{{</mermaid>}}

Make sure to switch on mermaid: true otherwise you’ll just see the following text

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

See the diagram in action:

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

If you have JS disabled you’ll just see text but you can see a picture of the diagram in action.

That’s it, MermaidJS, why it’s cool, how easy it is to integrate and how to do so as a Hugo shortcode.

unsplash-logoZbysiu Rodak

Author

Hugo Di Francesco

Co-author of "Professional JavaScript", "Front-End Development Projects with Vue.js" with Packt, "The Jest Handbook" (self-published). Hugo runs the Code with Hugo website helping over 100,000 developers every month and holds an MEng in Mathematical Computation from University College London (UCL). He has used JavaScript extensively to create scalable and performant platforms at companies such as Canon, Elsevier and (currently) Eurostar.

Get The Jest Handbook (100 pages)

Take your JavaScript testing to the next level by learning the ins and outs of Jest, the top JavaScript testing library.