Reference
A schema type for referencing other documents.
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
Whether a reference should be strong or weak is configured by setting the weak
property on the reference field. Note that merely changing this property won't automatically update reference fields in the data store.
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
For a more in-depth discussion on how to think about references in Sanity, we recommend reading the supplementary article Connected Content.
Properties
REQUIREDtypestring
Value must be set to
reference
.REQUIREDnamestring
Required. The field name. This will be the key in the data record.
REQUIREDtoarray
Required. Must contain an array naming all the types which may be referenced e.g.
[{type: 'person'}]
. See more examples below.weakboolean
Default
false
. If set totrue
the reference will be made weak. This allows references to point at documents that may or may not exist, such as a document that has not yet been published or a document that has been deleted (or indeed an entirely imagined document).titlestring
Human readable label for the field.
boolean | 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.
initialValueObjectOrResolverFunction
The initial value that will be used when creating new values from this type. Can be either the literal value or a resolver function that returns either the literal value or a promise that resolves to the initial value.
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
disableNewboolean
Disables inline creation of new documents from the reference field. Defaults to
false
.filterstring | function
Additional GROQ-filter to use when searching for target documents. The filter will be added to the already existing type name clause.
If a function is provided, it is called with an object containing
document
,parent
andparentPath
properties as well as a convenientgetClient()
method, and should return an object containingfilter
andparams
. As ofv2.4.0
this function can optionally be async and return a Promise that resolves to an object containingfilter
andparams
.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 of parameters for the GROQ-filter specified in
filter
.
Validation
Learn more about validationrequired()function
Ensures that this field exists.
custom(fn)function
Creates a custom validation rule.
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'}]
}
]
}
Output
{
"_type": "reference",
"_ref": "ffda9bed-b959-4100-abeb-9f1e241e9445" /* This could be the id of Jessica Chastain */
}
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'
},
]
}
Output
{
"_type": "reference",
"_ref": "93f3af18-337a-4df7-a8de-fbaa6609fd0a" /* Movie id */
"_weak": true
}
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'}
]
}
]
}
Output
[
{
"_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"
}
]
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'}
}
}
Output
{
"_type": "reference",
/* this could be the id of some director */
"_ref": "9b711031-3744-47ab-9bb7-1bceb177d0d0"
},
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
}
}
}
}
}
Output
{
"_type": "reference",
/* this could be the id of some director,
* born after the movie was released */
"_ref": "9b711031-3744-47ab-9bb7-1bceb177d0d0"
}
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},
}
},
},
}
Output
{
"_type": "reference",
/* this could be the id of some director, actor, or producer */
"_ref": "9b711031-3744-47ab-9bb7-1bceb177d0d0"
}
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,
}
}
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
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}`)
})
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
.
*[_type == "movie"] {
...,
"actors": actors[]{
...
person->
}
}
*[_type=="person"]{
name,
"relatedMovies": *[_type=='movie' && references(^._id)]{
title,
slug,
releaseDate
}
}