Sanity Best Practices
Apply and integrate best practices for Sanity CMS content modeling and workflows
Category: productivity Source: sanity-io/agent-toolkitSanity Best Practices is a community skill for building content platforms with Sanity CMS, covering schema design, GROQ queries, real-time collaboration, image handling, and deployment patterns for headless content management.
What Is This?
Overview
Sanity Best Practices provides patterns for designing and managing content with the Sanity headless CMS platform. It covers schema definition with document types, object types, and custom input components for structured content authoring, GROQ query language for fetching and transforming content with projections and joins, real-time collaboration features including presence indicators and live editing, image pipeline configuration with hotspot cropping, focal point selection, and responsive image URLs, and content modeling patterns for reusable page builders with portable text. The skill enables developers to build content-driven applications where editors can collaborate in real time while maintaining structured, queryable content.
Who Should Use This
This skill serves developers building headless CMS-powered websites with Sanity, content teams designing editorial workflows with real-time collaboration, and engineers integrating Sanity content into frontend frameworks.
Why Use It?
Problems It Solves
Designing content schemas that balance editorial flexibility with structured output requires understanding Sanity schema patterns. Querying deeply nested content with references needs GROQ syntax for joins and projections. Handling images with responsive sizing and art direction requires proper image pipeline configuration. Building page builder experiences with flexible content blocks demands portable text and reference patterns.
Core Highlights
Schema designer creates document and object types with validation rules and custom components. GROQ query builder fetches content with projections, filters, and reference expansion. Image pipeline generates responsive URLs with crop and hotspot parameters. Portable text renderer converts rich text to framework-specific components.
How to Use It?
Basic Usage
// schemas/post.ts
import { defineType, defineField }
from 'sanity';
export default defineType({
name: 'post',
title: 'Blog Post',
type: 'document',
fields: [
defineField({
name: 'title',
type: 'string',
validation: (Rule) =>
Rule.required().max(200),
}),
defineField({
name: 'slug',
type: 'slug',
options: {
source: 'title',
maxLength: 96,
},
validation: (Rule) =>
Rule.required(),
}),
defineField({
name: 'author',
type: 'reference',
to: [{ type: 'author' }],
}),
defineField({
name: 'mainImage',
type: 'image',
options: { hotspot: true },
}),
defineField({
name: 'body',
type: 'blockContent',
}),
defineField({
name: 'publishedAt',
type: 'datetime',
}),
],
preview: {
select: {
title: 'title',
author: 'author.name',
media: 'mainImage',
},
},
});
Real-World Examples
// GROQ queries for fetching content
import { createClient } from
'@sanity/client';
const client = createClient({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2024-01-01',
useCdn: true,
});
// Fetch posts with expanded refs
const posts = await client.fetch(`
*[_type == "post"
&& defined(publishedAt)]{
title,
"slug": slug.current,
publishedAt,
"author": author->{
name, "avatar":
image.asset->url },
"imageUrl":
mainImage.asset->url,
"excerpt": array::join(
string::split(
pt::text(body),
"")[0..200], "") + "..."
} | order(publishedAt desc)
[0...20]
`);
// Fetch single post by slug
async function getPost(
slug: string
) {
return client.fetch(`
*[_type == "post"
&& slug.current == $slug][0]{
title, body, publishedAt,
"author": author->{name},
"image": mainImage{
asset->{url, metadata}
}
}
`, { slug });
}
const post = await getPost('my-post');
console.log(post?.title);
Advanced Tips
Use GROQ projections to reshape response data at query time instead of transforming in application code. Configure webhook triggers for on-demand ISR revalidation when content is published. Use Sanity image URL builder for responsive srcset generation with automatic format conversion.
When to Use It?
Use Cases
Build a marketing website with a page builder that editors compose from reusable content blocks. Create a blog platform with real-time collaborative editing and scheduled publishing. Implement a product catalog with rich media handling and variant relationships.
Related Topics
Headless CMS, GROQ query language, content modeling, real-time collaboration, and structured content.
Important Notes
Requirements
Sanity project created through the CLI or dashboard. Node.js with @sanity/client for content fetching. Sanity Studio configured for content editing.
Usage Recommendations
Do: enable CDN caching for read-heavy production queries to reduce API response times. Use schema validation rules to enforce content quality at the CMS level. Define preview configurations for document types to help editors identify content in lists.
Don't: fetch all fields with GROQ when projections can limit the response to needed data. Store computed values in documents when GROQ can derive them at query time. Use the real-time listener for high-frequency polling when webhooks are appropriate.
Limitations
GROQ query language has a learning curve distinct from SQL or GraphQL. Real-time collaboration features require active Sanity subscriptions for larger teams. Image transformations are limited to the parameters supported by the Sanity image CDN.