T-CREATOR

Mermaid で日本語が潰れる問題を解決:フォント・エンコード・SVG 設定の勘所

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エンコード指定の欠落半角カタカナ化・濁点分離
3SVG 埋め込み時のスタイル不備ブラウザやツールでの表示崩れ
4レンダリング環境の差異CLI と Web で異なる結果

これらの課題は、1 つだけ解決しても他の要素が原因で問題が残ることが多く、総合的な対処が必要です。

1. 日本語フォントが未指定

Mermaid のデフォルト設定は欧文フォント(例:Arialsans-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 での確認・変更方法

  1. 右下のステータスバーに表示されている文字コードをクリック
  2. 「エンコード付きで保存」を選択
  3. 「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 を生成できます。

解決策のまとめ表

#解決策対象環境効果
1CSS でフォント指定HTML/Webブラウザでの表示を改善
2UTF-8 エンコード統一全ファイル文字化け・濁点分離を防止
3SVG にフォント情報埋め込み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一部の文字だけ豆腐になるシステムに該当フォントがインストール済みかフォントを追加インストール
2CLI では正常だが Web で崩れるHTML の <meta charset> が正しいかUTF-8 を明示し、ファイルも UTF-8 で保存
3SVG を Inkscape で開くと崩れるSVG 内の <style> タグがあるか手動または自動スクリプトで追加
4CI/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 つを適切に行うことで解決できます。本記事でご紹介した内容を振り返りましょう。

重要ポイント

#ポイント効果
1CSS で日本語フォントを明示ブラウザでの文字化けを防止
2UTF-8 エンコードに統一濁点分離や半角カタカナ化を防止
3SVG に <style> タグを埋め込むツール間での表示崩れを防止
4CLI 設定ファイルで fontFamily 指定CLI 出力でも日本語を正しく表示
5Docker 環境にフォントを追加CI/CD での自動生成でも正常動作

推奨設定のチェックリスト

以下のチェックリストを参考に、プロジェクトの設定を見直してみてください。

  • Mermaid コードを含むファイルを UTF-8 で保存している
  • HTML ファイルに <meta charset="UTF-8"> を記載している
  • CSS または Mermaid 設定で日本語フォントを指定している
  • CLI を使う場合は mermaid.config.json を用意している
  • SVG 出力後に <style> タグでフォント情報を埋め込んでいる
  • Docker や CI/CD 環境に日本語フォントがインストールされている

今後の展望

Mermaid は活発に開発が続いており、将来的にはデフォルトで多言語対応が強化される可能性もあります。しかし現時点では、本記事でご紹介した設定を行うことが最も確実な方法です。

日本語を含む図を美しく描けるようになれば、ドキュメントの可読性が大きく向上しますね。ぜひプロジェクトに取り入れて、より伝わりやすい技術資料を作成してみてください。

関連リンク