👋 Next.js Conf 2024: Come build, party, run, and connect with us! See all events

Schema / Field Types

Schema types are all the attributes or schema types available to add to a form to create a document type. Often schema types and field types are used synonymously.

At first, building schemas can be a lot to wrap your brain around (or grasp), but there are optional functions to help you get up and running:

Helper functions: defineType, defineField, and defineArrayMember

These helper functions are optional, but helpful as they allow for better implementation of autocomplete in most IDEs. As their names imply, you use each function to wrap your definitions for documents, fields and array members respectively.

// /schemas/product.js (.ts)

import { defineType, defineField } from "sanity";

export const product = defineType({
  name: "product",
  type: "document",
  title: "Product",
  fields: [
    defineField({
      name: "productName",
      type: "string",
      title: "Product name",
    }),
    defineField({
      name: "tags",
      type: "array",
      title: "Tags for item",
      of: [
        defineArrayMember({
          type: 'object',
          name: 'tag',
          fields: [
            {type: 'string', name: 'label'},
            {type: 'string', name: 'value'},
          ]
        })
      ]
    }),
  ],
})

Product document type with product name and date added to inventory fields using helper functions defineType and defineField helper functions.

It is sometimes difficult to decide what field type and how to use it in a document to get the job done. Below are a few examples of common field types and how and when to use them.

Simple field types: Essential building blocks for your document

String - the string field type is most useful when only a small amount of text is needed. Typical uses of string fields include a title, name, and non-calculable numbers such as a postal code. There are also field options such as list that create predefined values for a string.

Why is this helpful?

Certain kinds of content do not change often and need to stay uniform. Predefined values make data consistency possible by transforming an open string field into a closed dropdown or radio button list. For example, in a product.js document, there might be a string field region where a particular product is sold. Perhaps, there are specific abbreviations for each region that are unlikely to change and should be uniform.

// /schemas/product.js (.ts)
// Region string type with a predefined list of locations
{
      title: 'Selling Region',
      name: 'region',
      type: 'string',
      initialValue: 'us-south',
      options: {
        list: [
          { title: 'US-North', value: 'us-north' },
          { title: 'US-South', value: 'us-south' },
          { title: 'US-East',  value: 'us-east' },
          { title: 'US-West',  value: 'us-west' },
          { title: 'UK',       value: 'uk' },
          { title: 'Europe',   value: 'europe' },
        ], // <-- predefined values
        //layout: 'radio' // <-- defaults to 'dropdown'
      }
  },

The region string field is transformed into a dropdown using the list option.

Creating a dropdown for string selection helps maintain content consistency with no data cleanup!

Advanced field types

Object - The object type can be used to build reusable custom content types that help keep your content consistent. A great use case for the object type is creating an accessible image content type.

// /schemas/objects/accessibleImage.js (.ts)

import { defineType } from 'sanity'

export default defineType ({
    name: 'accessibleImage',
    type: 'object',
    fields: [
      {
        name: 'alt',
        type: 'string',
        title: 'Alternative text',
        description: 'Alternative text is required.',
        hidden: ({ parent }) => !parent?.asset,
        validation: Rule => [
          Rule.required(),
        ],
        options: {
          isHighlighted: true,
        }
      },
      {
        name: 'caption',
        type: 'string',
        title: 'Caption',
        hidden: ({ parent }) => !parent?.asset,
        options: {
          isHighlighted: true
        }
      }
    ]
  }) 

The new custom accessibleImage content-type added to distributor.js document adds an accessible image field for distributors. Creating this image as an object means that it can be used or hoisted into any document type that requires an image. For instance, this content type could also be added to a post or page document to ensure all pages and posts have accessible images.

// schemas/distributor.js (.ts)
{
        name: 'distroImage',
        title: 'Distributor image',
        type: 'accessibleImage',
        description: 'Add an image or logo of the distributor',
},

Objects allow you to create nested patterns of content that are not only time savers but powerful tools that can empower brand consistency and create seamless editor experiences.

Array - Use the array field type to create a list that references another document type in the content model. One way to think about the array is that it creates an unordered list. The array field is great to use when a field will have two or more pieces of data or you need to create repeatable content. For example, the product document might contain a field for distributors. Since a product can have more than one distributor, the array field is used to make a list of all the distributors for a product.

// /schemas/product.js(.ts)

	{
      title: 'Product Distributor',
      name: 'productDistributor',
      type: 'array',
      of: [
        {
          type: 'reference',
          to: [{ type: distributorType.name }],
        },
     ]
	}

The product document now has an array field that uses the document type distributor. So, Protect Ya Neck Industries and Boogie Down Productions are now listed as distributors for a product.

For a complete list for all of the available fields, go to the schema types reference documentation.

Was this article helpful?