🌿 えふてぃブログ

AstroブログにMermaid図表を導入した話【ハマったポイントと解決策】


こんにちは、えふてぃです。

「ブログ記事でフローチャートやシーケンス図を使いたいな…」
そう思って、Mermaidをブログに導入してみようとしたんですが、これが意外と大変でした。

Mermaidは、テキストベースで図表を簡単に作れる便利なツール。
Markdownのコードブロックに記述するだけで、フローチャート、シーケンス図、ガントチャートなどが描けます。

この記事では、AstroブログにMermaid図表を導入する方法と、実際にハマったポイント・解決策を詳しくまとめます。
同じように導入を検討している方の参考になれば嬉しいです。

Mermaidとは?

Mermaidは、テキストで図表を描けるJavaScriptライブラリです。

Yes

No

開始

条件分岐

処理1

処理2

終了

上記のようなコードブロックを書くと、フローチャートが自動的にSVG形式で生成されます。
図表として視覚的に表示されるので、複雑なプロセスや関係性を一目で理解できるようになります。

Mermaidでできること

Mermaidでは、様々な種類の図表を作成できます。
ここでは、特によく使う3つの図表を実際に表示してみます。

フローチャート(プロセスの流れを視覚化)

Yes

No

開始

条件判定

処理A

処理B

終了

シーケンス図(システム間のやり取りを図示)

DBサーバークライアントDBサーバークライアントリクエスト送信データ取得データ返却レスポンス返却

クラス図(オブジェクト指向設計の図示)

作成する

1
*

User

+String name

+String email

+login()

+logout()

Article

+String title

+String content

+publish()

他にも、ガントチャート(プロジェクトのスケジュール管理)、ER図(データベース設計の可視化)、状態遷移図など、様々な図表が作成できます。

技術的な説明をする時に、言葉だけで伝えるより図表があった方が圧倒的に分かりやすいですよね。

なぜAstroブログに追加したのか

私のブログでは、技術系の記事を書くことが多いです。
最近、「プログラムの処理フローを説明したいな」と思う機会が増えてきました。

でもいちいち図を作るのは手間がかかるし、修正も面倒…
そこで、コードベースで図表を管理できるMermaidが最適だなと思い採用しました。

Mermaidのメリット

  1. テキストで管理できる: Gitで差分管理しやすい
  2. 修正が簡単: コードを書き換えるだけ
  3. 統一感がある: 自動生成なので見た目が統一される
  4. 軽量: 画像ファイルを増やさずに済む
  5. AIとの相性が良い: Claudeあたりに「〇〇の図を作って」と頼めば、Mermaid記法でコードを生成してくれる

特に、「後から修正しやすい」ことと「AIでサッと大枠を生成できる」というのが大きなポイントでした。

環境

本記事は以下の環境で検証しています。

  • Node.js: 20.x
  • Astro: 5.x

それでは、実際の導入手順を見ていきましょう。

必要なパッケージのインストール

まずは必要なパッケージをインストールします。

npm install rehype-mermaid unist-util-visit
npm install -D playwright

パッケージの役割

  • rehype-mermaid: MermaidコードをSVGに変換するrehypeプラグイン
  • unist-util-visit: ASTを走査するユーティリティ(カスタムプラグインで使用)
  • Playwright: サーバーサイドでMermaidをレンダリングするために必要
📝 なぜPlaywrightが必要なのか?

rehype-mermaidは、ビルド時(サーバーサイド)でMermaid図をSVG画像に変換します。しかし、Mermaid自体はブラウザ上で動くJavaScriptライブラリで、DOMやCanvasなどのブラウザAPIを使用します。

Node.js環境(ビルド時)にはこれらのAPIがないため、Playwrightというヘッドレスブラウザ(画面なしで動くブラウザ)を使って、仮想的にブラウザ環境を作り出しています。

つまり、「サーバーサイドでブラウザ専用ライブラリを動かす」ためにPlaywrightが必要というわけです。

Playwrightのブラウザをインストール

パッケージをインストールしただけでは、Playwrightは動きません。
別途、ブラウザバイナリのインストールが必要です。

npx playwright install

これを忘れると、ビルド時に「Executable doesn’t exist」というエラーが出るので注意してください。

カスタムrehypeプラグインの作成

ここが今回のハマりポイントでした。
rehype-mermaidをインストールして設定に追加しただけでは、Mermaidコードブロックがただの文字列として表示されるんです。

原因

rehype-mermaidは、<pre>タグにmermaidクラスが付いていることを期待しています。
しかし、Astroは自動でそのクラスを付けてくれません。

解決策

カスタムrehypeプラグインを作成して、mermaidコードブロックに自動でmermaidクラスを追加します。

astro.config.mjsに以下のコードを追加してください。

import rehypeMermaid from 'rehype-mermaid';
import { visit, CONTINUE } from 'unist-util-visit';

// カスタムrehypeプラグイン
const addMermaidClass = () => (tree) => {
  visit(tree, (node) => {
    // <pre>タグかつdataLanguageがmermaidの場合
    if (
      node.type === 'element' &&
      node.tagName === 'pre' &&
      node.properties?.dataLanguage === 'mermaid'
    ) {
      // 既存のclassNameを保持しつつ、mermaidクラスを追加
      node.properties.className = [...(node.properties.className || []), 'mermaid'];
      return CONTINUE; // 次のノードへ
    }
  });
};

