This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# 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
|
||||
|
||||
```typescript
|
||||
// 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.
|
||||
|
||||
```typescript
|
||||
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)`.
|
||||
Reference in New Issue
Block a user