Skill 02 · Content Modeling Best Practices
Subchapter 2.1
references/content-reuse.mdMarkdown3 KBView on GitHub
Effective content models maximize reuse while minimizing duplication. Here are patterns for achieving both.
Full Duplication ←————————————————→ Full Reference
(Copy everything) (Link to one source)Most real-world content sits somewhere in between.
Create reusable content blocks that can be embedded anywhere.
Use case: Testimonials, FAQs, CTAs that appear on multiple pages.
// Standalone testimonial documents
defineType({
name: 'testimonial',
type: 'document',
fields: [
defineField({ name: 'quote', type: 'text' }),
defineField({ name: 'author', type: 'string' }),
defineField({ name: 'company', type: 'string' }),
]
})
// Reference in page builders
defineField({
name: 'pageBuilder',
type: 'array',
of: [
{ type: 'reference', to: [{ type: 'testimonial' }] }
]
})Extract common fields into reusable definitions.
Use case: SEO fields, social metadata, common dates.
// Shared field definition
export const seoFields = [
defineField({ name: 'seoTitle', type: 'string' }),
defineField({ name: 'seoDescription', type: 'text' }),
defineField({ name: 'ogImage', type: 'image' }),
]
// Spread into multiple types
defineType({
name: 'page',
fields: [
defineField({ name: 'title', type: 'string' }),
...seoFields
]
})
defineType({
name: 'post',
fields: [
defineField({ name: 'title', type: 'string' }),
...seoFields
]
})Centralize classification for consistent tagging.
Use case: Categories, tags, topics that span content types.
// Central taxonomy
defineType({
name: 'category',
type: 'document',
fields: [
defineField({ name: 'title', type: 'string' }),
defineField({ name: 'slug', type: 'slug' }),
]
})
// Used across content types
defineField({
name: 'categories',
type: 'array',
of: [{ type: 'reference', to: [{ type: 'category' }] }]
})Small, reusable pieces that combine into larger content.
Use case: Bios, addresses, contact info.
// Fragment type
defineType({
name: 'contactInfo',
type: 'object',
fields: [
defineField({ name: 'email', type: 'email' }),
defineField({ name: 'phone', type: 'string' }),
defineField({ name: 'address', type: 'text' }),
]
})
// Reused across types
defineType({
name: 'office',
fields: [
defineField({ name: 'name', type: 'string' }),
defineField({ name: 'contact', type: 'contactInfo' }),
]
})Not everything needs to be reusable. If content is only used in one place, embedding is simpler.
Signs of over-abstraction: