Index
Edit

The Building Blocks

You did read the introduction about schemas, right? Now, let's skim across the major building blocks of a schema. Later you should peruse the reference documentation for all the juicy details.

Basic value-types

You got your basic string, number and boolean types basically mapping to the exact same types in JSON. On top of that you got datetime and url which are both strings in JSON but provides a UI appropriate for those content types.

All of these becomes a single basic JSON value when you fetch them through the api. Here is a document containing one of each:

{
  "string": "A string",
  "number", 123.45,
  "boolean": true,
  "datetime": "2017-06-21T13:55:26Z", // datetime is always in UTC form
  "url": "https://www.sanity.io"
}

Then of course, at times, you'll also need more complex types that cannot be encoded in a single basic JSON value. These are typically based on the type object:

Objects

In the introduction we talked about defining new document-types. In the same manner you may define object-types. An object is a collection of fields just like documents, but you use them as one value in another document. Let's say we are making fantasy style game with a number of enemies that all provide certain loot when beaten. We want to model the loot in one general way across adversaries, so we define an object in the schema:

// The schema for the Loot object type

{
title: 'Loot',
name: 'loot', type: 'object', fields: [ { title: 'Resource', name: 'resource', type: 'string' // Here the user will be prompted to write any string to describe the resource type. // There is a way to limit this to a number of preset strings and provide a pull-down // or radio buttons to select resource. This is left as an exercise for the reader! See // the reference docs! }, { title: 'Amount', name: 'amount', type: 'number' } ] },

Unlike the document-type we defined in the introduction, this will not appear in the side bar as a document an editor may create. Objects are meant to be embedded inside documents. Let's make an ogre:

// The schema for the Ogre document type

{
  title: 'Ogre',
  name: 'ogre',
  type: 'document',
  fields: [
    {
      title: 'Hit Points',
      name: 'hp',
      type: 'number'
    },
    {
      title: 'Reward',
      name: 'reward',
      type: 'loot'
    }
  ]
},

The field reward will now contain an instance of the loot-object we defined above. In a specific document this could look like this:

// One specific Ogre-document

{
  "_id": "dc667c61-00fb-47e6-aaba-a6a4a2edc988",
  "_type": "ogre",
  "hp": 21,
  "reward": {
    "_type": "loot", // Objects always gets tagged with their type like this
    "resource": "gold",
    "amount": 10
  }
}

In this game there are also sphinxes that don't fight, but pose difficult questions. We are now able to reuse the loot object type for sphinxes although they are a different document type:

// The schema for the Sphinx document type

{
  title: 'Sphinx',
  name: 'sphinx',
  type: 'document',
  fields: [
    {
      title: 'Question',
      name: 'question',
      type: 'string'
    },
    {
      title: 'Answer',
      name: 'answer',
      type: 'string'
    }
    {
      title: 'Reward',
      name: 'reward',
      type: 'loot'
    }
  ]
},

So later in that project when the designer want treasure chests too, we just add a new document type for them and re-use the loot-object. This is cool and all, but objects get really useful when combined with arrays!

Arrays

When you need a field to contain a list of things, you use an array. A very simple example could be a list of keywords for an author. Let's say our goal is to model a document like this:

// A specific author with a keyword-array
{
  "_id": "dc667c61-00fb-47e6-aaba-a6a4a2edc988",
  "_type": "author",
  "name": "William Gibson",
  "keywords": ["sci-fi", "cyberpunk"]
}

Here, the keyword field is an array of strings. The schema would look like this:

// The schema for authors with keywords as an array of strings
{
  title: "Author",
  name: "author",
  type: "document",
  fields: [
    {
      title: "Name",
      name: "name",
      type: "string"
    },
{
title: "Keywords",
name: "keywords",
type: "array",
of: [{type: "string"}]
}
// There is a way to make arrays of strings appear as a neat // tokenized tag-field. Check the reference documentation! ] }

The really useful thing, though, is arrays of objects. Say we're making a site about architecture and we want each building to list a number of milestones describing the different project stages from competition to topping out. First we'd define an object type describing each milestone:

// The schema of the Milestone object-type
{
  title: "Milestone",
  name: "milestone",
  type: "object",
  fields: [
    {
      title: "Event",
      name: "event",
      type: "string"
    },
    {
      title: "Time",
      name: "time",
      type: "datetime"
    }
  ]
}

Now, in our buildings we can have arrays of milestones like this:

// Partial schema for a building document type
{
  title: "Building",
  name: "building",
  type: "document",
  fields: [
    // ... lots of fields, probably ...
{
title: "Process",
name: "process",
type: "array",
of: [{type: "milestone"}]
}
] }

At this point most people ask why the of-value is an array and not just the type, that is because arrays of objects may actually support a selection of types. In an outdoorsy app about hiking in the wilderness, we might define a trip as an array of waypoints, vantage-points, fishing-spots, animal sighting opportunities etc which could look something like this:

// Partial schema for a trip document type
{
  title: "Trip",
  name: "trip",
  type: "document",
  fields: [
    // ... lots of fields, probably ...
    {
      title: "Features",
      name: "features",
      type: "array",
of: [
{type: "waypoint"},
{type: "vantagePoint"},
{type: "animalSighting"},
{type: "landmark"}
]
} ] }

And with very little work on your part, a user interface where you can add, remove, reorder and edit all these complex types is generated for you. You are welcome ;-)

References

We covered references quite thoroughly in the introduction to this chapter, so we'll skip the examples here. If you are looking for a quick primer, go there now!

References are "pointers" where one document references another document. The purpose of references is to enable you to divide your content into small, meaningful, reusable documents and reference them wherever you need them. Some common use-cases include:

  • You have a documentation site and a chapter references a number of related articles
  • You are modelling small movie theatre, you have a number of ready to go, reusable movie description. Each screening references the movies to be shown.

We also recommend using references instead of url's to represents internal links between your documents, also in text. This allows the front-ends to be restructured without changing the content—and for som platforms urls doesn't make sense at all anyway. You can read more on the details of how to do this in the reference article for block text.

The Sanity Query language includes facilities to automatically replace references with the content they reference. This is all explained in the query tutorial.

Previous: Don'ts and DosNext: Previews / List Views