AstroでMermaid図をレンダリングする

Mermaidとは?

Mermaidは、プレーンテキストの定義からフローチャート、シーケンス図、クラス図などをレンダリングするライブラリです。Markdownとの相性が良く、バージョン管理も容易なため、ドキュメントやブログで広く使われています。

rehype-mermaidでMarkdownとMermaidを統合する

rehype-mermaidは、Markdown→HTMLパイプライン内のMermaidコードブロックを検出し、レンダリングされた図(SVGまたは画像)に置き換えるrehypeプラグインです。

  • Markdown内の ```mermaid コードブロック、またはHTML内の <pre class="mermaid"> を検出します
  • remark-rehype の出力(<pre><code class="language-mermaid">)と互換性があります
  • ビルド時に図をレンダリングするため、クライアント側でMermaidを読み込む必要がなく、パフォーマンスとSEOが向上します

インストール

npm install rehype-mermaid

Node.jsで実行する場合、rehype-mermaidは内部的にPlaywrightを使用して図をレンダリングするため、Playwrightとブラウザが必要です:

npm install playwright
npx playwright install --with-deps chromium

Astroのようにビルド時にMarkdownを処理する場合、この設定がビルド環境で必要になります。

使い方(Astroの例)

Astroの markdown.rehypePlugins にrehype-mermaidを追加します:

// astro.config.mjs
import rehypeMermaid from "rehype-mermaid";
 
export default defineConfig({
  markdown: {
    rehypePlugins: [rehypeMermaid],
    gfm: true,
  },
});

設定後、Markdownのコードブロックで言語を mermaid に指定すると、ビルド時に図に変換されます。

GitHub Actionsでのビルド

.github/workflows/deploy-pages.yml ファイルは、main へのプッシュ時にビルドを実行し、Cloudflare Pagesにデプロイする GitHub Actions ワークフローを定義しています。Mermaid図はこのワークフローの pnpm build 中にレンダリングされます。

ワークフローのステップは以下の通りです:

  1. Checkoutactions/checkout でソースを取得します
  2. Node.jsのセットアップpnpm/action-setupactions/setup-node でNode.js 20とpnpm 9を設定します
  3. 依存関係のインストールpnpm install --frozen-lockfile
  4. Chromiumのインストールpnpx playwright install --with-deps chromium を実行し、rehype-mermaidが図をレンダリングするために必要な環境を整えます
  5. ビルドpnpm build でAstroのMarkdown処理がトリガーされ、rehype-mermaidが各 ```mermaid ブロックをSVGに置き換えます
  6. デプロイcloudflare/wrangler-actiondist をCloudflare Pagesプロジェクト tadayou にアップロードします

ワークフローのYAMLは以下の通りです:

# .github/workflows/deploy-pages.yml
name: Deploy to Cloudflare Pages
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: cloudflare pages
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v3
        with:
          version: 9
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"
      - run: pnpm install --frozen-lockfile
      - run: pnpx playwright install --with-deps chromium
      - run: pnpm build
        env:
          NODE_ENV: production
      - uses: cloudflare/wrangler-action@v3
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          command: pages deploy dist --project-name=tadayou

SVGはCI中に埋め込まれるため、本番のHTMLにはレンダリング済みの図が含まれており、ランタイムでMermaidのJavaScriptを読み込む必要はありません。

Markdownで図を書く

記事では、Mermaid構文を ```mermaid フェンスで囲みます:

フローチャートの例

シーケンス図の例

レンダリング戦略

rehype-mermaidは出力形式を制御する strategy オプションを受け付けます:

strategy説明
'inline-svg'インラインの <svg> を出力します(デフォルト
'img-svg'SVGデータURLの <img> を出力します
'img-png'PNGデータURLの <img> を出力します
'pre-mermaid'<pre class="mermaid"> をそのまま残し、クライアント側でMermaidがレンダリングします

デフォルトの inline-svg はビルド時にSVGを埋め込むため、追加のJavaScriptは不要です。このブログではこのアプローチを採用しています。

まとめ

  • Mermaid を使うと、テキストで図を定義できます
  • rehypeパイプラインに rehype-mermaid を追加すると、ビルド時に ```mermaid ブロックが図に変換されます
  • Astroでは rehypePlugins に追加するだけです
  • GitHub Actionsでビルドする場合pnpm build の前に pnpx playwright install --with-deps chromium を実行して、CIで図がレンダリングされデプロイ出力に含まれるようにします
  • デフォルトの inline-svg 戦略を使えば、クライアント側のオーバーヘッドなしで図を表示できます

ドキュメントやブログでMermaidを使いたい場合は、rehype-mermaidをぜひ試してみてください。