Skip to content
Mackin Digital
English

Markdown and Content Collections in Astro

Use Markdown, frontmatter, content collections, and Zod schemas in Astro. Learn trade-offs between approaches for editorial websites.

City buildings illuminated with blue light trails at night.

Astro provides multiple approaches for managing editorial content, each suited to different project needs. Markdown with frontmatter offers a straightforward foundation for defining content metadata. The src/pages/ directory enables automatic page generation through file-based routing. Content collections provide a more structured alternative for organizing related content groups with validation and querying capabilities. MDX extends Markdown with component support for interactive content. Understanding when and how to use each approach - and recognizing the trade-offs between build-time and live collections - helps developers build scalable editorial websites efficiently.

Markdown and Frontmatter Fundamentals

What is frontmatter?

Frontmatter is a block of data, typically written in YAML or TOML, located at the beginning of a Markdown file. Astro includes built-in support for Markdown files that can include frontmatter to define custom properties such as a title, description, and tags 1. With Astro 7’s default Markdown processor, this basic support is available without extra installation or configuration 1.

YAML and TOML syntax

YAML uses colons between keys and values. A list such as tags can contain several values. TOML expresses the same kind of metadata with equals signs and array syntax. Astro supports both formats for frontmatter 1. These illustrative snippets define the same three fields:

YAML:

title: 'A practical Astro guide'
description: 'Organize a small editorial website.'
tags:
  - astro
  - markdown

TOML:

title = 'A practical Astro guide'
description = 'Organize a small editorial website.'
tags = ['astro', 'markdown']

The values are an editorial example, not Astro-reserved fields. A content collection schema determines which fields your project requires. The separate minimal Markdown example below shows the complete YAML frontmatter block, including its opening and closing fences.

Custom properties for editorial metadata

Custom properties defined in frontmatter, such as title, description, and tags, serve as editorial metadata for content 1.

Here is a minimal Markdown file example with a frontmatter block and body content:

---
title: 'The greatest post of all time'
author: 'Ben'
---
Here is my _great_ post!
Frontmatter Structure Example
  1. Opening fence: --- (three hyphens)
  2. YAML key-value pairs: title, description, tags, published date
  3. Closing fence: --- (three hyphens)
  4. Markdown body content below frontmatter

Markdown in Astro | Docs

Show the anatomy of a Markdown file with YAML frontmatter and body content

Automatic Page Generation from src/pages/

File-based routing

Markdown files located within src/pages/ will automatically generate pages on your site 1. Astro treats any supported file inside of the /src/pages/ directory as a page, including .md and other Markdown file types 1. Placing a file in this directory, or any sub-directory, will automatically build a page route using the pathname of the file and display the Markdown content rendered to HTML 1. This automatic behavior requires no additional configuration 1.

Directory structure and URL mapping

File paths in src/pages/ map directly to URL routes on your site 1. For example, a Markdown file at src/pages/blog/my-article.md becomes accessible at /blog/my-article/ 1. The directory structure you create mirrors the URL structure visitors will use to access your content 1.

Consider this example structure:

src/pages/
├── page-1.md              → your-domain.com/page-1/
├── blog/
│   ├── my-article.md      → your-domain.com/blog/my-article/
│   └── another-post.md    → your-domain.com/blog/another-post/
└── docs/
    └── guide.md           → your-domain.com/docs/guide/

Each Markdown file’s frontmatter and body content are automatically processed 1. Astro injects an id attribute into all heading elements (<h1> to <h6>) in Markdown files, enabling anchor links 1. For instance, a heading ## Introduction in page-1.md generates an anchor at your-domain.com/page-1/#introduction 1.

When using the frontmatter layout property, you can wrap your Markdown content in an Astro layout component 1. This layout receives your frontmatter properties through Astro.props.frontmatter, allowing you to style and structure pages consistently 1. Note that when using a layout component, you must manually include the <meta charset="utf-8"> tag, as Astro no longer adds it automatically 1.

When to use src/pages/ Markdown

The src/pages/ approach works well for simple sites with straightforward content organization 1. This method requires no configuration and immediately generates pages based on the file structure 1.

However, content collections offer advantages when your site grows or content becomes more complex 1. Content collections allow you to store Markdown files anywhere on your filesystem, define schemas for validation and type safety, and use optimized APIs for querying and rendering content 1. Collections are intended for sets of data that share the same structure, such as blog posts or product items 1.

Choose src/pages/ Markdown when:

  • Your site has few pages or simple organization 1
  • You prefer file-based routing without additional configuration 1
  • You do not need content validation or type checking 1
  • You are managing individual pages that do not need a shared set of frontmatter fields 2

Consider content collections instead when:

  • You have groups of related Markdown files sharing a common structure 1
  • You want schema validation and editor type safety 1
  • You need to query and filter content programmatically 1
  • Your site will scale to many pages with similar layouts 1

File Path to URL Routing Examples

file pathgenerated url
src/pages/index.md/
src/pages/about.md/about/
src/pages/blog/first-post.md/blog/first-post/
src/pages/blog/2024/january.md/blog/2024/january/

