Astro の Content Collections で記事データに型を付ける

frontmatter の書き間違いをビルド時に検出できるように、Content Collections と Zod のスキーマで記事データを定義する方法を紹介します。

Hiraoku1 分で読めます

図形付きの原稿カードを、対応する青緑色のフォルダーに整理する黒ペン風イラスト

Markdown で記事を書いていると、frontmatter の日付の形式を間違えたり、必須の項目を書き忘れたりしがちです。Astro の Content Collections を使うと、こうしたミスをビルド時に見つけられます。

コレクションを定義する

src/content.config.ts にコレクションとスキーマを書きます。

import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';

const blog = defineCollection({
  loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    tags: z.array(z.string()).default([]),
  }),
});

export const collections = { blog };

z.coerce.date() を使うと、2026-10-06 のような文字列を Date に変換してくれます。

Markdownのfrontmatterをloaderとschemaで検証し、型の付いたコレクションをページで使う流れ

必須項目の不足や変換できない日付は、検証の段階で検出されます。図は記事データが表示へ届く経路を示しています。

記事を取得する

ページ側では getCollection で記事を取り出します。戻り値にはスキーマから推論された型が付くので、post.data.title などを補完付きで扱えます。

import { getCollection } from 'astro:content';

const posts = (await getCollection('blog', ({ data }) => !data.draft)).sort(
  (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
);

まとめ

  • スキーマを書いておけば、frontmatter のミスはビルドが教えてくれる
  • 型が付くので、テンプレート側のタイポも防げる
  • 下書きフラグのような運用ルールもスキーマで表現できる

ほかの記事も読む