公開
Astro の Content Collections で型安全なブログを作る
Content Collections とは
Astro の Content Collections は、Markdown / MDX ファイルを型安全に管理する仕組みです。Zod スキーマでフロントマターを検証し、TypeScript の型推論が効くようになります。
Content Collections を使うと、記事データの取得時に自動で型が付くため、タイポや型の不一致をビルド時に検出できます。
セットアップ
まず src/content.config.ts でコレクションを定義します。
import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders";
const blog = defineCollection({
loader: glob({ pattern: "**/*.mdx", base: "./src/content/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
date: z.date(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
ポイントは z.boolean().default(false) のようにデフォルト値を設定できること。フロントマターに draft を書かなければ自動的に false になります。
記事の取得
コレクションから記事を取得するユーティリティを作ります。
import { getCollection } from "astro:content";
export async function getPublishedPosts() {
const posts = await getCollection("blog", ({ data }) => {
return data.draft !== true;
});
return posts.sort(
(a, b) => b.data.date.getTime() - a.data.date.getTime()
);
}
この関数は以下の2つを行っています:
draft: trueの記事を除外する- 日付の降順(新しい順)でソートする
ページでの使用
動的ルーティングで各記事のページを生成します。
---
import { getCollection, render } from "astro:content";
export async function getStaticPaths() {
const posts = await getCollection("blog");
return posts.map((post) => ({
params: { slug: post.id },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await render(post);
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>
post.data.title には自動的に string 型が付きます。スキーマに存在しないプロパティにアクセスしようとすると、TypeScript がエラーを出してくれます。
glob パターンの活用
月別フォルダで記事を管理する場合、**/*.mdx パターンが便利です。
src/content/blog/
├── 2026-01/
│ └── first-post.mdx
├── 2026-02/
│ └── second-post.mdx
└── 2026-03/
└── third-post.mdx
フォルダ構造に関係なく、すべての .mdx ファイルが再帰的に収集されます。entry.id にはフォルダパスが含まれる(2026-03/third-post)ので、スラッグ生成時にフォルダ部分を除去する処理が必要です。
export function getSlug(id: string): string {
const parts = id.split("/");
return parts[parts.length - 1];
}
まとめ
Content Collections を使うメリットは3つです:
- 型安全: フロントマターの型が自動推論される
- バリデーション: ビルド時にスキーマ違反を検出できる
- 柔軟性: glob パターンで自由なファイル構成に対応できる
個人ブログのような小規模なサイトでも、型安全な記事管理は開発体験を大きく改善してくれます。