Correct way to embed Mermaid.JS

I found 4 tutorials that all embed Mermaid differently:

This says: Add Diagrams to your Jekyll/Hugo/Gatsby blog with Mermaid JS · Code with Hugo

Add this code to layouts/shortcodes/mermaid.html:

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

and add this to unknown location:

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

This says: On The Other Hand · Integrating Mermaid JS Into Hugo

Add to layouts/shortcodes/mermaid.html:

{{ if ($.Page.Params.mermaid) }}
<script src="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>!window.mermaid && document.write(unescape('%3Cscript src="/js/mermaid-8.9.1/mermaid.min.js"%3E%3C/script%3E'))</script>
<script>mermaid.initialize({startOnLoad:true});</script>
{{ end }}
<div class="mermaid">
  {{.Inner}}
</div>

This says: skeptric - Diagrams in Hugo with Mermaid

Add to layouts/shortcodes/mermaid.html

{{ $_hugo_config := `{ "version": 1 }` }}
<div class="mermaid" align="{{ if .Get "align" }}{{ .Get "align" }}{{ else }}center{{ end }}">{{ safeHTML .Inner }}</div>

and in layouts/partials/site-header.html:

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

And this says: Build and display Mermaid.js diagrams in Hugo

Add to layouts/shortcodes/mermaid.html:

<script async type="application/javascript" src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js">
  var config = {
    startOnLoad:true,
    theme:'{{ if .Get "theme" }}{{ .Get "theme" }}{{ else }}dark{{ end }}',
    align:'{{ if .Get "align" }}{{ .Get "align" }}{{ else }}center{{ end }}'
  };
  mermaid.initialize(config);
</script>

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

What is the RIGHT way?

I doubt there is a right way, your mileage may vary.

Personally, I find the most elegant way to display mermaid diagrams is to make use of a code block render hook. This is how it is done in the docsy theme:

Please note that Mermaid is at version 10.0.2 now, which is ESM only. If you want to use the latest version of mermaid, you have to import mermaid as module.

1 Like

I agree with @deining.

This is simple:
https://gohugo.io/content-management/diagrams/#mermaid-diagrams

GitHub uses the same approach—a fenced code block in markdown.

Would this make the script load all the time?

The 1 benefit of the short-code is that it only loads on certain pages that use it (or so it says).

The example in docs that I linked to:

{{ if .Page.Store.Get "hasMermaid" }}

If only loads JS for a page with a mermaid code block.

1 Like

@jmooring Where is .Page.Store documented? Nothing comes up in search, nothing listed on the page variables page. Is that supposed to be .Scratch?

Have a look here:

That’s true, this variable should be added, indeed.

1 Like

It seems the Algolia search takes some time to update. I looked up hasSuffix a few days ago after it was added in the last release and it was missing in the search. But now it is showing up.

Done with this commit.

1 Like

I tried the code-fence style as the docs say, but it just won’t render and remains blank.

What I did:

  1. Created render-codeblock-mermaid.html in the correct dir with this content:
<div class="mermaid">
  {{- .Inner | safeHTML }}
</div>
{{ .Page.Store.Set "hasMermaid" true }}
  1. Modified my content file single.html in layouts/_default/ with:
{{ define "main" }}
<h1>{{ .Title }}</h1>

{{ if ne .Params.Type "page" }}
  {{ partial "metadata.html" . }}
{{ end }}

{{ .Content }}

{{ 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 }}

{{ if .Params.categories }}

  <p><strong>Related categories:</strong></p>

  <ul>

  {{ with .Params.categories }}
  {{ range . }}
  {{ $href := print (absURL "categories/") (urlize .) }}
  <li><a href="{{ $href }}">{{ . }}</a></li>
  {{ end }}
  {{ end }}

  </ul>

{{ end }}

{{ if .Params.tags }}

  <p><strong>Related tags:</strong></p>

  <ul>

  {{ with .Params.tags }}
  {{ range . }}
  {{ $href := print (absURL "tags/") (urlize .) }}
  <li><a href="{{ $href }}">{{ . }}</a></li>
  {{ end }}
  {{ end }}

  </ul>

{{ end }}

{{ end }}
  1. Result = a blank white area where the diagram should be.

In the end only the short-code method is working, based on this:

What is “the correct dir?”

And Hugo version?

This works fine:

git clone --single-branch -b hugo-forum-topic-43491 https://github.com/jmooring/hugo-testing hugo-forum-topic-43491
cd hugo-forum-topic-43491
hugo server

/layouts/_default/_markup/

hugo v0.110.0+extended linux/amd64

I’m not sure why it isn’t working for you. The best I can suggest is to clone and build the example in my previous comment.

Yours works.

The issue seems to be in my theme: GitHub - leonstafford/accessible-minimalism-hugo-theme: Minimalist Hugo theme with a penchant for accessibility

I also try to set Hugo to verbose, but get no errors.

Nor does the browser console give errors.

Nor is it a browser issue cause your sample rendered but mine doesn’t.

How can I debug correctly to get the right errors?

I use: hugo server -v --disableFastRender -D

No, the theme works fine with the test site from my previous post.

If you want help, you need to share your project.

Can you share with me the updated branch with the theme?

I will set up the repo for you tomorrow.

git clone --single-branch -b hugo-forum-topic-43491 https://github.com/jmooring/hugo-testing hugo-forum-topic-43491
cd hugo-forum-topic-43491
git submodule update --init
hugo server

Then visit http://localhost:1313/tests/mermaid-test/

1 Like

It appears to be some caching, as it is now working.

Thank you for your help to jmooring & everyone else.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.