Content Collections: Organization and Flexibility

What are content collections?

A content collection groups related entries that share an overall data structure 2. This data can be stored in one or several files locally, such as a folder of individual Markdown files for blog posts, or a single JSON file for product descriptions 2. Content can also be fetched from remote sources like a database, Content Management System (CMS), or Application Programming Interface (API) endpoint 2. Each member of a collection is called an entry 2. Collections are defined by the location and shape of their entries and provide a way to query and render content and associated metadata 2. You can create a collection when you have a group of related data or content, stored in the same location, that shares a common structure 2.

Advantages over file imports

Content collections offer several advantages compared to direct file imports. If you have groups of related Markdown files, defining them as collections provides benefits such as the ability to store Markdown files anywhere on your filesystem or remotely 1. Collections use content-specific, optimized APIs for querying and rendering Markdown content instead of file imports 1. When you define the shape of your content in a schema, you gain validation, type safety, and Intellisense in your editor 1. Collections are intended for sets of data that share the same structure, such as blog posts or product items 1.

Filesystem and remote storage flexibility

Content collections provide flexibility in where your content is stored. They support storing Markdown files anywhere on your filesystem or remotely 1. Astro provides built-in loaders for fetching local content at build time, including glob() and file() 2. The glob() loader fetches entries from directories of Markdown, MDX, Markdoc, JSON, YAML, or TOML files from anywhere on the filesystem 2. The file() loader fetches multiple entries from a single local file 2. For remote data, you can build a custom loader using the Content Loader API to fetch content from sources like a CMS, database, or API endpoint 2.

Setting up src/content/ directory

One possible layout keeps the configuration beside the content directories:

src/
  content.config.ts
  content/
    blog/
      first-post.md
      second-post.md

This folder arrangement is an example, not a mandatory storage location. The loader’s base path determines where entries are read 2.

All build-time content collections are defined in a src/content.config.ts file (or .js and .mjs extensions) 2. In this file, you import utilities from astro:content, define each collection using defineCollection(), and then export a single collections object 2. Each build-time collection configures a required loader for its data source and an optional schema for validation and type safety 2.

For example, a blog collection might be defined with a glob() loader and a schema:

import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';

const blog = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
  }),
});

export const collections = { blog };

The glob() loader requires a pattern of entry files to match and a base file path where your files are located 2. A unique ID for each entry is automatically generated from its filename, but you can define custom IDs 2. Once defined, you can query your content collections data using getCollection() and getEntry() helper functions 2.

Content Collections vs. File Imports

aspectfile importscontent collections
File locationLocal Markdown in src/ imported into a componentLocal or remote data through a configured loader
Schema validationValidation requires a separate approachOptional Zod schema validates entry data
QueryingImport a file or use import.meta.glob()Use getCollection() and getEntry()
Content organizationSuitable for individually managed filesShared metadata structure and content-focused APIs

Schema Validation with Zod

Introduction to Zod validation

Zod is the validation library Astro uses for schemas in content collections 2. To use Zod in Astro, import the z utility from astro/zod 2. This is a re-export of the Zod library, and it supports all of the features of Zod 4 2.

Enforcing consistent data structure

Schemas enforce consistent frontmatter or entry data within a collection through Zod validation 2. A schema guarantees that this data exists in a predictable form when you need to reference or query it 2.

Type safety and build-time error detection

When you define a schema for your collection, Astro automatically generates and applies a TypeScript interface to it 2. The result is full TypeScript support when you query your collection, including property autocompletion and type-checking 2. If any file violates its collection schema, Astro will provide a helpful error 2.

Defining collection schemas

Providing a schema is optional, but highly recommended 2. If you choose to use a schema, then every frontmatter or data property of your collection entries must be defined using a Zod data type 2.

Here is an example schema for a blog collection 2:

import { defineCollection } from 'astro:content';
import { z } from 'astro/zod';
import { glob } from 'astro/loaders';

const blog = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/data/blog' }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
  }),
});

export const collections = { blog };

In this example, title and description are defined as required strings, pubDate as a required date (using z.coerce.date()), and updatedDate as an optional date 2.

MDX: Adding Components and Interactivity

What is MDX?

MDX extends Markdown by allowing the inclusion of components and JSX expressions directly within Markdown content 1. This makes MDX useful when an article needs embedded components alongside its prose 1.

Installing @astrojs/mdx

To enable MDX functionality, such as including components and JSX expressions in Markdown, the @astrojs/mdx integration package must be added 1.

Use cases for components in Markdown

MDX is valuable for scenarios requiring the inclusion of components and JSX expressions within Markdown 1. This can be useful for interactive examples, embedding components, or dynamic content.

When MDX is optional

MDX is an optional feature for Astro’s editorial workflow 1. It is not required for basic editorial tasks 1.

Live Collections: Trade-offs and Constraints

Build-time vs. live collections

