Process
Schemas before content
Why we write the Zod schema before we write the first paragraph — and how that one rule has saved us from years of cleanup work.
There’s a rule on this team that we don’t break: no content type ships without a schema. Not a sketch. Not a “we’ll formalize it later.” A real Zod schema, in packages/schemas, validated by the Astro Content Layer at build time.
It sounds like overhead. In practice, it’s the single biggest reason our authoring experience stays calm as the catalog grows.
What goes wrong without a schema
Anyone who has worked on a marketing site for more than a year has seen this movie:
- A field gets renamed in three posts and not the other forty.
- A required image alt text quietly becomes optional because someone needed to ship.
- A “tags” array starts holding strings, then objects, then strings with embedded JSON, then comments.
- Templates end up wrapped in defensive null-checks that exist only to handle the drift.
The cost isn’t immediate. It compounds. By the time a refactor is justified, there are six contributors who all “know” the rules from memory, and none of those mental models agree.
What a schema gives us back
The schema is a single artifact that does five jobs at once:
- Type contract for every template that consumes the content.
- Validation gate at build time — broken frontmatter fails the build, never production.
- Documentation for human and AI authors alike. The schema is the spec.
- Refactor safety net. Renaming a field updates the type, which updates every template, which surfaces every callsite that needs attention.
- AI-friendly authoring substrate. Claude can read the schema, generate compliant frontmatter, and self-correct on validation errors.
A schema is the cheapest, most durable form of editorial leverage we’ve found.
The actual workflow
When we add a content type, the order is fixed:
- Write the Zod schema in
packages/schemas/src/<type>.ts. - Wire it into
apps/<site>/src/content/config.tsas a collection. - Build the template that renders it.
- Then author the first piece of content.
If step four reveals a missing field, we go back to step one. Authors are not allowed to add an undeclared frontmatter key as a workaround. That’s how drift starts.
The rule pays for itself within weeks
The first time someone tries to add a field that doesn’t exist and the build catches it before review, the rule has earned its keep. The second time the AI authoring assistant produces a perfectly-shaped post on the first try because the schema told it exactly what to write, the rule starts paying compound interest.
Schemas before content. Every time.
- #zod
- #content-modeling
- #authoring
Share this post
Related reading
-
Engineering · Apr 24, 2026 · 5 min
Performance budgets that stick
How we keep Lighthouse scores above 95 in production by treating performance as a build-time gate instead of a quarterly cleanup project.
-
Engineering · Apr 22, 2026
Why we built our own marketing platform
On the trade-offs behind rolling our own Astro-based stack instead of reaching for an off-the-shelf CMS.
-
Updates · Apr 20, 2026
Welcome to Site A
A short intro to what this site is, who it's for, and where we're headed next.