This documentation is also published as Markdown for efficient machine reading: the whole site is indexed at /llms.txt, and every page has a clean Markdown copy at the same URL with .md appended. These are generated from the same source and cost far fewer tokens to read than this rendered HTML.

Skip to main content Skip to navigation
Guides

Embed a Mermaid diagram in a markdown page

Author Mermaid diagrams in markdown with a fenced `mermaid` block and let the DocSite render them client-side with theme awareness.

To drop a flowchart, sequence diagram, or other visual into a markdown article without authoring SVG by hand, fence the diagram with mermaid as the language. The DocSite renders the fence body verbatim, then a client script swaps each block for an SVG in the browser. Sites that build offline or behind a firewall must vendor Mermaid themselves — see Vendor the library for offline builds below.

Before you begin

  • An existing Pennington site renders markdown (see Create your first Pennington site if not).
  • The host uses AddDocSite or AddBlogSite, or — on a bare AddPennington host — references Pennington.UI and emits its script bundle from the layout (<script type="module" src="/_content/Pennington.UI/scripts.js" defer></script>).
  • Familiarity with Mermaid syntax — this page covers the fence wiring, not Mermaid itself. See the upstream Mermaid docs for the grammar.

Diagram syntaxes

Pennington does not preprocess the fence body — anything valid in Mermaid renders as-is. The two most common shapes are below.

Flowchart

Fence a block with mermaid as the language and write a flowchart body. The client script swaps the <code> element for an SVG at page load.

markdown
```mermaid
flowchart LR
    A[Markdown file] --> B[MarkdownContentParser]
    B --> C[ContentPipeline]
    C --> D[MarkdownContentRenderer]
    D --> E[Response processors]
    E --> F[Rendered HTML]
```
mermaid
flowchart LR
    A[Markdown file] --> B[MarkdownContentParser]
    B --> C[ContentPipeline]
    C --> D[MarkdownContentRenderer]
    D --> E[Response processors]
    E --> F[Rendered HTML]

Sequence diagram

Sequence diagrams use the same mermaid fence with a sequenceDiagram body.

markdown
```mermaid
sequenceDiagram
    Alice->>Bob: Hello Bob, how are you?
    Bob-->>Alice: I'm good, thanks!
    Alice->>Bob: Want to grab lunch?
    Bob-->>Alice: Sounds great.
```
mermaid
sequenceDiagram
    Alice->>Bob: Hello Bob, how are you?
    Bob-->>Alice: I'm good, thanks!
    Alice->>Bob: Want to grab lunch?
    Bob-->>Alice: Sounds great.

What the renderer emits

Each fence renders as <pre><code class="language-mermaid">…</code></pre> with the body verbatim — Pennington does not transform it server-side. The browser script then loads Mermaid from cdn.jsdelivr.net and replaces each block with an inline SVG. The theme toggle re-renders every diagram with the matching built-in Mermaid theme, so diagrams track light and dark mode. Diagrams render on both the live dev server and the static build output.

For per-diagram theme overrides, use Mermaid's inline %%{init: { 'theme': '…' } }%% directive at the top of the fence body — Mermaid syntax, not Pennington syntax.

Vendor the library for offline builds

The bundled support loads Mermaid from cdn.jsdelivr.net at first render. A site that builds offline or behind a firewall must serve the library itself: vendor the Mermaid module into wwwroot and load it from your own layout. This is the same pattern any CDN-backed widget follows — see Load the library and your script for the vendoring recipe.

Verify

  • Open a page with a diagram in the browser. The fence renders as an SVG, not as a raw code block. A diagram still showing its flowchart/sequenceDiagram text means the script never replaced it.
  • On a failure, open the browser network tab and confirm the import from cdn.jsdelivr.net succeeds. A blocked or 404'd jsdelivr request is the silent-failure signature — Mermaid never loads and the original code block stays in place. Vendor the library to fix it.