Files
theater-ziefen-website/.agents/skills/content-modeling-best-practices/references/reference-vs-embedding.md
T
johannes.gasser 57af0b8386
Build and Deploy / build-and-deploy (push) Successful in 2m53s
add skills
2026-05-18 08:39:42 +02:00

2.3 KiB

Reference vs Embedding Content

When should content be linked (referenced) vs copied (embedded)? This decision affects reusability, query complexity, and editing workflows.

The Trade-offs

Aspect Reference Embedded Object
Reusability Shared across documents Copied per document
Single source Update once, reflects everywhere Must update each copy
Query complexity Requires joins/expansion Inline, simpler queries
Editing UX Separate editing interface All fields in one place
Independence Can exist on its own Only exists within parent

When to Reference

Use references when content:

  • Is reusable — Same author across many articles
  • Needs central management — Update product info once
  • Has its own lifecycle — Published/draft independent of parent
  • Should stay in sync — Price changes reflect everywhere

Examples:

  • Author profiles
  • Product catalog items
  • Shared testimonials
  • Category taxonomy
  • Reusable CTAs

When to Embed

Use embedded objects when content:

  • Is unique to this document — Page-specific hero
  • Doesn't make sense alone — SEO metadata
  • Should be copied, not linked — Historical snapshot
  • Simplifies editing — All fields in one form

Examples:

  • SEO metadata
  • Page-specific sections
  • Address information
  • Social links
  • Configuration options

Sanity Implementation

// Reference: Author is reusable
defineField({
  name: 'author',
  type: 'reference',
  to: [{ type: 'author' }]
})

// Embedded: SEO is page-specific
defineField({
  name: 'seo',
  type: 'object',
  fields: [
    defineField({ name: 'title', type: 'string' }),
    defineField({ name: 'description', type: 'text' })
  ]
})

The Hybrid Approach

Sometimes you want both: a reference for the canonical data, plus embedded overrides.

defineField({
  name: 'featuredProduct',
  type: 'object',
  fields: [
    defineField({ 
      name: 'product', 
      type: 'reference', 
      to: [{ type: 'product' }] 
    }),
    defineField({ 
      name: 'overrideTitle', 
      type: 'string',
      description: 'Optional: Override the product title for this context'
    }),
  ]
})

Query uses coalesce(overrideTitle, product->title).