Studio

Reference

A schema type for referencing other documents.

A GIF of a showing the behaviour of a reference field in Sanity Studio
In a reference field you can search for, browse and select references to other documents, or create new documents of the appropriate type in a new pane

Relations between documents are modeled using the reference type. To model a one-to-many relation, store the references in an array.

References can be either strong (default) or weak. A strong reference will enforce that the document it points to actually exists, and will not allow deletion of a document that any other document refers to. A weak reference allows pointing to documents that may not exist (yet) or may have been deleted.

Gotcha

When working in Sanity Studio, the reference input allows you to search for already existing documents, or create and publish new documents of the appropriate type inline from the place of referral. In order to secure referential integrity, the referring document will be blocked from publishing until the new, referenced, document has been published. The exception is if the reference has the property weak: true.

Protip

Properties

  • Requiredtypestring

    Value must be set to reference.

  • Requirednamestring

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

  • Requiredtoarray

    An array of objects containing a type property that points to the document type that can be referenced. For example: [{type: 'person'}]

  • titlestring

    A human-readable label for the field.

  • descriptionstring

    A short description visible to editors that describes how to use the field.

  • weakboolean

    If set to true, the reference will be made weak. This allows references to point to documents that may or may not exist, such as a document that has not yet been published or one that has been deleted. Defaults to false.

  • hiddenboolean | fn

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

  • readOnlyboolean | fn

    If set to true, this field will be readOnly in the studio. You can return a callback function to use this as a conditional field. Defaults to false.

  • initialValue

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

  • deprecatedobject

    Marks a field as deprecated. Requires a single reason property that displays a user-facing message to explain the deprecation. When used with GraphQL, this is translated to a @deprecated directive. Example: {reason: 'no longer used'}

Options

  • disableNewboolean

    Disables inline creation of new documents from the references field. Defaults to false.

  • filterstring | function

    Additional GROQ-filter to use when searching target documents. The filter will apply to the already existing type defined in to.

    If a function is provided, it is called with an object containing document, parent, and parentPath properties as well as a getClient() method. It should return an object containing filter and params. This can optionally be async and return a promise that resolves this object.

    Note: The filter only constrains the list of documents returned at the time you search. It does not guarantee that the referenced document will always match the filter provided.

  • filterParamsobject

    Object parameters for the GROQ-filter specified in filter.

  • sortarray

    An array of objects to aid in sorting the available reference results, each with a direction and field property. For example: [{ direction: "asc", field: "title" }].

Validation

Default reference

Define the movie's director as a reference to a person:

Input

{
  name: 'movie',
  type: 'object',
  fields: [
    {
      title: 'Director',
      name: 'director',
      type: 'reference',
      to: [{type: 'person'}]
    }
  ]
}

Response

{
  "_type": "reference",
  "_ref": "ffda9bed-b959-4100-abeb-9f1e241e9445" /* This could be the id of Jessica Chastain */
}

Weak reference

Define the screening's movie as a weak reference to a movie, thereby allowing the movie to be deleted without deleting the screening first:

Input

{
  name: 'screening',
  type: 'document',
  fields: [
    {
      name: 'movie',
      title: 'Movie',
      type: 'reference',
      weak: true,
      to: [{type: 'movie'}],
      description: 'Which movie are we screening'
    },
  ]
}

Response

{
  "_type": "reference",
  "_ref": "93f3af18-337a-4df7-a8de-fbaa6609fd0a" /* Movie id */
  "_weak": true
}

Reference multiple types

The directors field is an array which can contain both person and bovinae (in the rare occasion a cow would direct a movie) references:

Input

{
  title: 'Directors',
  name: 'directors',
  type: 'array',
  of: [
    {
      type: 'reference',
      to: [
        {type: 'person'},
        {type: 'bovinae'}
      ]
    }
  ]
}

Response

[
  {
    "_type": "reference",
    /* this could be the id of Yvonne, the escaped cow */
    "_ref": "9b711031-3744-47ab-9bb7-1bceb177d0d0"
  },
  {
    "_type": "reference",
    /* this could be the id of Matt Damon */
    "_ref": "ffda9bed-b959-4100-abeb-9f1e241e9445"
  }
]

Additional static filter

If providing a target schema type is not enough to provide a meaningful set of search results, you may want to further constrain the search query:

Input