このプラグインは、ASTを走査してdataLanguage="mermaid"を持つ<pre>タグを見つけ、mermaidクラスを追加します。
これにより、rehype-mermaidがMermaidコードブロックを正しく認識できるようになります。

astro.config.mjsの設定

次に、Astroの設定ファイルにプラグインを組み込みます。

export default defineConfig({
  integrations: [
    mdx({
      syntaxHighlight: false, // 重要!
      rehypePlugins: [
        addMermaidClass, // 先にクラスを追加
        [rehypeMermaid, { strategy: 'inline-svg' }] // 後でレンダリング
      ],
    }),
    // 他のインテグレーション...
  ],
  markdown: {
    syntaxHighlight: 'shiki', // Markdown用のシンタックスハイライトは有効
  },
});

ポイント

  1. syntaxHighlight: false: MDXのシンタックスハイライトを無効化
  2. プラグインの順序: addMermaidClassを先に、rehype-mermaidを後に配置
  3. strategy: 'inline-svg': SVGをインラインで埋め込む設定
💡 プラグインの実行順序が重要

rehype-mermaidより先にクラスを追加しないと、Mermaidとして認識されません。rehypePlugins配列の順序には注意してください。

ハマったポイント詳細

1. rehype-mermaidがそのままでは動かない

問題: rehype-mermaidをインストールして設定に追加しただけでは、Mermaidコードブロックがただの文字列として表示される

原因: rehype-mermaidは<pre>タグにmermaidクラスが付いていることを期待しているが、Astroは自動でそのクラスを付けてくれない

解決策: カスタムrehypeプラグインを作成して、mermaidコードブロックに自動でmermaidクラスを追加する

これが一番苦戦したポイントです。
公式ドキュメントを見て「インストールしたらすぐに行けるかな」と思ってたんですが、全然動かなくて…

調べてみたら、Astro特有の問題だったみたいです。

2. Playwrightのブラウザインストールが必要

問題: ビルド時に「Executable doesn’t exist」というエラーが出る

原因: rehype-mermaidはサーバーサイドでMermaid図をレンダリングするためにPlaywrightを使用するが、ブラウザバイナリが別途必要

解決策: 以下のコマンドを実行

npx playwright install

これは最初、エラーメッセージを見ても意味が分かりませんでした。
「Executable doesn’t exist」って何が存在しないの?って感じで。

調べてみたら、Playwrightのブラウザバイナリが必要だったんですね。

3. MDXのシンタックスハイライトと競合

問題: Shikiがmermaidコードブロックをシンタックスハイライトしようとして、rehype-mermaidの処理を邪魔する

原因: MDXの設定でシンタックスハイライトが有効になっていると、Mermaidコードブロックが先にハイライト処理されてしまう

解決策: MDXの設定でsyntaxHighlight: falseにして、シンタックスハイライトを無効化

mdx({
  syntaxHighlight: false, // これ重要!
  rehypePlugins: [
    addMermaidClass,
    [rehypeMermaid, { strategy: 'inline-svg' }]
  ],
})

最初、「なんでコードブロックがハイライトされた状態で表示されるんだ?」って思ったんですが、Shikiが先に処理していたからでした。

👤

でも、他のコードブロックのシンタックスハイライトは残したいんだけど…

大丈夫です!MDXのシンタックスハイライトを無効化しても、Markdownファイル用のシンタックスハイライトは別に設定できます。上記の設定では、markdown.syntaxHighlight: 'shiki'で通常のMarkdownファイルにはShikiが適用されます。

🤖

4. プラグインの実行順序が重要

問題: rehype-mermaidより先にクラスを追加しないといけない

解決策: rehypePlugins配列で、カスタムプラグインを先に、rehype-mermaidを後に配置

rehypePlugins: [
  addMermaidClass,           // ← 先にクラスを追加
  [rehypeMermaid, { strategy: 'inline-svg' }]  // ← 後でレンダリング
]

これも最初分からなくて、順序を逆にしていたら全然動かなかったです。
rehypeプラグインは配列の順番通りに実行されるので、順序が重要なんですね。

最終的な構成

最終的に、以下の構成で動作するようになりました。

package.json(抜粋)

{
  "dependencies": {
    "rehype-mermaid": "^3.0.0",
    "unist-util-visit": "^5.0.0"
  },
  "devDependencies": {
    "playwright": "^1.56.1"
  }
}

astro.config.mjs(完全版)

import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import rehypeMermaid from 'rehype-mermaid';
import { visit, CONTINUE } from 'unist-util-visit';

// カスタムrehypeプラグイン
const addMermaidClass = () => (tree) => {
  visit(tree, (node) => {
    // <pre>タグかつdataLanguageがmermaidの場合
    if (
      node.type === 'element' &&
      node.tagName === 'pre' &&
      node.properties?.dataLanguage === 'mermaid'
    ) {
      // 既存のclassNameを保持しつつ、mermaidクラスを追加
      node.properties.className = [...(node.properties.className || []), 'mermaid'];
      return CONTINUE; // 次のノードへ
    }
  });
};

