Data, content, and assets

Create a content collection

Group related content entries under one typed model rather than reading arbitrary files throughout page templates.

When a site has ten posts, you can read ten files. When it has two hundred, you need a system. That system in Astro is a content collection: a named group of entries that share a shape, loaded and validated in one place.

Collections fit blog posts, docs pages, products, team members. Anything where you have many entries with the same fields.

Define a collection

In Astro 7 collections live in src/content.config.ts. Each collection needs a loader, which tells Astro where the entries come from:

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

const notes = defineCollection({
  loader: glob({
    base: './src/content/notes',
    pattern: '**/*.{md,mdx}'
  })
})

export const collections = { notes }

Now every Markdown file under src/content/notes/ is an entry in the notes collection.

Create one to see it work. Save this as src/content/notes/first-note.md:

---
title: My first note
---

Astro collections are neat.

Each entry has an id, derived from the file name, so this one is first-note. Its frontmatter is available as data, so data.title is “My first note”. And the body can be rendered to HTML, which we do in a later lesson.

Loaders

glob() is the loader for a folder of files. There are others.

file() turns one JSON, YAML, or TOML file into many entries. Good for a list of authors or a small product catalog you keep in a single file.

Custom loaders can fetch from anywhere. A CMS, a database, an API. The pages querying the collection don’t care. They see entries with id and data, same as before.

Why not just read the files?

You could import.meta.glob() the Markdown files from a page and loop over them. It works for one page. Then a second page needs the same list, and a third, and each one has its own slightly different reading code.

A collection gives the content one front door. Pages ask for notes and get typed entries back. Switch from Markdown files to a CMS next year and you change the loader. The pages stay the same.

Run npm run dev after saving the config. Astro generates types for the collection, so in a page note.data.title autocompletes. If the types feel stale, run npx astro sync to regenerate them.

Lesson completed