Building a static blog with Astro content collections
Placeholder post. How a typed content schema and a glob loader catch broken frontmatter at build time instead of in production.
This is placeholder content; replaced by the migrated WordPress post in Phase 1.
The useful part of a content collection is not the loader, it is the schema. A typo in a category name, a missing description, a date written the American way round — all of it fails the build rather than quietly rendering a page nobody notices is wrong for a year.
The whole definition fits on a screen:
const posts = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/posts" }),
schema: z.object({
title: z.string(),
description: z.string().max(160),
pubDate: z.coerce.date(),
category: z.enum(["opinions-blogs", "development-and-coding"]),
draft: z.boolean().default(false),
}),
});
Because the schema is the source of truth, every template downstream is typed for free: the category is one of two known strings, the date is a real Date, and the draft flag exists on every post whether the author remembered it or not.
The file name is the slug and the slug is the URL, which means a migration is mostly a renaming exercise. Get the file names right and nothing else has to know that the site changed underneath it.
Love, peace and happiness