A L E X   K U Z N E T S O F
Sep 11,2025
Read Time: 3 min

Understanding Schemas and Content Types in Sanity CMS

Understanding Schemas and Content Types in Sanity CMS

Sanity CMS is a powerful headless content management system that separates content creation from presentation, giving developers and content creators unprecedented flexibility. At the heart of this system lies the concept of schemas and content types – the fundamental building blocks that define how your content is structured, stored, and managed. This guide will walk you through everything you need to know about these essential concepts.

What Are Schemas in Sanity?

A schema in Sanity is essentially a JavaScript object that defines the structure of your content. Think of schemas as detailed blueprints for your data – they determine what types of content editors can create and edit in Sanity Studio, what fields are available, and how those fields behave.

Schemas serve a similar purpose to what other content management systems call “content models,” “custom fields,” or “entities”. However, Sanity’s approach is unique because the schema is confined to the Studio workspace, not to the actual Content Lake dataset, which remains “schemaless”. This means you can store any JSON documents in Content Lake as long as they have a _type property.

Understanding Content Types vs Document Types

  • Document types are collections of documents that represent standalone pieces of content (e.g., blog posts, authors, products).
  • Content types encompass the broader concept of different kinds of content your application manages.

Document types can represent anything from traditional content like blog posts and articles to more abstract concepts like projects, people, products, or places. They don’t have to map directly to pages on your website – they represent the conceptual building blocks of your content model.

Core Schema Components

Fields and Field Types

Fields are the individual pieces of information within a content type. Sanity offers a comprehensive range of built-in field types:

  • String: Short text content like titles and names
  • Text: Longer content like descriptions
  • Number: Numerical data such as prices
  • Boolean: True/false values for feature toggles
  • Date/DateTime: Standardized date entries
  • Image/File: Media assets with alt text options
  • Reference: Links to other document types
  • Array: Repeatable lists of other field types
  • Object: Groups of related fields
  • Block: Rich text content using Portable Text
  • Slug: URL-friendly strings
  • Geopoint: Geographical coordinates

Each field type serves a specific purpose and should be chosen carefully. Using appropriate field types enforces data integrity and improves content management consistency.

Example: Blog Post Schema


export default {
  name: 'post',
  title: 'Blog Post',
  type: 'document',
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: rule => rule.required().min(10).max(80)
    },
    {
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      options: { source: 'title', maxLength: 96 }
    },
    {
      name: 'author',
      title: 'Author',
      type: 'reference',
      to: [{type: 'author'}]
    },
    {
      name: 'body',
      title: 'Body',
      type: 'array',
      of: [{type: 'block'}]
    },
    {
      name: 'publishedAt',
      title: 'Published At',
      type: 'datetime'
    }
  ]
}

  

Schema Validation

Validation is crucial for maintaining content quality and consistency. Sanity provides both field-level and document-level validation.

Field-Level Example


{
  name: 'title',
  type: 'string',
  validation: rule => rule.required().min(10).max(80)
}
  

Document-Level Example


{
  name: 'post',
  type: 'document',
  validation: rule => rule.custom(fields => {
    if (fields.authors.length > 0 && Object.keys(fields.guest).length > 0) {
      return "You can't have both an author AND guest author"
    }
    return true
  })
}
  

Schema Relationships

Sanity excels at creating relationships between different content types using references.

One-to-One Example


{
  name: 'author',
  title: 'Author',
  type: 'reference',
  to: [{type: 'author'}]
}
  

One-to-Many Example


{
  name: 'categories',
  title: 'Categories',
  type: 'array',
  of: [{type: 'reference', to: {type: 'category'}}]
}
  

Pro Tip: Always use arrays of references even if you initially think you’ll only need one reference. This future-proofs your schema and avoids migrations later.

Portable Text and Rich Content

Sanity uses Portable Text for rich content editing. This is a JSON-based spec that provides more flexibility than HTML or Markdown, supports structured rich content, custom embeds, and serialization to any markup format.


{
  name: 'body',
  title: 'Body',
  type: 'array',
  of: [{type: 'block'}]
}
  

Best Practices for Schema Design

  • Plan Your Content Model First: Map your types and relationships before writing code.
  • Design for Modularity: Build reusable object types for consistency.
  • Use Appropriate Field Types: Prefer specificity; it enforces integrity.
  • Implement Proper Validation: Add validation rules for quality and error prevention.
  • Consider Future Scalability: Default to flexible structures like arrays of references.

Working with Schemas in Practice

  1. Create schema files in your project’s schemas directory.
  2. Define document types with their fields.
  3. Add the schema to your Sanity studio config.
  4. Test and iterate with content creators.

Querying Content with GROQ


*[_type == "post"]{
  _id,
  title,
  slug,
  author->{name, bio},
  publishedAt
}
  

Written by Alex Kuznetsof. For more, visit https://www.sanity.io/docs.

Shared by