Moh Hasbi Assidiqi

Render MermaidJS Diagram in Astro



Diagrams in a blog can be useful for several reasons:

  1. Visual Explanation: Diagrams can help explain complex concepts more clearly than text alone.
  2. Engagement: Visual elements can make a blog post more engaging and interesting to readers.
  3. Memory Retention: People often remember visual information better than text.
  4. Clarification: Diagrams can clarify relationships and processes that might be confusing in a text description.
  5. Professionalism: Including diagrams can make a blog post look more professional and well-researched.

One popular tool for creating diagrams in Markdown is Mermaid. Mermaid is a simple markdown-like script language for generating charts from text via JavaScript. It can be used to create flowcharts, sequence diagrams, Gantt charts, and more.

It also supported by the Markdown community. So that, it can convert this code block syntax…

```mermaid
flowchart LR
    A[Input] --> B[Neuron]
    B --> C[Output]
```

… into this diagram:

In this blog post, we will explore how to render MermaidJS diagrams in an Astro blog using MDX and a Rehype plugin.

Setup

To render MermaidJS diagrams in an Astro blog, we need to use a combination of MDX and a Rehype plugin. Here are the steps to set it up:

1. Install the Required Packages

First, we need to install the necessary packages. We will use rehype-mermaid to render MermaidJS diagrams in our blog.

npm install rehype-mermaid

2. Add some workaround to the Rehype Plugin

The rehype-mermaid plugin does not work out of the box with Astro. We need to add a workaround to make it work. To make it work, rehype-mermaid need a \<pre\> tag with mermaid class. So we need to create a plugin for that. Here is the workaround based on this article:

add-mermaid-classname.ts
import { visit, CONTINUE } from "unist-util-visit"
import type { Plugin } from 'unified';
import type { Root, Element } from 'hast';

const visitor = (node: any) => {
  const dataLanguageMermaid = "mermaid"
  const typeElement = "element"
  const tagNamePre = "pre"
  const classMermaid = dataLanguageMermaid

  const isPreElement = (node: any) => typeof node.type !== undefined && node.type === typeElement
    && node.tagName !== undefined && node.tagName === tagNamePre
    && node.properties !== undefined && node.properties.dataLanguage === dataLanguageMermaid

  if(!isPreElement(node)) {
    return CONTINUE
  }

  const element = node as Element
  const properties = element.properties
  const className = properties.className as Array<string>
  properties.className = [...className, classMermaid]

  return CONTINUE
}

const addMermaidClass: Plugin<void[], Root> = () =>
  (ast: Root) => visit(ast, visitor)

export default addMermaidClass

3. Add the Rehype Plugin to the Astro Config

Finally, we need to add the Rehype plugin to the Astro config. We can do this by updating the astro.config.mjs file in the root of our project:

astro.config.mjs
import rehypeMermaid from 'rehype-mermaid';
import addMermaidClass from './add-mermaid-classname';

export default {
  // Other config options...
  markdown: {
    rehypePlugins: [
      addMermaidClass,
      rehypeMermaid,
    ]
  }
}

4. Render MermaidJS Diagrams in MDX

Now that we have set up the Rehype plugin, we can render MermaidJS diagrams in our MDX files. When we build our Astro project, the MermaidJS diagram will be rendered in the blog post.

Conclusion

In this blog post, we explored how to render MermaidJS diagrams in an Astro blog using MDX and a Rehype plugin. By following the steps outlined above, you can easily include diagrams in your blog posts to enhance the visual appeal and clarity of your content.

Happy diagramming!

References

Mermaid | Diagramming and charting tool

MermaidJS Live Editor

Extending AstroJS Markdown Processing With Remark and Rehype Plugins - DEV Community

Include diagrams in your Markdown files with Mermaid - The GitHub Blog

GitLab Flavored Markdown (GLFM) | GitLab

Width Fit Content

Filename for a Markdown Code Block

Line Numbering using CSS

Demo

Here is a demo of a MermaidJS diagram:

using this syntax

sequenceDiagram
    participant Alice
    participant Bob
    Alice->>John: Hello John, how are you?
    loop HealthCheck
        John->>John: Fight against hypochondria
    end
    Note right of John: Rational thoughts <br/>prevail!
    John-->>Alice: Great!
    John->>Bob: How about you?
    Bob-->>John: Jolly good!