Astro 5 (beta in September 2024) brings the Content Layer: a unified API to read content from any source (Markdown files, Sanity, Notion, REST APIs) as if they were typed collections.
The problem it solves
Before Astro 5, content collections only worked on local files. To integrate Sanity or an external API you wrote ad-hoc code with no type safety and no getCollection(). Result: mixed projects where half the content was in .md and the other half in scattered fetches.
How it works
Define a loader per source, and Astro materialises it into a consistent collection.
// src/content/config.ts
const articles = defineCollection({
loader: sanityLoader({ query: '*[_type == "article"]' }),
schema: z.object({ title: z.string(), slug: z.string() }),
});
From here on getCollection('articles') returns typed data at build time.
Existing loaders
- Markdown / MDX files (built-in)
- Sanity (community)
- Contentful (community)
- Notion (community)
- Custom REST/GraphQL (10 lines of code)
When we care
For projects where content lives in multiple places (main CMS + repo + internal database), the Content Layer cuts 200 lines of glue code and gives one read surface. For pure Markdown sites the gain is marginal; for real editorial projects it is large.
What to wait for
The API is still beta in 5.0. 5.1 should stabilise it with incremental rebuild improvements. For projects starting now, adoption is worth it — the design is solid.