Astro Content Collections でブログを構築する|型安全な Frontmatter と Zod スキーマ設計

Astro ブログ フロントエンド TypeScript Zod
結論:30秒で Astro Content Collections を理解する
  • スキーマ定義: src/content/config.ts に Zod スキーマを作成
  • メリット: タイポや記述漏れをビルド時に自動検知
  • 取得 API: const posts = await getCollection('blog');

1. スキーマの定義 (src/content/config.ts)

import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    tags: z.array(z.string()).default([]),
  }),
});

export const collections = { blog };

2. 記事の記述 (src/content/blog/hello.mdx)

---
title: はじめての記事
description: テスト用の記事です。
pubDate: 2025-02-15
tags: ["Astro"]
---

本実証の本文です。

3. 一覧・詳細ページの実装

---
// src/pages/blog/index.astro
import { getCollection } from 'astro:content';

const entries = await getCollection('blog');
const sorted = entries.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());
---

<ul>
  {sorted.map((entry) => (
    <li>
      <a href={`/blog/${entry.slug}/`}>{entry.data.title}</a>
    </li>
  ))}
</ul>

4. 注意点(ハマりどころ)

  1. Frontmatter の型チェックエラー
    • 日付プロパティに pubDate: 2025-02-15 を指定し z.date() のままスキーマ定義すると、文字列判定されてビルドエラーになります。必ず z.coerce.date() を使用してください。