Astroでブログ作成してみた話 -技術編-
Next.jsばっかりやってたけどAstroでブログ作ってみたら爆速すぎた!1.5秒でビルド完了、設定不要でMarkdown対応、画像最適化も自動。個人ブログ作るならNext.jsよりAstroの方が圧倒的に楽だったので、実際の開発体験と選んだ理由を話します。
「ブログ記事でフローチャートやシーケンス図を使いたいな…」
そう思って、Mermaidをブログに導入してみようとしたんですが、これが意外と大変でした。
Mermaidは、テキストベースで図表を簡単に作れる便利なツール。
Markdownのコードブロックに記述するだけで、フローチャート、シーケンス図、ガントチャートなどが描けます。
この記事では、AstroブログにMermaid図表を導入する方法と、実際にハマったポイント・解決策を詳しくまとめます。
同じように導入を検討している方の参考になれば嬉しいです。
Mermaidは、テキストで図表を描けるJavaScriptライブラリです。
上記のようなコードブロックを書くと、フローチャートが自動的にSVG形式で生成されます。
図表として視覚的に表示されるので、複雑なプロセスや関係性を一目で理解できるようになります。
Mermaidでは、様々な種類の図表を作成できます。
ここでは、特によく使う3つの図表を実際に表示してみます。
他にも、ガントチャート(プロジェクトのスケジュール管理)、ER図(データベース設計の可視化)、状態遷移図など、様々な図表が作成できます。
技術的な説明をする時に、言葉だけで伝えるより図表があった方が圧倒的に分かりやすいですよね。
私のブログでは、技術系の記事を書くことが多いです。
最近、「プログラムの処理フローを説明したいな」と思う機会が増えてきました。
でもいちいち図を作るのは手間がかかるし、修正も面倒…
そこで、コードベースで図表を管理できるMermaidが最適だなと思い採用しました。
特に、「後から修正しやすい」ことと「AIでサッと大枠を生成できる」というのが大きなポイントでした。
本記事は以下の環境で検証しています。
それでは、実際の導入手順を見ていきましょう。
まずは必要なパッケージをインストールします。
npm install rehype-mermaid unist-util-visit
npm install -D playwright
rehype-mermaidは、ビルド時(サーバーサイド)でMermaid図をSVG画像に変換します。しかし、Mermaid自体はブラウザ上で動くJavaScriptライブラリで、DOMやCanvasなどのブラウザAPIを使用します。
Node.js環境(ビルド時)にはこれらのAPIがないため、Playwrightというヘッドレスブラウザ(画面なしで動くブラウザ)を使って、仮想的にブラウザ環境を作り出しています。
つまり、「サーバーサイドでブラウザ専用ライブラリを動かす」ためにPlaywrightが必要というわけです。
パッケージをインストールしただけでは、Playwrightは動きません。
別途、ブラウザバイナリのインストールが必要です。
npx playwright install
これを忘れると、ビルド時に「Executable doesn’t exist」というエラーが出るので注意してください。
ここが今回のハマりポイントでした。
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の設定ファイルにプラグインを組み込みます。
export default defineConfig({
integrations: [
mdx({
syntaxHighlight: false, // 重要!
rehypePlugins: [
addMermaidClass, // 先にクラスを追加
[rehypeMermaid, { strategy: 'inline-svg' }] // 後でレンダリング
],
}),
// 他のインテグレーション...
],
markdown: {
syntaxHighlight: 'shiki', // Markdown用のシンタックスハイライトは有効
},
});
syntaxHighlight: false: MDXのシンタックスハイライトを無効化addMermaidClassを先に、rehype-mermaidを後に配置strategy: 'inline-svg': SVGをインラインで埋め込む設定rehype-mermaidより先にクラスを追加しないと、Mermaidとして認識されません。rehypePlugins配列の順序には注意してください。
問題: rehype-mermaidをインストールして設定に追加しただけでは、Mermaidコードブロックがただの文字列として表示される
原因: rehype-mermaidは<pre>タグにmermaidクラスが付いていることを期待しているが、Astroは自動でそのクラスを付けてくれない
解決策: カスタムrehypeプラグインを作成して、mermaidコードブロックに自動でmermaidクラスを追加する
これが一番苦戦したポイントです。
公式ドキュメントを見て「インストールしたらすぐに行けるかな」と思ってたんですが、全然動かなくて…
調べてみたら、Astro特有の問題だったみたいです。
問題: ビルド時に「Executable doesn’t exist」というエラーが出る
原因: rehype-mermaidはサーバーサイドでMermaid図をレンダリングするためにPlaywrightを使用するが、ブラウザバイナリが別途必要
解決策: 以下のコマンドを実行
npx playwright install
これは最初、エラーメッセージを見ても意味が分かりませんでした。
「Executable doesn’t exist」って何が存在しないの?って感じで。
調べてみたら、Playwrightのブラウザバイナリが必要だったんですね。
問題: 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が適用されます。
問題: rehype-mermaidより先にクラスを追加しないといけない
解決策: rehypePlugins配列で、カスタムプラグインを先に、rehype-mermaidを後に配置
rehypePlugins: [
addMermaidClass, // ← 先にクラスを追加
[rehypeMermaid, { strategy: 'inline-svg' }] // ← 後でレンダリング
]
これも最初分からなくて、順序を逆にしていたら全然動かなかったです。
rehypeプラグインは配列の順番通りに実行されるので、順序が重要なんですね。
最終的に、以下の構成で動作するようになりました。
{
"dependencies": {
"rehype-mermaid": "^3.0.0",
"unist-util-visit": "^5.0.0"
},
"devDependencies": {
"playwright": "^1.56.1"
}
}
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になっているかmermaidになっているかrm -rf .astro && npm run build)Mermaid図表を導入してから、複雑な処理フローやシステム構成を説明するのがすごく楽になりました。
文章だけで伝えるより、図表があった方が読む人にとってわかりやすいですよね。
画像ファイルと違ってテキストで管理できるので、Gitで差分も追えるし、修正も簡単です。
導入は少し手間がかかりましたが、一度設定してしまえば快適に使えています。
AstroブログにMermaid図表を導入する方法と、実際にハマったポイントを紹介しました。
syntaxHighlight: falsenpx playwright install正直、思ったより大変でした。
当初の想定より意外と手間がかかったかもしれません。
でも、導入してしまえば、テキストベースで図表を管理できるのはすごく便利です。
技術ブログを運営している方には、おすすめの機能だと思います。
同じように導入を検討している方の参考になれば嬉しいです。
何か質問があれば、X(旧Twitter)でお気軽に聞いてください!
読んでくれてありがとう。よかったらシェアやフォロー押してってください。Xで雑に絡んでくれるのも普通に嬉しい。