Astro Content Collections: type safety para tu blog
Cómo usar las Content Collections de Astro 4 con Zod para tener esquemas validados en tiempo de build y autocompletado completo en tus posts de Markdown.
TL;DR
defineCollection + z.object() = posts tipados con validación en build time. Cero sorpresas en producción.
Índice
Uno de los puntos de fricción clásicos con los blogs basados en Markdown es que cualquier typo en el frontmatter pasa desapercibido hasta que ves el post roto en producción. Las Content Collections de Astro resuelven esto de forma elegante.
El problema
---
pubDate: "mañana" # ← se cuela sin avisar
tags: "Astro" # ← debería ser array
---
La solución: defineCollection + Zod
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
pubDate: z.coerce.date(), // coerce convierte strings a Date
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
});
Desde este momento, astro build falla si algún post tiene un frontmatter inválido. El feedback es inmediato y el mensaje de error te dice exactamente qué campo falla.
Acceso tipado en las páginas
---
import { getCollection } from 'astro:content';
const posts = await getCollection('blog', ({ data }) => !data.draft);
// posts[0].data.pubDate es un Date, no un string. TypeScript lo sabe.
---
El autocompletado funciona a la perfección. Sin castings manuales, sin as Date.
Trade-off a tener en cuenta
Las Content Collections añaden un paso de generación de tipos que tarda ~200ms en el primer astro dev. En repos grandes con cientos de posts se nota. La alternativa sería usar import.meta.glob directamente, pero pierdes la validación.
Para la mayoría de blogs: usa Collections sin dudar.