Typing your content with schemas

Frontmatter is a tiny database that nobody validates. A missing title, a date written as 10/08, a tag list that turned into a string: each one quietly ships.

A schema per collection

Describe the fields once, next to the collection, and let the build read every file through it.

const posts = z.object({
  title: z.string(),
  date: z.coerce.date(),
  tags: z.array(z.string()).default([]),
});

The same schema gives the editor its form and the layouts their types. A field that does not exist is a type error in the template, not a blank space on the page.

Errors that point somewhere

An error message is a user interface. "Invalid input" helps nobody; content/posts/hello.md:3: date: Invalid date sends you straight to the line.

New posts and the best notes in your inbox. No tracking, and you can leave with one click.