The reference you did not make is the migration you will

A string is cheap to add and expensive to keep. Every duplicated value is a migration waiting for the day someone spells it differently.

Avery Lin

Avery Lin

Content Architect ·

Abstract teal gradient suggesting linked nodes

Nothing in a content model looks more reasonable at the time than a plain string. The author is a name, the category is a word, the product tier is one of three things everybody already knows. Typing it is faster than building a document type for it, and the first twenty entries agree with you.

Duplication is a promise you cannot keep

The moment a value appears in two documents it has two spellings, and only one of them is right. There is no query that repairs this, because there is nothing structural to repair — the dataset holds exactly what was typed.

A reference is the same value stored once and pointed at. Rename it, give it a bio, add an avatar, and every post that points at it updates with no migration at all.

The projection is where it pays off

A reference costs an editor one extra click and costs the query one arrow. This is a whole author profile, resolved in the projection so the component receives it as a prop and fetches nothing after mount (GROQ reference documentation (opens in new tab)):

shared/groq-queries.tsTypeScript
<script setup lang="ts">
// Fetched once, at build time, into the prerendered payload.
const { data } = await useSanityContent<BlogIndexQueryResult>(
    blogIndexQuery
)

// Paging and search are derived from it — no second request.
const matching = computed(() =>
    (data.value?.posts ?? []).filter(matchesFilters)
)
</script>

The -> is the entire cost. What you buy with it is that the author is one document, the category list is one set of documents, and neither can drift from itself.

When a string really is a string

Tags are the honest exception. They are folksonomy — cheap, disposable, allowed to be messy, and never the thing a page is looked up by. If a value needs a page of its own, a description, or a colour, it stopped being a tag some time ago.

Content ModellingReferencesGROQ
Avery Lin

Written by

Avery Lin

Content Architect

Avery designs content models for teams moving off page-builder CMSes, and writes about keeping structured content structured.