Islands First
Content collections
Lesson 4 of 5
What you'll learn
- Define a content collection with a frontmatter schema
- Understand how
getCollectionreturns validated, typed entries - See validation reject malformed frontmatter at build time
A content collection is a folder of markdown (or MDX) files plus a schema that describes their frontmatter. You declare the shape once in src/content/config.ts, and Astro validates every file against it — turning loose YAML into typed, trustworthy data.
import { defineCollection, z } from "astro:content";
const blog = defineCollection({
schema: z.object({
title: z.string(),
pubDate: z.date(),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
Now each .md file in src/content/blog must carry a title and a pubDate, or the build fails with a clear error. You read the entries with getCollection:
import { getCollection } from "astro:content";
const posts = await getCollection("blog");
// posts: { data: { title, pubDate, draft }, slug, body }[]
The schema is a gate, not a suggestion
Because validation runs at build time, a typo in frontmatter can never reach production. A missing required field or a wrong type stops the build — you fix the data, not chase a runtime crash later.
Defaults fill the gaps
Use .default(...) for optional-with-a-fallback fields like draft. Entries that omit the field still validate and come back with the default already applied, so your templates never special-case undefined.
A schema is just a set of field rules applied to each entry. The challenge models that validator and reports which entries pass and why the others fail.
Run it. Each schema field has a type and a required flag; the validator checks every entry and reports pass/fail with the reason.
Next: wrapping every page in shared chrome with layouts.
Sign in to save your progress across devices.