export default defineConfig({
  integrations: [
    mdx({
      syntaxHighlight: false,
      rehypePlugins: [
        addMermaidClass,
        [rehypeMermaid, { strategy: 'inline-svg' }]
      ],
    }),
    // 他のインテグレーション...
  ],
  markdown: {
    syntaxHighlight: 'shiki',
  },
});

実際の使用例

設定が完了したら、MDXファイルでMermaidが使えるようになります。

フローチャートの例

```mermaid
graph TD
    A[ユーザー登録] --> B{メール認証}
    B -->|成功| C[アカウント有効化]
    B -->|失敗| D[エラーメッセージ]
    C --> E[ホーム画面へ]
    D --> A
```

シーケンス図の例

```mermaid
sequenceDiagram
    participant U as ユーザー
    participant S as サーバー
    participant DB as データベース

    U->>S: ログイン要求
    S->>DB: 認証情報確認
    DB-->>S: 認証結果
    S-->>U: ログイン成功
```

コードブロックに書くだけで、自動的にSVG図表として表示されます。

ビルド時にレンダリング

rehype-mermaidは、ビルド時にMermaid図をSVGに変換します。そのため、ブラウザ側でJavaScriptを実行する必要がなく、パフォーマンスも良好です。

トラブルシューティング

もし問題が発生した場合は、以下の点を確認してください。

  • npx playwright installを実行したか
  • astro.config.mjsでMDXのsyntaxHighlight: falseになっているか
  • rehypePlugins配列の順序が正しいか(addMermaidClass → rehypeMermaid)
  • コードブロックの言語指定がmermaidになっているか
  • ビルドをクリーンしてから再実行してみる(rm -rf .astro && npm run build

導入してよかったこと

Mermaid図表を導入してから、複雑な処理フローやシステム構成を説明するのがすごく楽になりました。
文章だけで伝えるより、図表があった方が読む人にとってわかりやすいですよね。

画像ファイルと違ってテキストで管理できるので、Gitで差分も追えるし、修正も簡単です。
導入は少し手間がかかりましたが、一度設定してしまえば快適に使えています。

まとめ:Astro × Mermaidは便利だけど導入は要注意

AstroブログにMermaid図表を導入する方法と、実際にハマったポイントを紹介しました。

導入のポイント

  1. 必要なパッケージ: rehype-mermaid、unist-util-visit、playwright
  2. カスタムプラグインが必須: mermaidクラスを自動追加する
  3. シンタックスハイライトを無効化: MDXの設定でsyntaxHighlight: false
  4. プラグインの順序が重要: クラス追加→Mermaidレンダリングの順
  5. Playwrightのブラウザインストールを忘れずに: npx playwright install

正直、思ったより大変でした。
当初の想定より意外と手間がかかったかもしれません。

でも、導入してしまえば、テキストベースで図表を管理できるのはすごく便利です。
技術ブログを運営している方には、おすすめの機能だと思います。

同じように導入を検討している方の参考になれば嬉しいです。
何か質問があれば、X(旧Twitter)でお気軽に聞いてください!

参考リンク


このブログが面白いと思った方は、是非とも下のボタンをクリックして、記事シェアやフォローをしていただけると嬉しいです!

この記事をシェア: はてブ

📚 関連記事

【第2章】Meta タグとOGP設定でSNSシェアを最適化!Astroブログで実装してみた

【第2章】Meta タグとOGP設定でSNSシェアを最適化!Astroブログで実装してみた

SEO対策の第2章として、Meta タグとOGP設定をAstroブログに実装してみました。検索結果やSNSシェアの見栄えを改善する方法を、実際のコード例と試行錯誤のプロセスを交えて解説します。

技術
Claude Code CLIのカスタムコマンドでブログ記事の品質チェックを効率化した話

Claude Code CLIのカスタムコマンドでブログ記事の品質チェックを効率化した話

Claude Codeのカスタムコマンド機能を使って、ブログ記事の事実確認を自動化する方法を紹介。技術記事や雑記記事の信頼性を高めるための実装例を解説します。

技術
【第1章】SEO対策とは?個人ブログ開発者が検索順位を上げるために調べた4つの施策

【第1章】SEO対策とは?個人ブログ開発者が検索順位を上げるために調べた4つの施策

SEO対策って何をすればいいの?と思って調べてみた話をまとめました。検索エンジンで上位表示されるために重要な4つの施策(コンテンツ最適化、技術的SEO、UX、外部対策)とGoogleの評価基準(E-E-A-T)を解説します。

技術 ショート
Claude Code CLIのカスタムコマンドでブログ運営を効率化する方法

Claude Code CLIのカスタムコマンドでブログ運営を効率化する方法

Claude Code CLIのカスタムコマンドで、記事作成からレビューまで自動化したら爆速になった!実際に作った「ブログ作成を支援」「ブログのレビュー」コマンドのコードと使い方を全部公開。ブログ運営を効率化したい人におすすめです。

技術