Skip to content

Mermaid Diagrams

The builder supports Mermaid diagrams with two-phase processing: a remark plugin at build time prepares the markup, and a client-side renderer produces the SVG.

The remark-mermaid plugin (provided by the docs-theme npm package) runs during the Astro build. It uses unist-util-visit to find fenced code blocks with lang === 'mermaid' and replaces them with HTML:

visit(tree, 'code', (node, index, parent) => {
if (node.lang !== 'mermaid' || index === undefined || !parent) return;
const escaped = node.value
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
parent.children[index] = {
type: 'html',
value: `<div class="mermaid-container" data-mermaid-src="${escaped}">
<pre class="mermaid">${node.value}</pre>
</div>`,
};
});

Key details:

AspectValue
Node type matchedcode nodes where lang === 'mermaid'
HTML entity escaping&, <, >, " — prevents attribute injection in data-mermaid-src
Output structure<div class="mermaid-container"> with data-mermaid-src attribute holding the escaped source
Fallback content<pre class="mermaid"> with the raw source (visible until JS renders)

The renderMermaidDiagrams() function in src/scripts/placeholder-dom.ts handles SVG generation in the browser.

Mermaid is loaded on demand from a CDN — it is not bundled:

const mermaid = (await import('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs')).default;
mermaid.initialize({
startOnLoad: false,
theme: 'default',
securityLevel: 'loose',
themeVariables: {
primaryColor: '#ffffff',
primaryBorderColor: '#cccccc',
background: '#ffffff',
mainBkg: '#ffffff',
secondBkg: '#ffffff',
tertiaryColor: '#ffffff',
},
});

startOnLoad: false prevents Mermaid from auto-scanning the page. securityLevel: 'loose' allows click events and links in diagrams.

For each .mermaid-container element:

  1. Read the raw diagram source from data-mermaid-src
  2. Run placeholder substitution on the source (see below)
  3. Clear the container and remove any data-processed attribute
  4. Call mermaid.render() with a random ID to produce SVG
  5. Set backgroundColor: 'white' on the rendered <svg> element

Before rendering, the diagram source passes through the same substituteText() function used by the DOM walker (see Placeholder System for the walker mechanism):

const template = container.getAttribute('data-mermaid-src') || '';
const substituted = substituteText(template, values);

This means placeholder tokens like xCUSTOMER_ASNx work inside Mermaid diagram definitions. When a user changes a value in the form, the placeholder-change event triggers a full re-render of all diagrams with updated values.

If mermaid.render() throws (for example, due to a syntax error in the diagram source), the catch block displays the error directly in the container:

} catch (e) {
container.textContent = `Diagram error: ${e}`;
}

This makes authoring errors visible without breaking the rest of the page.

Diagrams re-render in two situations:

TriggerEventWhat happens
Placeholder value changesplaceholder-changehandleChange() calls renderMermaidDiagrams() with new values
Astro page navigationastro:page-loadinit() calls renderMermaidDiagrams() for the new page

Write a standard fenced code block with the mermaid language tag:

```mermaid
flowchart LR
A[Customer ASN: xCUSTOMER_ASNx] --> B[F5 XC ASN: xF5_XC_ASNx]
```

The remark plugin converts this to a container div at build time. The client renders it as an SVG with placeholder values substituted.