Sanity
Learn (Beta)
Course

Day One with Sanity Studio

Lesson
3

Creating a schema

Learn how to configure a schema for Sanity Studio that defines your content model and builds out an editorial interface.

Log in to mark your progress for each Lesson and Task

Let’s start with some foundational knowledge of how your Sanity Studio and Content Lake are integrated and how to think about the “schema.” You can skip right to the code part and return to this later if you prefer to be hands-on first.

The schema for a Sanity Studio workspace defines what document types and fields can be accessed by a content team. It is also in the schema configuration you define much of the editorial experience for these documents and fields, like field descriptions, validation, initial value, and so on.

If you have used other CMSes, the “schema” will be similar to what is commonly referred to as “content model,” “fields and entities.” “custom types,” “advanced custom fields,” etc.

It's important to note that the schema is confined to a Studio workspace, not to the Sanity Content Lake dataset, which is considered "schemaless." That means that you can store pretty much any JSON document in it, as long as it has a value for the _type property.

As with everything, this has advantages and trade-offs. An advantage is that you can store more content in your dataset without being constrained to a specific Studio schema. A trade-off is that if you update content with APIs, you must recreate whatever data validation you have for documents and fields in the Studio.

A large part of configuring the schema is configuring the content types that one can create and edit in the Studio. This is also where you shape how and what content you can query in applications.

In a production project, you should first consult with your wider team of designers, content creators, and others to work with them to design a content model that best represents your business and your goals.

See Implementing Sanity successfully for guidance on how to work with a team to set yourself up for success.

In the following exercises, you'll be building the content model from the Hello, Structured Content module. Configuring schema types to represent a live music production company.

See Content Modeling for an exercise in identifying content types in an organization.

Create and open a new file in your Studio’s schemaTypes folder called eventType.ts. Copy-paste the following code into it:

Create your first document type: event.
./schemaTypes/eventType.ts
import {defineField, defineType} from 'sanity'
export const eventType = defineType({
name: 'event',
title: 'Event',
type: 'document',
fields: [
defineField({
name: 'name',
type: 'string',
}),
],
})
The defineField and defineType helper functions in the code above are not required, but they provide autocomplete suggestions and can catch errors in your configuration in code editors with TypeScript tooling.

Now you can import this document type into the schemaTypes array in the index.ts file in the same folder.

Register the event schema type to the Studio's schema
./schemaTypes/index.ts
import {eventType} from './eventType'
export const schemaTypes = [eventType]

When you save these two files, your Studio should automatically reload and show your first document type. You can and should create a new "event" document.

When you add content in the Name field, all your changes are automatically synced to your project's dataset in the Content Lake.

Now, let's add some more document types with fields in them. Same procedure as with the event type: add new files, copy-paste the code into them, and import and add them to the schemaType array in index.ts.

Create new document types for Artist and Venue.
./schemaTypes/artistType.ts
import {defineField, defineType} from 'sanity'
export const artistType = defineType({
name: 'artist',
title: 'Artist',
type: 'document',
fields: [
defineField({
name: 'name',
type: 'string',
}),
],
})
./schemaTypes/venueType.ts
import {defineField, defineType} from 'sanity'
export const venueType = defineType({
name: 'venue',
title: 'Venue',
type: 'document',
fields: [
defineField({
name: 'name',
type: 'string',
}),
],
})

Notice how all these document types use singular names and titles. This is because the singular form makes sense in most contexts where these values are used. Later in this module, you will learn how to customize document lists to use plural names.

Update the array of schema types with the new document types
./schemaTypes/index.ts
import {eventType} from './eventType'
import {artistType} from './artistType'
import {venueType} from './venueType'
export const schemaTypes = [artistType, eventType, venueType]

All these document types only have one field; you'll need to add more.

Sanity Studio has the field types you'd expect for storing content in a JSON format. For example string, number, boolean, array, object, and more.

In a typical project, the document types you create and the fields you add within them should be informed by conversations you've had with designers and content creators.

Using the Sanity schema docs as a guide, complete the fields we need for our project. See: Schema / Field Types.

Add the following fields to your event schema type. You will extend the configuration later to make their purpose clearer:

slug: a slug type field
eventType: a string type field to
date: a datetime type field
doorsOpen: a number type field
venue: a reference type field to the venue document type
headline: a reference type field to the artist document type
image: an image type field
details: an array of block type fields
tickets: a url field

Once complete, your eventType file should look like this:

./schemaTypes/eventType.ts
import {defineField, defineType} from 'sanity'
export const eventType = defineType({
name: 'event',
title: 'Event',
type: 'document',
fields: [
defineField({
name: 'name',
type: 'string',
}),
defineField({
name: 'slug',
type: 'slug',
}),
defineField({
name: 'date',
type: 'datetime',
}),
defineField({
name: 'doorsOpen',
type: 'number',
}),
defineField({
name: 'venue',
type: 'reference',
to: [{type: 'venue'}],
}),
defineField({
name: 'headline',
type: 'reference',
to: [{type: 'artist'}],
}),
defineField({
name: 'image',
type: 'image',
}),
defineField({
name: 'details',
type: 'array',
of: [{type: 'block'}],
}),
defineField({
name: 'tickets',
type: 'url',
}),
],
})

You can now compose and publish documents with multiple fields of varying data types, including a "reference" field that can relate one document with another.

You could deploy this to content creators in its current state. It’s already a working content management system!

You might notice that the details field appears as a block content (or "rich text") editor in the Studio. Any array type field that includes a block type will automatically change the UI for the field to this editor.

This is how Sanity Studio is designed for authoring and storing block content. Instead of saving block content and rich text in formats like Markdown or HTML as a string, Sanity Studio stores it in the open-source specification called Portable Text. This unlocks powerful querying and filtering capabilities in your projects and makes integrating across most platforms and frameworks easier.

Lastly, create and publish at least three documents:

One event document for an upcoming show
One venue document for an imagined location
One artist type document using that "really great band name" you thought of once

Composing content is now possible, but the editorial experience can be improved. You will work on that in the next exercise.