content-collection について
ブログやドキュメントなど、Astro プロジェクトの構造化コンテンツを作成・再構成するスキルです。現行の Content Layer API、クエリ、ルートでの描画、旧形式からの移行を扱います。
主な機能
- 01スキーマとローダーを使ったコレクション定義
- 02フィールドと参照の検証
- 03目的に応じたエントリー検索
- 04エントリーとルート・描画の連携
- 05旧コンテンツ API からの移行
活用シーン
- 01ブログやドキュメント用のコレクション構築
- 02コンテンツ項目や画像アセットの検証
- 03旧 Astro プロジェクトを現行 API に移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ incluud/ astro-agent-skills --skill content-collectionインストール後、Claude Code で/content-collectionを入力して読み込まれたか確認します。
詳細
Astro Content Collections
ブログ、ドキュメント、変更履歴、導入事例、チームデータなど、スキーマに基づくコンテンツを Astro で作成またはリファクタリングする際は、このスキルを使用してください。
astro-best-practices を利用できる場合は、命名、アクセシビリティ、パフォーマンスのデフォルト設定に関して、このスキルと併せて適用してください。
ワークフロー
1. コレクションをビルド時にするか、ライブにするか決める
ほとんどのコンテンツサイトでは、src/content.config.* にビルド時コレクションを使用します。リクエスト時の鮮度が本当に必要なデータに限り、src/live.config.* のライブコレクションを使用してください。
コーディングの前に、以下を決めてください。
- どのコレクションが存在するか
- どのフィールドが必須か
- どの関連に参照が必要か
- 画像などのアセットを検証するかどうか
現在のフロントマターの形式だけでなく、サイトでコンテンツをどのようにクエリするかを反映したスキーマを優先してください。
2. src/content.config.* でコレクションを定義する
現行の Content Layer API を使用してください。ビルド時コレクションの場合は、以下のようにします。
src/content.config.ts(または.js/.mjs)で定義する- すべてのコレクションに
loaderを指定する astro/zodからzをインポートするtype: 'content'やtype: 'data'は使用しない
例:
import { defineCollection, reference } 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: ({ image }) => z.object({
title: z.string(),
description: z.string(),
publishDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
author: reference('authors'),
cover: image().optional(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
}),
})
const authors = defineCollection({
loader: glob({ base: './src/data/authors', pattern: '**/*.json' }),
schema: z.object({
name: z.string(),
email: z.email().optional(),
avatar: z.url().optional(),
}),
})
export const collections = { blog, authors }
便利なパターン:
- ローカルエントリーのフォルダーには
glob() - 単一の JSON ファイルやその他のデータファイルには
file() - 値を制限するには
z.enum(...) - フロントマターの日付には
z.coerce.date() - 関連には
reference('collection-name') - 画像の検証が必要な場合は
schema: ({ image }) => ...
3. コレクションの構成を最新に保つ
Astro 6 以降では、以下を使用してください。
src/content/config.*ではなくsrc/content.config.*を使用する- URL やクエリでスラッグに相当する識別子として
entry.idを使用する - ソースパスが本当に必要な場合に限り、
entry.filePathを使用する - 旧式の
getEntryBySlug()やgetDataEntryById()の代わりにgetEntry()を使用する
安定したフォルダー構成と予測可能な ID を優先してください。論理的にひとつのコレクションであるコンテンツを、ルートフォルダーに分散させないでください。
4. 意図に沿ってクエリする
用途に合ったコンテンツ API を使用してください。
- リストには
getCollection() - 既知の単一エントリーには
getEntry() - 参照の配列には
getEntries() - 下書きと公開済みのコンテンツを分けるにはコレクションフィルター
例:
---
import { getCollection } from 'astro:content'
const posts = await getCollection('blog', ({ data }) => !data.draft)
---
エントリーをレンダリングする際は、ルートの生成とコンテンツのレンダリングを十分に分離し、それぞれを理解しやすい状態に保ってください。
5. 現行の API でルートとレンダリングを接続する
動的ルートでは、以下のようにします。
- コレクション ID からパスを構築する
- エントリーを props で適切に渡す
render(entry)でコンテンツをレンダリングする
例:
---
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>
6. 同期と検証を行う
コレクションを変更した後は、以下を行ってください。
npx astro syncまたはリポジトリで通常使用する Astro のワークフローを実行する- 型を弱めるのではなく、スキーマの不一致を修正する
- 各コレクションで少なくともひとつの実際のエントリーを検証する
- ローダーの不足、旧式の設定パス、非推奨のインポートに関する警告を確認する
移行ガイド
古いコンテンツパターンから移行する場合:
src/content/config.tsをsrc/content.config.tsに移動する- すべてのコレクションに
loaderを追加する type: 'content'やtype: 'data'を削除するimport { defineCollection, z } from 'astro:content'をimport { defineCollection } from 'astro:content'とimport { z } from 'astro/zod'に置き換えるpost.slugをpost.idに置き換えるentry.render()をrender(entry)に置き換えるgetEntryBySlug()とgetDataEntryById()をgetEntry()に置き換える
同時に Astro のバージョンをまたいで移行する場合は、確定する前に、現行の公式 Astro ドキュメントでバージョン依存のコンテンツ API を確認してください。