How to Integrate Next, React, Mermaid, and Markdown

Andy Nanopoulos • February 9, 2023 2 min read

how-to-integrate-next-react-mermaid-markdown

Its a challenge to get Mermaid.js, Next 13, React, and Markdown to play nicely together when using the /app directory structure for a Next project. The goal is to be able to define a Mermaid diagram in a Markdown file that has been server-side rendered. These are the steps I used to accomplish this goal:

  • npm install react-markdown
  • npm install remark-gfm
  • npm install rehype-raw
  • This is an example page.jsx file that I've placed at /app/blog/[slug]/page.jsx
import React from "react";
import PropTypes from "prop-types";
import getMarkdowns from "../../../src/utils/getMarkdowns/getMarkdowns";
import getMarkdown from "../../../src/utils/getMarkdown/getMarkdown";
import remarkGfm from "remark-gfm";
import rehypeRaw from "rehype-raw";
import ReactMarkdown from "react-markdown";
import Script from "next/script";

export default async function Page({ params }) {
const contentPath = "src/content/blog";
const post = getMarkdown(params.slug, contentPath);

return (
  <div>
    <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
      {post.content}
    </ReactMarkdown>
    <Script
      type="module"
      strategy="afterInteractive"
      dangerouslySetInnerHTML={{
        __html: `
        import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs";
        mermaid.initialize({startOnLoad: true});
        mermaid.contentLoaded();
`,
      }}
    />
  </div>
);
}

export function generateStaticParams() {
const contentPath = "src/content/blog";
const posts = getMarkdowns(contentPath);

return posts.map((post) => ({
  slug: post.slug,
}));
}

Page.propTypes = {
params: PropTypes.func.isRequired,
};
  • I've placed my blog posts .md files in the directory /src/content/blog. As an example, add this snippet to your .md file. If you are not using tailwindcss, remove the bg-white, flex, and justify-center tags:
<pre class="mermaid bg-white flex justify-center">
graph LR
  Start --> Stop
</pre>

Mermaid looks for <pre class="mermaid"> tags, so we define those tags in the Markdown file and those tags will be included in the output of the page that is server-side rendered. The purpose of the rehype-raw plugin is to allow HTML to be added to the Markdown file. Once the page is loaded in the browser, Mermaid will replace the <pre> tags with an SVG of the diagram. You will see the original text first, then the SVG will replace it. If this bothers you, skip this whole process, create an image of the mermaid diagram, place it in your public folder, and include the image path in your markdown file. Enjoy!

sequenceDiagram
    You->>Me: This is cool!
    Me-->>You: Glad you like it!