Astro’s Content Collections API provides type-safe content management for your Markdown, MDX, and JSON files.
Importing Functions
import {
defineCollection,
getCollection,
getEntry,
getEntries,
reference
} from 'astro:content';
defineCollection
Define a content collection schema in your src/content/config.ts file.
defineCollection(config: CollectionConfig): CollectionConfig
Collection configuration object.The type of collection. Use 'content' for Markdown/MDX files with frontmatter, or 'data' for JSON/YAML data files.Default: 'content'
A Zod schema to validate frontmatter or data.import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.date(),
tags: z.array(z.string()).optional(),
}),
});
A loader function for loading collection data. Used with the Content Layer API.import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/data/blog' }),
});
Example
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: z.string().optional(),
}),
});
const newsletter = defineCollection({
type: 'data',
schema: z.object({
title: z.string(),
date: z.date(),
}),
});
export const collections = { blog, newsletter };
getCollection
Retrieve all entries from a collection, optionally filtered.
getCollection(
collection: string,
filter?: (entry: CollectionEntry) => boolean
): Promise<CollectionEntry[]>
The name of the collection to query.
filter
(entry: CollectionEntry) => boolean
Optional filter function to select specific entries.const publishedPosts = await getCollection('blog', (entry) => {
return entry.data.draft !== true;
});
return
Promise<CollectionEntry[]>
An array of collection entries with the following properties:Unique identifier for the entry (filename without extension).
URL-friendly slug for the entry.
The name of the collection this entry belongs to.
Parsed and validated frontmatter data matching your schema.
Raw Markdown/MDX content (content collections only).
render
() => Promise<RenderResult>
Function to render the content (content collections only).
Example
// src/pages/blog/index.astro
import { getCollection } from 'astro:content';
// Get all blog posts
const allPosts = await getCollection('blog');
// Get only published posts
const publishedPosts = await getCollection('blog', ({ data }) => {
return data.draft !== true;
});
// Sort by date
const sortedPosts = allPosts.sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
);
getEntry
Retrieve a single entry from a collection.
getEntry(collection: string, id: string): Promise<CollectionEntry | undefined>
getEntry(entry: { collection: string; id: string }): Promise<CollectionEntry | undefined>
getEntry(entry: { collection: string; slug: string }): Promise<CollectionEntry | undefined>
The name of the collection.
The entry ID (filename without extension).
return
Promise<CollectionEntry | undefined>
A single collection entry, or undefined if not found.
Example
// src/pages/blog/[...slug].astro
import { getEntry } from 'astro:content';
const entry = await getEntry('blog', Astro.params.slug);
if (!entry) {
return Astro.redirect('/404');
}
const { Content } = await entry.render();
getEntries
Retrieve multiple entries by reference.
getEntries(
entries: { collection: string; id: string }[]
): Promise<CollectionEntry[]>
Array of entry references.
return
Promise<CollectionEntry[]>
Array of matching collection entries.
Example
import { getEntries } from 'astro:content';
const post = await getEntry('blog', 'welcome');
const relatedPosts = await getEntries(post.data.relatedPosts);
reference
Create a reference to entries in another collection.
reference(collection: string): ZodSchema
The name of the collection to reference.
A Zod schema that validates references to the specified collection.
Example
// src/content/config.ts
import { defineCollection, z, reference } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
relatedPosts: z.array(reference('blog')).optional(),
author: reference('authors'),
}),
});
const authors = defineCollection({
type: 'data',
schema: z.object({
name: z.string(),
bio: z.string(),
}),
});
export const collections = { blog, authors };
---
// src/pages/blog/[slug].astro
import { getEntry } from 'astro:content';
const post = await getEntry('blog', Astro.params.slug);
const author = await getEntry(post.data.author);
---
<h1>{post.data.title}</h1>
<p>By {author.data.name}</p>
Rendering Content
Call render() on a content entry to get renderable content.
const entry = await getEntry('blog', 'my-post');
const { Content, headings, remarkPluginFrontmatter } = await entry.render();
An Astro component containing the rendered content.
Array of headings extracted from the content.type MarkdownHeading = {
depth: number;
slug: string;
text: string;
};
Frontmatter data modified or injected by remark/rehype plugins.
Example
---
import { getEntry } from 'astro:content';
const entry = await getEntry('blog', Astro.params.slug);
if (!entry) {
return Astro.redirect('/404');
}
const { Content, headings } = await entry.render();
---
<article>
<h1>{entry.data.title}</h1>
<Content />
<aside>
<h2>Table of Contents</h2>
<ul>
{headings.map(heading => (
<li>
<a href={`#${heading.slug}`}>{heading.text}</a>
</li>
))}
</ul>
</aside>
</article>