A Folder of Markdown Files Becomes a Typed Collection
The Glob Loader
`glob()` pulls every matching file into the collection. Each file becomes one entry; its frontmatter is the entry's `data`.
What you'll learn
- Use `glob` with `pattern` and `base`
- Understand the resulting entry id
- Filter and nest files
The glob loader matches a set of files and turns each into an
entry. It’s the right loader for blog posts, docs pages, recipes —
anything where one file = one entry.
A Basic Glob
import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders";
const blog = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/blog" }),
schema: z.object({ title: z.string() }),
}); pattern— globs to match (relative tobase)base— the folder to search from
Allowed File Types
.md, .mdx, .markdown, .json, .yaml, .yml — Astro picks
the right parser per extension. For a single-file source (e.g. an
authors list in one JSON), use the file loader instead (next
lesson).
The Entry id
For each matched file, the id is the file path relative to
base, without the extension.
base: ./src/blog
pattern: **/*.md
Files:
hello-world.md → id: "hello-world"
advanced/effects.md → id: "advanced/effects" You’ll use this id later for routing and references.
Multiple Patterns
loader: glob({
pattern: ["**/*.md", "**/*.mdx"],
base: "./src/blog",
}), Excluding Files
Lead any pattern with ! to exclude:
loader: glob({
pattern: ["**/*.md", "!**/_*.md"], // skip drafts that start with _
base: "./src/blog",
}), Up Next
When all your data is in one file — JSON or YAML.
The File Loader →