Astro 内容集合详解
深入理解 Astro 的 Content Collections API,如何定义 schema、查询内容、生成动态路由。
· 3 分钟阅读 技术
Astro 的 Content Collections 是管理 Markdown/MDX 内容的官方方案。这篇文章记录一下核心用法。
为什么用 Content Collections
在 Astro 2.0 之前,内容文件散落在各个目录里,靠 glob() 查询。问题很明显:
- 没有类型安全
- 没有数据校验
- 没有自动补全
Content Collections 解决了这些问题。
定义 Schema
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string().optional(),
pubDate: z.coerce.date(),
category: z.enum(['tech', 'life']),
tags: z.array(z.string()).default([]),
featured: z.boolean().default(false),
}),
});
export const collections = { blog };
关键点:
z.coerce.date()— 自动把 YAML 里的日期字符串转成 Date 对象z.enum()— 限制可选值,写错会报错.default()— 设置默认值,frontmatter 里不写也行
查询内容
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
const sorted = posts.sort((a, b) =>
b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
);
动态路由
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.id },
props: { post },
}));
}
渲染内容
import { render } from 'astro:content';
const { Content } = await render(post);
Content 是一个 Astro 组件,直接在模板里用就行。
总结
Content Collections 的核心价值是类型安全 + 数据校验。对于博客这种内容驱动的站点,几乎是必选项。