Skip to content
Colin M. Skinner, PhD

Sep 10, 2026 · 1 min

Type-safe content belongs in a portfolio

  • typescript
  • content
  • nextjs

A personal site is a content problem dressed as a design problem. The temptation is to hand-write a few cards and move on. That works until the third post is missing a date.

I parse MDX with gray-matter and validate it with Zod. The loaders return a typed BlogPost or Project. Pages never see raw frontmatter. Invalid files fail next build.

That is not ceremony. It is the same instinct you want in a production app: make illegal states unrepresentable, then generate the routes from what remains.

The reading time is derived. Drafts are a boolean, not a separate folder you forget to exclude. Tags are a union of what the files actually use.

None of this requires a CMS. Git is the CMS. The schema is the contract.