Integrating Mermaid Diagrams with Astro

4 min read, Sun, 16 Mar 2025

Astro is a web framework based on Vite, a tool for building great websites and documentation pages. A well crafted ecosystem of Astro allows integrating different plugins to extend its basic functionality.

Mermaid is a JavaScript diagramming and charting library that can dynamically create diagrams based on the text instructions provided. It gets very well integrated with Markdown and is an excellent source for creating well-defined diagrams as code. For example, please have a look at the mermaid’s simplistic flowchart definition and its output:

```mermaid
 flowchart LR
 A[Start] --> B[Stop]
```
flowchart LR
 A[Start] --> B[Stop]

How lovely it is! This is just an example. One can generate very complex diagrams like sequence diagrams, User Journey, UML etc.

Overview

Today, in this document we will discuss how can we easily integrate Mermaid diagrams into Astro.

Although there are many other online articles on this topic I found those a bit complex. In this article, I will discuss a very easy method to add support for Mermaid to Astro in Markdown texts.

Installing Mermaid using NPM

We will assume that Astro is already installed. Let’s begin by installing the Mermaid first.

npm install mermaid

Handling Syntax Highlighting for Mermaid

Next, if you have configured syntax highlighting in your astro.config.mjs for Markdown content, we need to stop syntax highlighter plugin to stop processing Mermaid code blocks in your Markdown content.

excludeLangs is an configuration option in Astro that take an array of laugages that we want Astro to not process if it encounter it in Markdown content.

export default defineConfig({
 ...
    markdown: {
        shikiConfig: {
            theme: "github-dark",
 },
        syntaxHighlight: {
            type: "shiki",
            excludeLangs: ["mermaid"],
 },
 },
 ...
});

Have a look at the line which adds excludeLangs.

Inspecting Mermaid Code Block Structure

Now open your Markdown document and add the following Mermaid code block.

```mermaid
flowchart TD
 A[Christmas] -->|Get money| B(Go shopping)
 B --> C{Let me think}
 C -->|One| D[Laptop]
 C -->|Two| E[iPhone]
 C -->|Three| F[Car]
```
This flow chart definition is from Mermaid's live editor example.

At this point if you head to the browser to see the rendered output, you wouldn’t see the diagrams rendered. But you can inspect the html code created for this code block.

<pre>
    <code class="language-mermaid">
 flowchart TD
 A[Christmas] -->|Get money| B(Go shopping)
 B --> C{Let me think}
 C -->|One| D[Laptop]
 C -->|Two| E[iPhone]
 C -->|Three| F[Car]
    </code>
</pre>

Notice <code class="lauguage-mermaid"> tag and the class attribute containing the language name. .language-name is going to be the value for our element selector in the next section.

Creating Reusable Astro Component for Mermaid

Next, we will create an Astro component for the Mermaid script. I will name this component as MermaidScript.astro.

---
const {elementSelector} = Astro.props;
---

<mermaid-selector data-elementSelector={elementSelector}></mermaid-selector>

<script>
    import mermaid from 'mermaid';
    mermaid.initialize({ startOnLoad: false });

    customElements.define('mermaid-selector', class extends HTMLElement {
        connectedCallback() {
            const elementSelector = this.dataset.elementselector as string;
            mermaid.run({
                nodes: document.querySelectorAll(elementSelector),
 })
 }
    });
</script>

In the above code block, we start by first destructuring the Astro component props. We are accepting an elementSelector prop. We will pass the selector value we decern in the previous step i.e. .language-mermaid.

Looking at <mermaid-selector> line, we are defining a custom element. This custom element is needed to pass the elementSelector value down to the <script> tag so that we can pass it to mermaid to render diagrams.

Mermaid API provides a method called run(). This method has a property called nodes, which accept DOM elements that we want mermaid to scan for Mermaid diagram definitions and convert them to diagrams. For detailed information on this method please visit Mermaid’s API documentation.

Enabling the Mermaid Rendering

After implementing this step, you need to open you Astro page which is going to render the Markdown content and add the MermaidScript component and pass elementSelector prop with value .language-mermaid. Something like following code block.

Add MermaidScript component in the footer. It will make sure that mermaid code blocks are present before the mermaid script executes.

...
<MermaidScript elementSelector=".language-mermaid"/>
...

It’s time to head to your browser and see your hard work. You would see a nice flowchart rendered.

flowchart TD
 A[Christmas] -->|Get money| B(Go shopping)
 B --> C{Let me think}
 C -->|One| D[Laptop]
 C -->|Two| E[iPhone]
 C -->|Three| F[Car]