Blog
Content operations
Engineering

Your content model is the product decision

Every content system fails the same way: a field that grew a second meaning, and a template that reads it both ways. The model is the one thing you will still be living with in three years.

Maya Chen

Nobody sets out to build a content model with a field called `extra`. It arrives in the third month, when one page needs one more thing and the schema is already live — and by the second year there are four fields whose names nobody will defend and a template that reads all of them.

The model outlives everything around it

Every other layer of a content system gets replaced on a schedule. The frontend is rewritten when the framework moves, the design changes with the brand, the delivery layer changes when the CDN does. The documents stay. That is the argument for spending the week you were going to spend on the hero animation on the schema instead: it is the part of the work the next three frontends will be built on.

The test of a model is not whether it is elegant. It is whether a new editor can file a document correctly without asking anybody. If they have to ask whether the excerpt is the same as the description, the model contains a question that should have been a decision.

A field that two people describe differently is not a field. It is a conversation that happens again every time somebody saves.

Three questions that settle most arguments

  • Is this a document or a field of one? If a page can link to it, it is a document.
  • Who fills it in first? Whoever does decides whether it is required, and whether it needs a description.
  • What happens when it is empty? If the answer is that the template breaks, it is required — and the schema should say so rather than the template.

Answer those three in writing and the argument about naming gets much shorter, because most naming arguments are really arguments about where a thing lives.

Then write the query that finds the documents that predate your decision. It is one line, and it is the difference between a model you changed and a model you only meant to change.

count(*[_type == "post" && !defined(excerpt)])

Maya Chen

Head of content operations

Maya ran content operations for a publisher with eleven mastheads before joining Achar. She spends most of her time on the unglamorous half of content: naming things consistently, retiring things on purpose, and making sure the person who wrote a headline can still find it a year later.

Related posts

Engineering

GROQ in twenty minutes

There is no join, because there is no second table. A query says which documents and then what to return, and everything that looks like syntax is one of those two halves made more specific.

Tomás Ferreira
Content operations

A content lake is not a CMS

A CMS owns your pages. A lake owns your content and has no opinion about your pages, which sounds like a small distinction until the second frontend arrives.

Maya Chen
Engineering
Content operations

Draft, publish, and the two-row trick

Achar stores a draft as a second document whose id begins `drafts.` rather than a flag on one row. It looks like duplication, and it is the reason a headline can be rewritten for a week without touching what the site serves.

Tomás Ferreira