なぜ移行したか

手書き HTML ブログの index.html 競合から逃げる では「記事 30 本 / 月 2 回コンフリクト / 追加忘れ 2 回目」のどれかで踏み切る、と書きました。

2026 年 6 月時点で次が重なり、踏み切りました。

延期の判断は当時正しかった一方、ルール追加だけではコンフリクトは消えない段階に入っていました。

採用した構成

項目内容
SSGAstro 6 + MDX
記事ソース60d.dev/astro-blog/src/content/blog/*.mdx
一覧Content Collections の getCollection() で日付降順自動生成
AI 開示AiDisclosureBadge.astro + 一覧 AiNotice.astro
本番配信Netlify(publish = "." の静的配信。生成 HTML を blog/ に commit)
文体 lintnpm run lint:style(MDX ソース)+ textlint

記事の slug は移行前と同一のため、旧 URL の 301 は不要でした。

やったこと

  1. Phase 0 — Astro スパイク(パイロット 2 本で build / preview 確認)
  2. Phase 1 — 公開 HTML から MDX へ一括移行(scripts/migrate-from-html.mjs、30 記事)
  3. 統合 — 別リポジトリだったスパイクを 60d.dev/astro-blog/ に組み込み
  4. 品質 — コードブロックへの言語タグ付与(Shiki ハイライト)、OGP 整備、NG 語彙修正
  5. 本番scripts/build-blog.shblog/ を生成し、Netlify へ反映(2026-06-06)

astro-blog/ の MDX ソースは netlify.toml/astro-blog/* を 404 にし、公開物は /blog/ 配下のみです。

移行後の執筆フロー

# 1. MDX を書く
#    astro-blog/src/content/blog/<slug>.mdx

# 2. 生成 HTML を blog/ に反映
bash scripts/build-blog.sh

# 3. MDX と blog/ の生成物を同一 PR に含めて main へ

一覧への手動追記は不要です。blog/index.html への行追加コンフリクトは構造的に起きなくなりました。

移行で分かったこと

まとめ