Appearance
System
Light
Dark
Setting applies to this browser only

Collections and Schemas


What Are Content Collections?

Content Collections are Astro’s built-in system for organizing and validating your Markdown, MDX, and data content. Instead of using loose Astro.glob() calls with manual type casting, collections give you:

  • Schema validation — Invalid frontmatter is caught at build time
  • Type safety — Full TypeScript autocompletion for frontmatter fields
  • Structured queryinggetCollection() and getEntry() APIs with typed returns
  • Content organization — Named directories with clear boundaries

Defining a Collection

Collections are defined in src/content.config.ts using the defineCollection function:

import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    author: z.string().default('Anonymous'),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };

The type field specifies whether the collection contains content files ('content' for Markdown/MDX) or data files ('data' for JSON/YAML).

Schema Field Types

Zod provides a rich set of validators for your frontmatter. Here are the most commonly used types:

Zod TypeUse CaseExample
z.string()Text fieldsTitle, description, author
z.number()Numeric valuesOrder, priority, rating
z.boolean()FlagsDraft, featured, published
z.date() or z.coerce.date()DatesPublication date, update date
z.array(z.string())ListsTags, categories
z.enum(['a', 'b'])Fixed optionsPost type, status
z.object({...})Nested dataSEO metadata, author info

Default Values and Optional Fields

Use .default() to provide fallback values and .optional() for fields that aren’t required:

schema: z.object({
  title: z.string(),                        // Required
  subtitle: z.string().optional(),          // Optional (can be undefined)
  author: z.string().default('Anonymous'),  // Defaults if not provided
  tags: z.array(z.string()).default([]),    // Empty array if not provided
})

Multiple Collections

You can define as many collections as your project needs. Each gets its own directory under src/content/ and its own schema:

const blog = defineCollection({ /* ... */ });
const docs = defineCollection({ /* ... */ });
const authors = defineCollection({ type: 'data', /* ... */ });

export const collections = { blog, docs, authors };

This separation keeps your content organized and each collection’s schema focused on its specific needs.

Home
Search
Menu
Theme
Top