90 lines
2.3 KiB
Markdown
90 lines
2.3 KiB
Markdown
# 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)`.
|