Astro offers two types of content collections: build-time and live. Build-time content collections are updated during the build process, and their data is stored in a content layer, which generally provides strong performance 2. In contrast, live content collections retrieve their data at runtime, rather than build time 2. This approach enables access to frequently updated data from sources like Content Management Systems (CMSs), APIs, or databases through a unified API, eliminating the need to rebuild the site when data changes 2.

Choosing between these collection types depends on specific needs. Build-time collections are recommended when performance is critical and data prerendering is desired, when data is relatively static (e.g., blog posts, documentation), when build-time optimization and caching are beneficial, when MDX processing or image optimization is required, or when data can be fetched once and reused across multiple builds 2. Live collections are designed for data that changes frequently and must be current at the time of a page request, such as real-time information (e.g., user-specific data, current stock levels), or when frequent updates necessitate avoiding constant site rebuilds 2. They are also suitable for dynamic filters based on user input or for CMS preview functionality where immediate display of draft content is needed 2.

No MDX rendering support

Live content collections do not support MDX rendering 2. MDX cannot be rendered at runtime 2.

No runtime image optimization

Images cannot be processed at runtime in live content collections 2.

Performance and caching considerations

Live content collections fetch data on each request, unless cached, which can impact performance 2. Build-time collections load their data during the build; their entries can be used in prerendered pages or in pages rendered on demand. Collection data loading and page rendering are separate choices. The performance implications of live collections should be weighed against the need for real-time data 2.

No data store persistence

Data from live content collections is not saved to the content layer data store 2.

When to accept these trade-offs

Live collections are appropriate when real-time information is needed (e.g., user-specific data, current stock levels), when frequent data changes make constant rebuilds impractical, when data updates frequently (e.g., up-to-the-minute product inventory, prices), when dynamic filters are required based on user input, or for CMS preview functionality where immediate display of draft content is essential 2. Astro’s documentation favors build-time collections where feasible, and suggests live collections when content needs real-time updates and the performance tradeoffs are acceptable 2.

Live Collections Limitations

limitationstatusimpact
MDX renderingNot supportedCannot render MDX entries at runtime
Image optimizationNot supportedImages cannot be processed or optimized at runtime
PerformanceData fetched per requestRequest-time fetching can add latency; caching affects the result
Data persistenceNot supportedData not saved to content layer data store

Frequently Asked Questions

What is frontmatter and how does it work in Astro?

Frontmatter is a block of YAML or TOML data at the beginning of a Markdown file that defines custom properties such as title, description, and tags. Astro 7 supports basic Markdown frontmatter with its default processor. For example, a Markdown file can begin with a frontmatter block enclosed by three hyphens (---), containing key-value pairs, followed by the Markdown body content.

How do Markdown files in src/pages/ automatically become pages?

Markdown files located in src/pages/ automatically generate pages on your site through file-based routing. No configuration is needed. File paths map directly to URL routes: a file at src/pages/blog/my-article.md becomes accessible at /blog/my-article/. Astro also automatically injects id attributes into heading elements, enabling anchor links like /blog/my-article/#introduction.

What advantages do content collections offer over file imports?

Content collections provide several advantages compared to direct file imports: the ability to store Markdown files anywhere on your filesystem or remotely, schema validation and type safety when a schema is configured, optimized APIs for querying and rendering content, and Intellisense support in your editor. Collections are designed for sets of data that share the same structure, such as blog posts or product items, providing a structured way to manage larger groups of related entries.

How do schemas with Zod validation improve content collections?

Schemas enforce consistent frontmatter or entry data within a collection through Zod validation. A schema guarantees that data exists in a predictable form when you need to reference or query it. Astro automatically generates a TypeScript interface from your schema, providing full TypeScript support including property autocompletion and type-checking. If any file violates its collection schema, Astro provides a helpful error at build time.

What is MDX and when should I use it?

MDX extends Markdown by allowing the inclusion of components and JSX expressions directly within Markdown content. It requires the @astrojs/mdx integration package. MDX is valuable for interactive examples, embedded components, and dynamic content. However, MDX is optional and not required for basic editorial workflows. Choose it when embedded components or JSX expressions serve the article; plain Markdown remains sufficient for prose, lists, code examples, and tables.

What are the 4 specific limitations of live content collections?

Live content collections have four limitations compared to build-time collections: (1) No MDX rendering - MDX cannot be rendered at runtime; (2) No image optimization - images cannot be processed at runtime; (3) Performance considerations - data is fetched on each request unless cached; (4) No data store persistence - data is not saved to the content layer data store. Despite these limitations, live collections are appropriate when real-time data is needed or when frequent updates make constant rebuilds impractical.

Astro’s editorial workflow accommodates projects of varying complexity. Simple sites benefit from src/pages/ Markdown and automatic routing. Growing projects gain organization, type safety, and scalability through content collections with Zod schemas. MDX adds interactivity when components are needed. Live collections enable real-time content updates but accept performance and feature trade-offs. Choosing the right combination depends on content structure, update frequency, performance requirements, and whether dynamic interactivity is necessary.

Sources

Related tags

Discuss online

View all