各SSGでのfrontmatterのまとめ

はじめに

最近、HugoからAstroへブログを移行しようとしたところ、frontmatterの互換性のなさに苦しんだ。特に、Hugoでは一般的なdateフィールドが、Astroのブログテンプレートでは認識されず、代わりにpubDateを使う必要があるという仕様は、公式にも明示されておらず罠のようだった。

将来的にSSGを乗り換える人が増えてくる中で、こうした違いは深刻な移行障壁となるだろうと思い、この記事を記すことにした。

共通部分

  • Markdownのfrontmatterは公式仕様ではなく、SSGやCMSが独自に解釈して使っている。
  • 通常、YAML形式(--- で囲む)で記述されるが、HugoではTOMLやJSONにも対応。
  • よく使われる共通フィールド:title, description, tags, draft, slug

Hugo

  • 使用できるフォーマット:TOML, YAML, JSON, org
  • 主なフィールド:
    • title: ページのタイトル
    • date: 作成日(公開日)
    • tags: タグ
    • description: ページの説明文
    • draft: 下書きフラグ(trueにするとビルド対象外)
    • aliases: 追加のURL。ここに記載したURLからもアクセス可能になる。
    • lastmod: 最終更新日
    • slug: URLパスの最後のセグメントを上書きする。
  • 参考:

Astro

  • 使用できる形式:YAML(.md / .mdx の先頭に記述)
  • 主なフィールド:
    • title: ページのタイトル
    • description: ページの説明文
    • pubDate: 公開日(※dateではなくpubDateにしないとテンプレートで無視されることがある)
    • tags: タグ(例:["astro", "blog"]
    • draft: 下書きフラグ(trueで非公開、ただし自動除外にはフィルターが必要)
    • slug: 任意のスラッグ(ファイル名とは別にURLパスを指定可能)
    • layout: 使用するレイアウトファイルのパス(例:../layouts/BlogLayout.astro
    • heroImage: 記事のトップに表示される画像(任意)
    • author: 著者名(任意)

pubDateの罠について

Astroではブログテンプレート(例:astro-blog, AstroPaperなど)で記事を日付順に並べる処理や日付の表示が行われているが、そこで参照されているのはdateではなくpubDateだ。

そのため、Hugoから移行してきたMarkdown資産でdateしか指定していない場合、Astroでは日付が表示されなかったり、並び順に影響が出たりする。

この仕様はAstro公式ドキュメントには明記されておらず、テンプレートの実装依存しだいだ。 移行時には必ずdatepubDateに変換するスクリプトまたは手動対応が必要になる。

ちなみにAstroでは、公式サイトを見ても、どのようなfrontmatterが使えるかは明記されていない。せいぜい、まともに解説があったのはstarlightというテーマでの解説のみ。今後、各SSG間の移行性や互換性が問題になりそうだ。