Happening this week! Hear how Amplitude built a self-serve marketing engine to drive growth 🚀

Array

Schema type for arrays of other types.

An array of references

An ordered list of data. The of property specifies which value types the array may hold.

Properties

  • REQUIREDtypestring

    Value must be set to array.

  • REQUIREDnamestring

    Required. The field name. This will be the key in the data record.

  • REQUIREDofarray

    Defines which types are allowed as members of the array.

  • titlestring

    Human readable label for the field.

  • hiddenboolean | function

    If set to true, this field will be hidden in the studio. You can also return a callback function to use it as a conditional field.

  • readOnlyboolean | function

    If set to true, this field will not be editable in the content studio. You can also return a callback function to use it as a conditional field.

  • descriptionstring

    Short description to editors how the field is to be used.

  • initialValueArrayOrResolverFunction

    The initial value that will be used when creating new arrays from this type. Can be either the literal array value or a resolver function that returns either the literal value or a promise resolving to the initial value.

  • componentsobject

    Lets you provide custom components to override the studio defaults in various contexts. The components available are field, input, item, preview.

  • deprecated{ reason: String }

    Marks a field or document type as deprecated in the studio interface and displays a user-defined message defined by the single required reason property.

    If you deploy a GraphQL API schema, this property will translated into the @deprecated directive.

Options

  • sortableboolean

    Controls whether the user is allowed to reorder the items in the array. Defaults to true.

  • layoutstring

    If set to tags, renders the array as a single, tokenized input field. This option only works if the array contains strings.

    If set to grid it will display in a grid.

    If the array uses the list option, it will display the values as a vertical list of checkboxes. Use grid layout to place the checkboxes horizontally.

  • listarray

    Renders checkboxes for a predefined list of values.

    For arrays of primitives the following formats are supported:

    • [ {value: <value>, title: <title>}, { … } ]
    • [ <value1>, <value2>, … ]

    For arrays of objects the format is

    [ {_type: <mandatory-object-type>, _key: <optional-key>, /* optionally any fields that exist in <object-type>*/}, { … } ]

    Objects will be rendered using the object types preview config.

  • modalobject

    Controls how the modal (dialog for array content editing) is rendered. Takes an object with type and width property.

    type can be dialog or popover, width can be 'auto' or a number.

    Default is {type: 'dialog', width: 'auto'}.

Validation

Learn more about validation
  • required()function

    Ensures that this field exists.

  • unique()function

    Requires all values within the array to be unique. Does a deep comparison, only excluding the _key property when comparing objects.

  • min(minLength)function

    Minimum number of elements in array.

  • max(maxLength)function

    Maximum number of elements in array.

  • length(exactLength)function

    Exact number of array elements to allow.

  • custom(fn)function

    Creates a custom validation rule.

Example: Array of strings

Vanilla, reorderable array of strings:

Schema

{
  title: 'Names',
  name: 'names',
  type: 'array',
  of: [{type: 'string'}]
}

API response

{
  "names": ["Wilma", "Håvard"]
}

Tokenized field (tags) is data-wise an ordinary array

Schema

// Presented as a tokenizing tag-field
{
  title: 'Tags',
  name: 'tags',
  type: 'array',
  of: [{type: 'string'}],
  options: {
    layout: 'tags'
  }
}

API response

{
  "tags": ["clever", "unexpected"]
}

Example: Array containing both crew members and cast members

Both crewMember and castMember are custom types defined in our schema. In this example we want an array of employees to be able to contain both crew members or cast members. The resulting array will end up containing inline instances of the actual objects. Note that in a real world example, you may want this to be references to existing cast members or crew members.

Schema

{
  title: 'Employees',
  name: 'employees',
  type: 'array',
  of: [{type: 'crewMember'}, {type: 'castMember'}]
}

API response

[
  {
      "_key": "5ead6b7c7dcc55ae66d504e2d9bfeff5",
      "_type": "castMember",
      "characterName": "Mark Watney",
      "externalCreditId": "53e7e85e0e0a266f9a0029aa",
      "person": {
        "_ref": "person_matt-damon",
        "_type": "reference"
      }
  },
  {
    "_key": "8c1dd384a3ab34befbe5fdd93478fc8e",
    "_type": "castMember",
    "characterName": "Melissa Lewis",
    "externalCreditId": "5466c78eeaeb8172820008e4",
    "person": {
      "_ref": "person_jessica-chastain",
      "_type": "reference"
    }
  },
  {
    "_key": "76a7e8c2547ce445294c581564bc7d75",
    "_type": "crewMember",
    "department": "Camera",
    "externalCreditId": "5607a946c3a3681218003eef",
    "externalId": 1404244,
    "job": "Helicopter Camera",
    "person": {
      "_ref": "person_john-marzano",
      "_type": "reference"
    }
  }
]

Example: Array of references

In this example, we want castMember and crewMember to be stored as separate documents, and our array should contain references to these documents instead of the actual data.

Schema

{
  title: 'Employees',
  name: 'employees',
  type: 'array',
  of: [
    {
      type: 'reference',
      to: [
        {type: 'castMember'},
        {type: 'crewMember'}
      ]
    }
  ]
}

API response

