关于 content-collection
面向 Astro 项目的结构化内容管理技能,适用于博客、文档等集合的创建与重构。涵盖当前 Content Layer API、内容查询、路由渲染和旧版迁移。
主要功能
- 01定义带 schema 和 loader 的集合
- 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 内容集合
在 Astro 中创建或重构结构化内容时,请使用此技能,例如博客、文档、更新日志、案例研究、团队数据或其他由架构驱动的内容。
如果有 astro-best-practices,请同时应用它,以遵循命名、无障碍和性能方面的默认做法。
工作流
1. 确定集合是在构建时还是实时加载
大多数内容网站都应在 src/content.config.* 中使用构建时集合。只有当数据确实需要在请求时保持最新,才应在 src/live.config.* 中使用实时集合。
编码前,请确定:
- 有哪些集合
- 哪些字段为必填项
- 哪些关系需要引用
- 是否应验证图片等资源
架构应反映网站查询内容的方式,而不仅仅是当前 frontmatter 的样子。
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(...) - 对 frontmatter 日期使用
z.coerce.date() - 对关系使用
reference('collection-name') - 需要验证图片时使用
schema: ({ image }) => ...
3. 保持集合结构与当前版本一致
对于 Astro 6 及更高版本:
- 使用
src/content.config.*,而不是src/content/config.* - 使用
entry.id作为 URL 和查询中的 slug 类标识符 - 仅在确实需要源路径时使用
entry.filePath - 使用
getEntry(),而不是旧版的getEntryBySlug()或getDataEntryById()
优先采用稳定的文件夹结构和可预测的 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 工作流 - 修复架构不匹配问题,不要放宽类型
- 至少验证每个集合中的一个真实条目
- 留意有关缺少 loader、旧版配置路径或已弃用导入的警告
迁移指南
从旧版内容模式迁移时:
- 将
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。
评论
支持 Markdown