技術ブログにMermaidダイアグラムを導入した話【はてなブログ・DEV.to・Next.js対応】
はじめに
技術記事を書く時、フローチャートやシーケンス図があると格段に分かりやすくなりますよね。
今回、マルチプラットフォーム対応の技術ブログでMermaid記法によるダイアグラム表示に対応したので、その実装方法を紹介します!
対応したプラットフォーム:
- 📝 はてなブログ - カスタムJavaScriptで対応
- 🌐 DEV.to - Mermaidを画像に変換して投稿
- ⚡ Next.js(Vercel) - クライアントサイドレンダリング
Mermaidとは?
Mermaidは、テキストベースでダイアグラムを描けるJavaScriptライブラリです。
記述例:
graph TD
A[ユーザー] -->|記事を書く| B[Markdown]
B -->|変換| C[Mermaid]
C -->|レンダリング| D[ダイアグラム表示]
シンプルなテキストで、こんな感じの図が描けます。めっちゃ便利!
各プラットフォームの対応方法
1. はてなブログでの対応
はてなブログは標準でMermaidをサポートしていないため、カスタムJavaScriptで対応しました。
実装手順
1) はてなブログの管理画面で「設定」→「詳細設定」を開く
2) 「headに要素を追加」に以下を貼り付け:
<!-- Mermaidダイアグラムのスタイル設定 -->
<style>
.mermaid {
background-color: #ffffff !important;
padding: 20px;
border-radius: 4px;
margin: 20px 0;
}
.mermaid svg {
background-color: #ffffff !important;
}
</style>
<!-- Mermaidダイアグラム表示用スクリプト -->
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
document.addEventListener('DOMContentLoaded', function() {
mermaid.initialize({
startOnLoad: true,
theme: 'default',
themeVariables: {
background: '#ffffff'
},
securityLevel: 'loose'
});
document.querySelectorAll('pre code').forEach((codeBlock) => {
const codeText = codeBlock.textContent || codeBlock.innerText;
if (codeText.trim().startsWith('mermaid')) {
const pre = codeBlock.parentElement;
if (pre) {
const lines = codeText.split('\\n');
const mermaidCode = lines.slice(1).join('\\n').trim();
const mermaidDiv = document.createElement('div');
mermaidDiv.className = 'mermaid';
mermaidDiv.textContent = mermaidCode;
pre.replaceWith(mermaidDiv);
}
}
});
mermaid.run({
querySelector: '.mermaid'
});
});
</script>
3) 記事では以下のように書く:
```
mermaid
graph LR
A --> B
```
[!IMPORTANT] はてなブログでは
```mermaidという書き方ができないため、コードブロック内の最初の行にmermaidと書く必要があります。
ポイント
- ✅ 白背景を強制: 暗い背景になる問題を解決
- ✅ CDN経由: 最新版のMermaidを自動で利用
- ✅ 一度設定すれば全記事に適用
2. DEV.toでの対応
DEV.toはMermaidをネイティブサポートしていないため、画像に変換して投稿する方式を採用しました。
実装(自動化)
Node.jsスクリプトで、記事投稿時に自動的にMermaidブロックを画像に変換します。
// scripts/utils/mermaid-converter.mjs
import { execSync } from 'child_process';
export async function convertMermaidToImage(mermaidCode, outputPath) {
const tempInputFile = `/tmp/mermaid-${Date.now()}.mmd`;
fs.writeFileSync(tempInputFile, mermaidCode, 'utf8');
// mermaid-cliで画像変換(背景は白色)
execSync(
`npx -y @mermaid-js/mermaid-cli@latest -i "${tempInputFile}" -o "${outputPath}" -b white`,
{ stdio: 'inherit' }
);
fs.unlinkSync(tempInputFile);
return true;
}
変換の流れ:
- Markdown内の
```mermaidブロックを検出 @mermaid-js/mermaid-cliで画像(PNG)に変換public/images/diagrams/に保存- Markdownを
に置き換え
メリット
- ✅ DEV.toでも確実に表示される
- ✅ 画像なのでロード時間が速い
- ✅ ダークモードでも見やすい(白背景指定)
3. Next.js(Vercel)での対応
自サイト(Next.js)では、クライアントサイドでMermaidをレンダリングしています。
実装
// src/components/mdx/MermaidRenderer.tsx
'use client';
import { useEffect } from 'react';
export function MermaidRenderer() {
useEffect(() => {
async function initMermaid() {
const mermaid = (await import('mermaid')).default;
mermaid.initialize({
startOnLoad: true,
theme: 'default',
themeVariables: {
background: '#ffffff', // ダークモードでも白背景
},
securityLevel: 'loose',
});
const codeBlocks = document.querySelectorAll('pre code.language-mermaid');
codeBlocks.forEach((codeBlock, index) => {
const pre = codeBlock.parentElement;
if (pre) {
const code = codeBlock.textContent || '';
const wrapper = document.createElement('div');
wrapper.className = 'mermaid-diagram-wrapper';
wrapper.id = `mermaid-diagram-${index}`;
wrapper.textContent = code;
pre.replaceWith(wrapper);
}
});
mermaid.run({
querySelector: '.mermaid-diagram-wrapper',
});
}
initMermaid();
}, []);
return null;
}
ダークモード対応(CSS)
/* src/app/globals.css */
.mermaid-diagram-wrapper,
.mermaid-diagram-wrapper svg {
background-color: #ffffff !important;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
/* ダークモードでは薄い枠線を追加 */
.dark .mermaid-diagram-wrapper {
border: 1px solid #475569;
}
苦労した点と解決方法
問題1: 背景が暗くて見づらい
症状: デフォルトのMermaidテーマだと、ダイアグラムの背景が暗い色になり、矢印や文字が見にくい。
解決策:
themeVariables.background: '#ffffff'で強制的に白背景に- CSSで
.mermaid要素にも白背景を適用
問題2: ダークモードで真っ白すぎて浮く
症状: ダークモードのページで白背景のダイアグラムが浮いて見える。
解決策:
.dark .mermaid-diagram-wrapper {
border: 1px solid #475569; /* 薄い枠線を追加 */
}
問題3: はてなブログで ```mermaid が使えない
症状: はてなブログはコードブロックの言語指定に対応していない。
解決策:
コードブロック内の最初の行を mermaid にして、JavaScriptで判定する方式に変更。
まとめ
Mermaidダイアグラムを3つのプラットフォームで表示できるようにした実装を紹介しました。
ポイント:
- 📝 はてなブログ: カスタムJSで動的レンダリング
- 🌐 DEV.to: CLIで事前に画像変換
- ⚡ Next.js: クライアントサイドレンダリング + ダークモード対応
各プラットフォームの特性に合わせた実装で、どこでも快適にダイアグラムが表示されるようになりました!
技術記事に図解を入れたい方の参考になれば嬉しいです 🎉
参考リンク
この記事の図解もすべてMermaidで作成されています!
