Mermaid で日本語が潰れる問題を解決:フォント・エンコード・SVG 設定の勘所
Mermaid で図を描く際に「日本語が豆腐になる」「文字が潰れて読めない」といった問題に遭遇したことはありませんか。英語だけなら綺麗に表示できるのに、日本語を使った途端に文字化けしてしまう……そんな困った経験をお持ちの方は少なくないでしょう。
本記事では、Mermaid で日本語が正しく表示されない原因を整理し、フォント設定・エンコード指定・SVG 出力時の注意点という 3 つの観点から具体的な解決策をご紹介します。これらを押さえておけば、日本語を含むフローチャートやシーケンス図も美しく描けるようになるはずです。
背景
Mermaid とは
Mermaid は、Markdown 風のテキストからフローチャートやシーケンス図などを自動生成できるダイアグラムツールです。GitHub や GitLab、Notion などでも対応が進んでおり、エンジニアの間で広く利用されていますね。
以下のようなシンプルなテキストから、フローチャートを自動生成できます。
mermaidflowchart LR
start["開始"] --> process["処理"]
process --> done["終了"]
コードは次のように記述します。
markdown```mermaid
flowchart LR
start["開始"] --> process["処理"]
process --> done["終了"]
```
このように、手軽にテキストベースで図を描けるのが魅力です。
日本語表示の難しさ
Mermaid は元々英語圏で開発されたため、デフォルトのフォント設定が欧文フォントになっていることがほとんどです。そのため日本語をノードやエッジに含めると、以下のような問題が起こります。
- 文字化け(豆腐、□ が並ぶ)
- 半角カタカナや濁点が分離
- フォントサイズが不自然に小さくなる
- SVG 出力時に表示が崩れる
これらは、フォント未指定・エンコーディングの不一致・レンダリングエンジンの違いなどが複雑に絡み合って発生するのです。
下図は、日本語表示で問題が起きる仕組みを簡略化したものです。
mermaidflowchart TD
text["Mermaid コード<br/>(日本語を含む)"] --> render["レンダリング"]
render --> font_check["フォント確認"]
font_check -->|日本語フォント不在| mojibake["文字化け"]
font_check -->|日本語フォント有| ok["正常表示"]
render --> encode_check["エンコード確認"]
encode_check -->|UTF-8 未指定| broken["文字崩れ"]
encode_check -->|UTF-8 指定済| ok
上記の図を生成するコードは以下の通りです。
markdown```mermaid
flowchart TD
text["Mermaid コード<br/>(日本語を含む)"] --> render["レンダリング"]
render --> font_check["フォント確認"]
font_check -->|日本語フォント不在| mojibake["文字化け"]
font_check -->|日本語フォント有| ok["正常表示"]
render --> encode_check["エンコード確認"]
encode_check -->|UTF-8 未指定| broken["文字崩れ"]
encode_check -->|UTF-8 指定済| ok
```
図で理解できる要点
- Mermaid コードがレンダリングされる際に、フォントとエンコードの 2 つのチェックを経る
- どちらかでも問題があると、文字化けや崩れが発生する
- 日本語フォントと UTF-8 エンコードの両方を正しく設定することが鍵
課題
Mermaid で日本語を扱おうとすると、以下のような複数の課題が同時に発生します。
| # | 課題 | 典型的な症状 |
|---|---|---|
| 1 | 日本語フォントが未指定 | □(豆腐文字)の表示 |
| 2 | エンコード指定の欠落 | 半角カタカナ化・濁点分離 |
| 3 | SVG 埋め込み時のスタイル不備 | ブラウザやツールでの表示崩れ |
| 4 | レンダリング環境の差異 | CLI と Web で異なる結果 |
これらの課題は、1 つだけ解決しても他の要素が原因で問題が残ることが多く、総合的な対処が必要です。
1. 日本語フォントが未指定
Mermaid のデフォルト設定は欧文フォント(例:Arial、sans-serif)に依存しています。そのため、日本語が含まれるノードラベルやエッジラベルを描画する際にフォントが見つからず、文字化けします。
2. エンコード指定の欠落
HTML ファイルに Mermaid を埋め込む際、<meta charset="UTF-8"> を忘れたり、Markdown ファイル自体が Shift_JIS など別エンコードで保存されていたりすると、ブラウザ側で正しく認識できません。
3. SVG 埋め込み時のスタイル不備
Mermaid は最終的に SVG として出力されますが、SVG 内部に日本語フォントの指定が含まれていないと、別のツールやブラウザで開いた際に再び文字化けが起きます。
4. レンダリング環境の差異
CLI ツール(mermaid-cli など)と Web ブラウザでは、インストール済みのフォントやレンダリングエンジンが異なります。そのため、ローカルでは問題なくても、CI/CD やドキュメント生成時に崩れるケースがあります。
下図は、課題がどのように関連しているかを示したものです。
mermaidflowchart LR
issue1["課題1<br/>フォント未指定"] --> symptom1["豆腐文字"]
issue2["課題2<br/>エンコード欠落"] --> symptom2["濁点分離"]
issue3["課題3<br/>SVG スタイル不備"] --> symptom3["ツール間で表示差"]
issue4["課題4<br/>環境差異"] --> symptom4["CLI/Web で異なる結果"]
symptom1 --> problem["日本語が<br/>正しく見えない"]
symptom2 --> problem
symptom3 --> problem
symptom4 --> problem
上記の図を生成するコードは以下の通りです。
markdown```mermaid
flowchart LR
issue1["課題1<br/>フォント未指定"] --> symptom1["豆腐文字"]
issue2["課題2<br/>エンコード欠落"] --> symptom2["濁点分離"]
issue3["課題3<br/>SVG スタイル不備"] --> symptom3["ツール間で表示差"]
issue4["課題4<br/>環境差異"] --> symptom4["CLI/Web で異なる結果"]
symptom1 --> problem["日本語が<br/>正しく見えない"]
symptom2 --> problem
symptom3 --> problem
symptom4 --> problem
```
図で理解できる要点
- 4 つの課題がそれぞれ異なる症状を引き起こす
- これらが複合的に絡み合い、「日本語が正しく見えない」という最終的な問題につながる
- 根本解決には、すべての課題を網羅的に対処する必要がある
解決策
日本語を Mermaid で正しく表示するには、フォント設定・エンコード指定・SVG 埋め込み設定の 3 つを適切に行うことが重要です。以下、それぞれの具体的な設定方法をご紹介しますね。
解決策 1:フォント設定を CSS で明示する
Mermaid が出力する SVG には、デフォルトで CSS スタイルが適用されます。そのため、HTML や Markdown を表示する際に、外部 CSS で日本語フォントを指定すれば解決できます。
HTML ファイルでの設定例
html<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Mermaid 日本語テスト</title>
<style>
/* Mermaid 全体に日本語フォントを適用 */
.mermaid {
font-family: 'Hiragino Sans',
'Hiragino Kaku Gothic ProN', 'Meiryo', sans-serif;
}
</style>
</head>
<body>
<div class="mermaid">
flowchart LR start["開始"] --> process["処理"] process
--> done["終了"]
</div>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
</body>
</html>
ポイント
<meta charset="UTF-8">でエンコードを明示.mermaidクラスに対してfont-familyで日本語フォントを列挙- ブラウザは左から順に利用可能なフォントを探すため、複数指定しておくと安心
Mermaid 設定ファイル(mermaid.config.json)での指定
CLI ツールを使う場合は、設定ファイルで fontFamily を指定できます。
json{
"theme": "default",
"themeVariables": {
"fontFamily": "Hiragino Sans, Hiragino Kaku Gothic ProN, Meiryo, sans-serif"
}
}
コマンド例
bashmmdc -i input.mmd -o output.svg -c mermaid.config.json
この設定により、CLI でも日本語フォントが適用されます。
解決策 2:エンコードを UTF-8 に統一する
Mermaid コードを含むファイル(.md、.html、.mmd など)は、すべて UTF-8 で保存しましょう。エディタによってはデフォルトが Shift_JIS や EUC-JP になっている場合があるため、保存時に確認が必要です。
VSCode での確認・変更方法
- 右下のステータスバーに表示されている文字コードをクリック
- 「エンコード付きで保存」を選択
- 「UTF-8」を選択して保存
HTML ファイルでの charset 指定
html<head>
<meta charset="UTF-8" />
</head>
注意点
<meta>タグは<head>内のなるべく早い位置に配置する- ファイル自体のエンコードと HTML 内の宣言が一致していないと、ブラウザが誤認識する
解決策 3:SVG 出力時にフォント情報を埋め込む
Mermaid CLI で SVG を生成する際、フォント情報が SVG 内部に含まれていないと、別のツールで開いた際に文字化けします。これを防ぐには、SVG 内に <style> タグでフォント指定を埋め込むか、後から編集します。
SVG への直接埋め込み例
svg<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200">
<style>
text {
font-family: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
}
</style>
<text x="50" y="50">開始</text>
</svg>
ポイント
- SVG 内の
<style>タグでtext要素にfont-familyを指定 - これにより、SVG 単体でも日本語が正しく表示される
CLI 出力後の自動編集スクリプト
CLI で生成した SVG に対して、Node.js スクリプトで <style> を挿入する方法もあります。
javascriptconst fs = require('fs');
// 生成された SVG を読み込む
const svgPath = './output.svg';
let svgContent = fs.readFileSync(svgPath, 'utf-8');
javascript// <style> タグを挿入する位置を探す
const styleTag = `
<style>
text {
font-family: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
}
</style>
`;
// <svg> タグの直後に挿入
svgContent = svgContent.replace(
/<svg([^>]*)>/,
`<svg$1>${styleTag}`
);
javascript// 上書き保存
fs.writeFileSync(svgPath, svgContent, 'utf-8');
console.log('SVG にフォント情報を追加しました');
実行例
bashnode add-font-to-svg.js
このスクリプトを CI/CD パイプラインに組み込めば、自動的にフォント情報が埋め込まれた SVG を生成できます。
解決策のまとめ表
| # | 解決策 | 対象環境 | 効果 |
|---|---|---|---|
| 1 | CSS でフォント指定 | HTML/Web | ブラウザでの表示を改善 |
| 2 | UTF-8 エンコード統一 | 全ファイル | 文字化け・濁点分離を防止 |
| 3 | SVG にフォント情報埋め込み | CLI 生成 SVG | ツール間での表示崩れを防止 |
下図は、解決策を適用した後のデータフローを示したものです。
mermaidflowchart TD
code["Mermaid コード<br/>(UTF-8)"] --> config["設定ファイル<br/>フォント指定"]
config --> render["レンダリング"]
render --> svg["SVG 出力"]
svg --> style_embed["<style> タグ<br/>埋め込み"]
style_embed --> result["日本語<br/>正常表示"]
上記の図を生成するコードは以下の通りです。
markdown```mermaid
flowchart TD
code["Mermaid コード<br/>(UTF-8)"] --> config["設定ファイル<br/>フォント指定"]
config --> render["レンダリング"]
render --> svg["SVG 出力"]
svg --> style_embed["<style> タグ<br/>埋め込み"]
style_embed --> result["日本語<br/>正常表示"]
```
図で理解できる要点
- UTF-8 エンコードのコードから始まり、設定ファイルでフォント指定を行う
- レンダリング後に生成される SVG に
<style>タグを埋め込むことで、最終的に日本語が正常表示される - この一連の流れを押さえることで、環境に依存しない安定した日本語表示が実現できる
具体例
ここでは、実際のプロジェクトで Mermaid の日本語表示を実現する手順を、段階的にご紹介します。フローチャートとシーケンス図の 2 つの例を通じて、設定のポイントを確認していきましょう。
例 1:フローチャートでの日本語表示
ステップ 1:Mermaid コードを UTF-8 で作成
markdown```mermaid
flowchart TD
start["開始"] --> input["ユーザー入力"]
input --> validate["バリデーション"]
validate -->|OK| save["データ保存"]
validate -->|NG| error["エラー表示"]
save --> done["終了"]
error --> done
```
このコードを flowchart.md として保存します。エディタで UTF-8 エンコードになっていることを確認してください。
ステップ 2:HTML ファイルに埋め込む
html<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>フローチャート例</title>
</head>
</html>
html <style>
/* Mermaid 全体のフォント設定 */
.mermaid {
font-family: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
font-size: 14px;
}
</style>
</head>
html<body>
<h1>日本語フローチャート</h1>
<div class="mermaid">
flowchart TD start["開始"] --> input["ユーザー入力"]
input --> validate["バリデーション"] validate -->|OK|
save["データ保存"] validate -->|NG| error["エラー表示"]
save --> done["終了"] error --> done
</div>
</body>
html <script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
</body>
</html>
実行結果
ブラウザで開くと、日本語が正しく表示されたフローチャートが確認できます。
ステップ 3:CLI で SVG 出力
CLI を使う場合は、設定ファイルを用意します。
json{
"theme": "default",
"themeVariables": {
"fontFamily": "Hiragino Sans, Hiragino Kaku Gothic ProN, Meiryo, sans-serif"
}
}
このファイルを mermaid.config.json として保存し、以下のコマンドで SVG を生成します。
bashyarn add -D @mermaid-js/mermaid-cli
yarn run mmdc -i flowchart.md -o flowchart.svg -c mermaid.config.json
生成された SVG の確認
svg<svg xmlns="http://www.w3.org/2000/svg" ...>
<style>
text {
font-family: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
}
</style>
<!-- 以下、グラフ要素 -->
</svg>
このように、SVG 内にフォント情報が埋め込まれていれば、別のツールで開いても日本語が崩れません。
例 2:シーケンス図での日本語表示
ステップ 1:Mermaid コードを作成
markdown```mermaid
sequenceDiagram
participant user as ユーザー
participant app as アプリ
participant db as データベース
user->>app: ログイン要求
app->>db: 認証情報確認
db-->>app: 認証OK
app-->>user: ログイン成功
```
このコードを sequence.md として UTF-8 で保存します。
ステップ 2:HTML に埋め込む
html<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>シーケンス図例</title>
</head>
</html>
html <style>
.mermaid {
font-family: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
font-size: 14px;
}
</style>
</head>
html<body>
<h1>日本語シーケンス図</h1>
<div class="mermaid">
sequenceDiagram participant user as ユーザー participant
app as アプリ participant db as データベース user->>app:
ログイン要求 app->>db: 認証情報確認 db-->>app: 認証OK
app-->>user: ログイン成功
</div>
</body>
html <script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
</body>
</html>
実行結果
ブラウザで開くと、日本語の参加者名やメッセージが正しく表示されます。
ステップ 3:CLI で PNG 出力
PNG 形式で出力する場合も、設定ファイルを使います。
bashyarn run mmdc -i sequence.md -o sequence.png -c mermaid.config.json
注意点
PNG 出力には Puppeteer が使われるため、初回実行時に Chromium がダウンロードされます。フォント設定が反映されていれば、PNG でも日本語が正しく表示されます。
トラブルシューティング:それでも文字化けする場合
| # | 症状 | 確認ポイント | 対処法 |
|---|---|---|---|
| 1 | 一部の文字だけ豆腐になる | システムに該当フォントがインストール済みか | フォントを追加インストール |
| 2 | CLI では正常だが Web で崩れる | HTML の <meta charset> が正しいか | UTF-8 を明示し、ファイルも UTF-8 で保存 |
| 3 | SVG を Inkscape で開くと崩れる | SVG 内の <style> タグがあるか | 手動または自動スクリプトで追加 |
| 4 | CI/CD で文字化けする | 実行環境に日本語フォントがあるか | Docker イメージにフォントを追加 |
Docker 環境でのフォント追加例
CI/CD で Mermaid CLI を実行する際、コンテナ内に日本語フォントがないと文字化けします。以下は Dockerfile の例です。
dockerfileFROM node:18
# 日本語フォントをインストール
RUN apt-get update && \
apt-get install -y fonts-noto-cjk && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install
COPY . .
CMD ["yarn", "run", "mmdc", "-i", "input.md", "-o", "output.svg", "-c", "mermaid.config.json"]
ポイント
fonts-noto-cjkは Google が提供する日本語・中国語・韓国語対応のフリーフォント- コンテナ内にインストールしておくことで、CLI 実行時に日本語が正しくレンダリングされる
下図は、具体例で紹介した設定の適用フローを示したものです。
mermaidflowchart LR
md["Markdown ファイル<br/>(UTF-8)"] --> html["HTML 埋め込み<br/>CSS フォント指定"]
md --> cli["CLI 実行<br/>config.json"]
html --> browser["ブラウザ表示<br/>正常"]
cli --> svg_png["SVG/PNG 出力<br/>正常"]
svg_png --> docker["Docker 環境<br/>フォント追加"]
docker --> ci_cd["CI/CD で自動生成<br/>正常"]
上記の図を生成するコードは以下の通りです。
markdown```mermaid
flowchart LR
md["Markdown ファイル<br/>(UTF-8)"] --> html["HTML 埋め込み<br/>CSS フォント指定"]
md --> cli["CLI 実行<br/>config.json"]
html --> browser["ブラウザ表示<br/>正常"]
cli --> svg_png["SVG/PNG 出力<br/>正常"]
svg_png --> docker["Docker 環境<br/>フォント追加"]
docker --> ci_cd["CI/CD で自動生成<br/>正常"]
```
図で理解できる要点
- Markdown ファイルから HTML 埋め込みと CLI 実行の 2 つのルートがある
- どちらも UTF-8 エンコードとフォント指定を行うことで、正常な表示を実現
- Docker 環境では追加でフォントインストールが必要だが、それを行えば CI/CD でも問題なく動作する
まとめ
Mermaid で日本語が潰れる問題は、フォント・エンコード・SVG 設定の 3 つを適切に行うことで解決できます。本記事でご紹介した内容を振り返りましょう。
重要ポイント
| # | ポイント | 効果 |
|---|---|---|
| 1 | CSS で日本語フォントを明示 | ブラウザでの文字化けを防止 |
| 2 | UTF-8 エンコードに統一 | 濁点分離や半角カタカナ化を防止 |
| 3 | SVG に <style> タグを埋め込む | ツール間での表示崩れを防止 |
| 4 | CLI 設定ファイルで fontFamily 指定 | CLI 出力でも日本語を正しく表示 |
| 5 | Docker 環境にフォントを追加 | CI/CD での自動生成でも正常動作 |
推奨設定のチェックリスト
以下のチェックリストを参考に、プロジェクトの設定を見直してみてください。
- Mermaid コードを含むファイルを UTF-8 で保存している
- HTML ファイルに
<meta charset="UTF-8">を記載している - CSS または Mermaid 設定で日本語フォントを指定している
- CLI を使う場合は
mermaid.config.jsonを用意している - SVG 出力後に
<style>タグでフォント情報を埋め込んでいる - Docker や CI/CD 環境に日本語フォントがインストールされている
今後の展望
Mermaid は活発に開発が続いており、将来的にはデフォルトで多言語対応が強化される可能性もあります。しかし現時点では、本記事でご紹介した設定を行うことが最も確実な方法です。
日本語を含む図を美しく描けるようになれば、ドキュメントの可読性が大きく向上しますね。ぜひプロジェクトに取り入れて、より伝わりやすい技術資料を作成してみてください。
関連リンク
articleMermaid で日本語が潰れる問題を解決:フォント・エンコード・SVG 設定の勘所
articleMermaid でデータ基盤のラインジを図解:ETL/DAG/品質チェックの全体像
articleMermaid 矢印・接続子チートシート:線種・方向・注釈の一覧早見
articleMermaid 図面の命名規約:ノード ID・エッジ記法・クラス名の統一ガイド
articleMermaid flowchart 実践 100 本ノック:subgraph/linkStyle/classDef の活用術
articleMermaid を VS Code で快適に:拡張機能・ライブプレビュー・ショートカット設定
articlePrisma 読み書き分離設計:読み取りレプリカ/プロキシ/整合性モデルを整理
articleMermaid で日本語が潰れる問題を解決:フォント・エンコード・SVG 設定の勘所
articlePinia 2025 アップデート総まとめ:非互換ポイントと安全な移行チェックリスト
articleMCP サーバー 実装比較:Node.js/Python/Rust の速度・DX・コストをベンチマーク検証
articleLodash のツリーシェイクが効かない問題を解決:import 形態とバンドラ設定
articleOllama のインストール完全ガイド:macOS/Linux/Windows(WSL)対応手順
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来