{
  title: 'Director',
  name: 'director',
  type: 'reference',
  to: [{type: 'person'}],
  options: {
    filter: 'role == $role',
    filterParams: {role: 'director'}
  }
}

Response

{
  "_type": "reference",
   /* this could be the id of some director */
  "_ref": "9b711031-3744-47ab-9bb7-1bceb177d0d0"
},

Additional dynamic filter

If you want to further constrain the search result, but need properties from the surrounding document or object/array, you can use the function form for filter:

Input

{
  title: 'Director',
  name: 'director',
  type: 'reference',
  to: [{type: 'person'}],
  options: {
    filter: ({document}) => {
      // Always make sure to check for document properties
      // before attempting to use them
      if (!document.releaseYear) {
        return {
          filter: 'role == $role',
          params: {role: 'director'}
        }
      }
      
      return {
        filter: 'role == $role && birthYear >= $minYear',
        params: {
          role: 'director',
          minYear: document.releaseYear
        }
      }
    }
  }
}

Response

{
  "_type": "reference",
   /* this could be the id of some director,
    * born after the movie was released */
  "_ref": "9b711031-3744-47ab-9bb7-1bceb177d0d0"
}

Additional async filter

If you want to constrain your filter based on factors available elsewhere in your content lake, you can specify your filter as an asynchronous function.

Input

{ 
  // Somewhat contrived example that will make the reference field accept any document of a valid type except the most recently published
  name: 'personRef',
  type: 'reference',
  to: [{type: 'director'}, {type: 'actor'}, {type: 'producer'}],
  options: {
    filter: async ({getClient}) => {
      const client = getClient({apiVersion: '2023-01-01'})
      const latestPersonId = await client.fetch(
        '*[title in ["director", "actor", "producer"] && _id in path("*")] | order(_createdAt desc) [0]._id'
      )
      return {
        filter: '_id != $latestPersonId',
        params: {latestPersonId: latestPersonId},
      }
    },
  },
}

Response

{
  "_type": "reference",
   /* this could be the id of some director, actor, or producer */
  "_ref": "9b711031-3744-47ab-9bb7-1bceb177d0d0"
}

Disable new document creation

If you wish to disable the inline creation of new document from the reference field. This is done by setting the disableNew option to true.

{
  title: 'Director',
  name: 'director',
  type: 'reference',
  to: [{type: 'person'}],
  options: {
    disableNew: true,
  }
}

Nonexistent reference

Sometimes the reference field may show an error message like <nonexistent reference>. This usually happens when creating documents with a client library and can mean one of two things:

  • The document with the ID you are referencing does not exist
  • The field does not allow references to the document type of the document ID you tried to reference

Create reference programmatically

If you want to create a reference to another document when using our APIs, you need to know the ID of the document you want to create a reference to. Then you need to add that to an object with the following form:

{
  _type: 'reference',
  _ref: 'id-of-reference-document'
}

Here's an example using the Javascript client:

import {createClient} from '@sanity/client'

export const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset-name',
  useCdn: true,
  apiVersion: '2023-05-03',
  token: process.env.SANITY_SECRET_TOKEN // Must have write access
})

client.create({
  _type: 'book',
  title: 'Some book title',
  author: {
    _type: 'reference',
    _ref: 'id-of-author-document'
  }
})
.then(result => {
  console.log(`Created book with id: ${result._id}`)
})

Always reference the published document _id

Reference unpublished version documents programmatically

When you're programmatically creating version documents that need to reference each other, you may run into the problem where you're trying to reference a document that hasn't been published. Weak references should work as expected, but strong references require more work. You incorporate the following into any custom logic that creates and publishes version references.

  • Create the reference with the _strengthenOnPublish attribute and _weak set to true. The contents of the _strengthenOnPublish object are primarily used to inform previews in Studio. You can leverage this content further if needed.
  • On publish, find all _strengthenOnPublish references and remove it along with the _weak property.

Writing GROQ queries for references

References by default are bi-directional and can be queried from either side of their relationship. For a movie that has an actors array referencing multiple person documents, we can join the person data to the movie by dereferencing its data, but we can also query all movies associated with a person.

Join the actor data onto movie data

*[_type == "movie"] {
  ...,
  "actors": actors[]{
    ...
    person->
  }
}

Get all movies for a person

*[_type=="person"]{
  name,
  "relatedMovies": *[_type=='movie' && references(^._id)]{ 
  	title,
  	slug,
  	releaseDate
	}
}

Was this page helpful?