• #mermaid
  • #svg
  • #beautiful-mermaid
  • #nuxt-content
  • #html-to-markdown
  • #タイムゾーン
開発blog-platformメモ

やったこと

HTMLファイル(logic-flow-v2.html)を、Nuxt Content向けのMarkdown記事に変換した。「お金儲けしたいんだけど、何の仕事が一番いい?」という問いに対して、3冊のマネー本から回答ロジックを組み立てた記事で、複数のMermaid図とインラインSVGが混在していた。

インラインSVG(幸福の方程式など)はそのままMarkdownに貼れたが、Mermaid図は一筋縄ではいかなかった。

Mermaidコードブロックの問題

最初はMermaidのコードブロックをそのまま記事に埋め込んだ。

```mermaid
graph TD
  A[ESBIクワドラント] --> B[E: 従業員]
  ...

ブラウザで開くと、ノードが重なり合い、ラベルのテキストが枠からはみ出していた。Mermaidのランタイムレンダリングはフォントやビューポートに引きずられるので、自分の環境では整って見えても別環境で崩れる。

## beautiful-mermaidでSVG生成に切り替え

[beautiful-mermaid](https://www.npmjs.com/package/beautiful-mermaid) パッケージを使い、Mermaid定義から静的SVGを生成する方向に切り替えた。

一時的なNode.jsスクリプトを作成し、4つのMermaid図をSVGファイルとして出力した。

```javascript
// generate-svgs.mjs(一時スクリプト、生成後に削除)
import { renderMermaid } from "beautiful-mermaid";

const diagrams = {
  "esbi-quadrant.svg": `graph TD ...`,
  "happiness-components.svg": `graph LR ...`,
  "phase-overview.svg": `graph TD ...`,
  "stock-acquisition.svg": `flowchart LR ...`,
};

for (const [filename, definition] of Object.entries(diagrams)) {
  const svg = await renderMermaid(definition);
  writeFileSync(filename, svg);
}

4つのSVGが生成され、Markdownからは ![alt](./esbi-quadrant.svg) で参照する形にした。スクリプトは役目を終えたので削除した。

生成したSVG

ファイル名内容
esbi-quadrant.svgESBIクワドラント(従業員・自営業・ビジネスオーナー・投資家)
happiness-components.svg幸福の構成要素(健康・人間関係・自由・余裕)
phase-overview.svg記事全体のフェーズ概要図
stock-acquisition.svg株式取得のフロー

Nuxt Contentスキーマのenum修正

記事をビルドしたら、frontmatterのバリデーションで止まった。content.config.tscategory enumに "commentary" が存在せず、project_name enumに "book-notes" もなかった。

最終的に category: "personal"project_name: "personal" に変更して解決した。enumに存在しない値を使うとビルド時にエラーが出るので、既存の値を確認してから設定する必要がある。

タイムゾーン問題の発見と修正

Chrome DevToolsでページを開いたら、ブログ一覧ページ(/blog)に今日の記事が出てこなかった。記事の個別ページは表示されるのに、一覧だけ空振りしている。

原因を掘ると、publishedAt の日付比較でタイムゾーンのずれが出ていた。publishedAt: "2026-02-28" は UTC の 2026-02-28T00:00:00Z として解釈されるが、JST(UTC+9)では 2026-02-28T09:00:00 になる。フィルタ条件が publishedAt <= now だったため、UTC基準で「まだ未来の記事」と判定されて一覧から除外されていた。

日付比較のロジックを修正し、タイムゾーンに依存しない比較に変更した。

学んだこと

  • Mermaidのランタイムレンダリングは環境差が出る。SSGサイトでは静的SVGに変換しておくと、どの環境でも同じ見た目を保てる
  • beautiful-mermaidはCLI不要で、Node.jsスクリプトから直接SVGを吐ける。スクリプトを書いて4つのSVGを生成し、スクリプトを消す。この「書いて・生成して・捨てる」の流れが5分で終わった
  • publishedAt の日付文字列はUTCとして解釈される。JSTで当日の記事を書いても、UTCではまだ「明日」になっていることがある。一覧から消える現象を目の前で見て初めて腑に落ちた