layouts: render ```mermaid code blocks as diagrams

Adds a Hugo codeblock render hook that turns ```mermaid fences into
<pre class="mermaid"> containers, plus a lazily-loaded mermaid bundle
that only ships on pages that actually contain a diagram. Mirrors the
existing YouTube embed pattern (Store flag + conditional script tag in
baseof) so the main scripts.js bundle stays unchanged.
This commit is contained in:
David Karlsson
2026-05-27 11:08:46 +02:00
parent a0a179c056
commit 9789556384
6 changed files with 990 additions and 2 deletions
+19
View File
@@ -0,0 +1,19 @@
import mermaid from 'mermaid'
const isDark = () => document.documentElement.classList.contains('dark')
mermaid.initialize({
startOnLoad: false,
securityLevel: 'strict',
theme: isDark() ? 'dark' : 'default',
})
const render = () => {
mermaid.run({ querySelector: 'pre.mermaid' })
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', render)
} else {
render()
}
@@ -0,0 +1,5 @@
{{- .Page.Store.Set "mermaid" true -}}
<pre
class="mermaid not-prose my-4 flex justify-center bg-transparent"
data-pagefind-ignore
>{{- .Inner -}}</pre>
+4
View File
@@ -0,0 +1,4 @@
{{ $mermaid := resources.Get "js/mermaid.js"
| js.Build (dict "minify" true "targetPath" "mermaid.js")
}}
<script defer src="{{ $mermaid.Permalink }}"></script>
+4
View File
@@ -95,5 +95,9 @@
{{ with .Store.Get "youtube" }}
{{ partialCached "youtube-script.html" "-" "-" }}
{{ end }}
{{/* Load mermaid if the page contains a mermaid code block */}}
{{ with .Store.Get "mermaid" }}
{{ partialCached "mermaid-script.html" "-" "-" }}
{{ end }}
</body>
</html>
+957 -2
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -25,6 +25,7 @@
"heroicons": "2.2.0",
"highlight.js": "11.11.1",
"marked": "17.0.4",
"mermaid": "11.15.0",
"tailwindcss": "4.2.1"
},
"devDependencies": {