[
  {
    "_ref": "person_harrison-ford",
    "_type": "reference"
  },
  {
    "_ref": "person_ridley-scott",
    "_type": "reference"
  }
  //...
]

Example: Array of both references and non-references

Arrays can contain mixed types – subject to the second limitation identified below. This includes mixing references and non-references (e.g., objects).

Let's consider the previous example once more. This time, we want castMember to be stored as a separate document that our array should reference, while crewMember is a type where we want to store an inline instance of the actual object.

Schema

{
  title: 'Employees',
  name: 'employees',
  type: 'array',
  of: [
    {
      type: 'reference',
      to: [
        {type: 'castMember'},
      ]
    },
    {type: 'crewMember'}
  ]
}

API response

[
  {
    "_ref": "person_harrison-ford",
    "_type": "reference"
  },
  {
    "_ref": "person_ridley-scott",
    "_type": "reference"
  },
  {
    "_key": "76a7e8c2547ce445294c581564bc7d75",
    "_type": "crewMember",
    "department": "Camera",
    "externalCreditId": "5607a946c3a3681218003eef",
    "externalId": 1404244,
    "job": "Helicopter Camera",
    "person": {
      "_ref": "person_john-marzano",
      "_type": "reference"
    }
  }
  //...
]

Notice that {type: 'crewMember'} is inside the of array but outside the reference.

Protip

Looking to query an array of mixed references and non-references? You could specify what to return from each _type in the array (e.g., crewMember, castMember, etc.) using projections, but you can also distinguish between references and non-references and either return the inline instance of the object or return the referenced document.

*[] {
  'employees': employees[] {
    _type == 'reference' => @->,
    _type != 'reference' => @
  }
}

Example: Predefined strings

Sometimes you need an array of strings presented as a set of predefined values. By using the list option, the field is presented as an array of check boxes where the editor can toggle which strings are in the array. This handles the array as a set and the ordering is not defined.

Schema

{
  title: 'Category Set',
  name: 'categorySet',
  type: 'array',
  of: [{type: 'string'}],
  options: {
    list: [
      {title: 'Building', value: 'building'},
      {title: 'Master plan', value: 'masterPlan'},
      {title: 'Infrastructure', value: 'infrastructure'},
      {title: 'Private Home', value: 'privateHome'}
    ]
  }
}

API response

{
  "categorySet": ["building", "privateHome"]
}

Example: Predefined objects

New in V3.

Schema

{
  title: "Example object list",
  type: "array",
  name: "example",
  of: [
    {
      type: "object",
      name: "inline",
      fields: [
        { type: "string", name: "title" },
        { type: "number", name: "amount" }
      ]
    }
  ],
  options: {
    list: [
      { _type: "inline", title: "Big amount", amount: 100 },
      { _type: "inline", title: "Small amount", amount: 1 }
    ]
  }
}

API response

{
  "example": [
    {
      "_type": "inline",
      "title": "Big amount",
      "amount": 100,
      "_key": "auto-generated-0"
    },
    {
      "_type": "inline",
      "title": "Small amount",
      "amount": 1,
      "_key": "auto-generated-1"
    }
  ]
}

Example: unique values

A common use case is to only want unique items in an array. This can be enforced by adding a validation function and using the unique() method.

Schema

{
  title: 'Category Set',
  name: 'categorySet',
  type: 'array',
  of: [{type: 'string'}],
  validation: Rule => Rule.unique()
}

API response

{
  "categorySet": ["building", "privateHome"]
}

Why the _key?

When adding data with type: 'object' to an array, each item gets assigned a persistent and unique _key property. This is to ensure that each item can be addressed uniquely in a collaborative, real time setting. This allows one user to edit an array item while another user simultaneously reorders the array.

Gotcha

When using the initialValue property in Sanity Studio to initialize a field with a predefined array of objects, setting the _key property of those objects manually will not work.

This: { type: 'array', initialValue: [{_key: 'monday', day: 'Monday'}] }

Will result in this: [{_key: '<random string>', day: 'Monday'}]

Two Limitations

  1. Due to a limitation in the data store, arrays may not currently contain arrays. Solve this by wrapping nested arrays in objects.
  2. It is not possible to define arrays that contains both object types and primitive types. Arrays that hold values of primitive types (e.g. strings or numbers) cannot be addressed uniquely by a key in real time. As a consequence, when defining an array of primitive values, the content studio will switch to a simpler array input widget for editing. This simpler input widget will not be able to handle object types, which is why it is not possible to define arrays that contains both object types and primitive types. If you should ever need an array that contains both primitive types (e.g., strings) and objects (e.g., movie), you should instead create an object as an item in the array and give it properties that hold the primitive values.

This will not work:

{
  type: 'array',
  of: [
    {
      type: 'actor', /* This is an object type */
      title: 'Actor'
    },
    {
      type: 'string', /* Will not work! */
      title: 'Actor name'
    }
  ]
}

This will work:

{
  type: 'array',
  of: [
    {
      title: 'Actor',
      type: 'actor'
    },
    {
      title: 'Actor name',
      type: 'object',
      fields: [
        {
          title: 'Name',
          name: 'value',
          type: 'string'
        } 
      ]
    }
  ]
}

Was this article helpful?