Cross Dataset References
All you need to know about creating references across datasets.
Paid feature
Shared content with Cross-Dataset References is an enterprise feature. Use our contact form to start a conversation with our sales team to enable your project to use this feature.
A fundamental requirement for enabling a content-driven workflow is having access to the proper tools to help you compartmentalize and then connect your content. A way of composing sets of fields to create documents, and of connecting documents to create relationships. Boxes and arrows, if you will.
The premier tool for connecting content in Sanity is the reference schema type, for creating binding relationships between content types. The reference type only allows references within a single dataset. This covers most use cases, but sometimes more complex architectures and content needs present a legitimate case for a way of communicating across datasets.
Enterprise organizations often have different teams working with different content across channels, geographies, and markets. You might have one team managing product data. A handful of others teams each in charge of the digital experience for their specific brand, in their specific market. And a centralized legal team, who supports various brands and markets by providing copy for Terms of Service, Warranties, and other official information. Making sure these teams all refer to the same single source of truth for any specific bit of content is a challenge in most CMSes and often leads to duplication of effort and content debt.
For these scenarios, there is the crossDatasetReference
schema type! With it comes the ability to make references between documents in different datasets.
While closely related to the reference
type, the crossDatasetReference
type has some unique capabilities and some different limitations that you should be aware of.
A cross-dataset reference is, as its name suggests, a reference in one dataset to a document in another dataset. In order for this to be possible, there are some requirements that must be filled.
For the remainder of this article, we’ll use the term referencing dataset when we discussing the dataset where the reference originates – i.e. the document that has a field pointing to a field in a different dataset – and referenced dataset when we talk about the dataset that is being referred to.
- Both datasets must belong to the same project which must be on an enterprise plan and have this feature enabled
- The source and target studios must both be updated to version
2.34.3
or later - The dataset name of the referenced dataset must be known at the time of creating the reference field in the referencing dataset
- Similarly, the type of document you wish to refer to in the referenced dataset, and one or more of its fields must be known in order to set up previews in the source dataset
To read details about the crossDatasetReference schema type, visit the schema type reference documentation.
The crossDatasetReference
type is, as mentioned, closely related to the reference
type. It supports most of the same properties and options, in addition to some specific ones. Let’s have a look at a minimal example of a crossdatasetReference
schema, and then go a bit further once we’ve established the basics.
//Type definition on the schema of the "referencing" dataset,
//i.e. where the reference originates
{
name: 'my-reference-field',
title: 'Field reference to other field in another dataset',
type: 'crossDatasetReference',
dataset: 'name-of-the-other-dataset',
to: [
{
type: 'article',
preview: {
select: {
title: 'title'
},
},
},
],
}
- All fields in the above example, except the title, are required
- The
type
must be set tocrossDatasetReference
- The
dataset
must have the appropriate value - The
to
field accepts an array of entries to different document types in the referenced dataset. You may define as many types here as you please, but eachcrossDatasetReference
field is limited to connecting to a single referenced dataset. - Because the entire schema of all document types in the referenced dataset is not known to the referencing dataset, the following is true for each entry in the
to
array:- In addition to
type
, each entry must specify one or more fields to use when searching for and previewing content in the referenced dataset. To learn more about previews and list views, please refer to this article.
- In addition to
Let’s add a few more fields and a little more complexity to our schema:
{
title: 'Reference to a document in a another dataset',
name: 'myCoolReferenceAcrossDatasets',
type: 'crossDatasetReference',
dataset: 'name-of-other-dataset',
studioUrl: ({ type, id }) => `https://target.studio/desk/${type};${id}`,
to: [
{
type: 'article',
preview: {
select: {
title: 'title',
media: 'heroImage',
},
},
},
{
type: 'person',
preview: {
select: {
name: 'name',
picture: 'portrait',
honorific: 'jobTitle',
},
prepare({ name, picture, honorific }) {
return {
title: name,
media: picture,
subtitle: honorific,
};
},
},
},
},
],
}
Let’s look at what we’ve added.
- The
studioUrl
field on line 6 accepts a function, which is invoked with thetype
andid
of your referenced document, and which should return a string in the shape of a URL to the document editing pane address in the referenced dataset studio. This field is used to create a direct link from the reference preview to its editing environment (providing your editors have access to it, of course). - Finally, we’ve added a second document type to our
to
array with an expanded preview configuration.
Having configured your schema, you should see the crossDatasetReference
field show up in your studio. While similar to reference
inputs they differ in some key aspects:
- The “Create New” button and option to open the referenced document in a new pane to the right are not available across datasets. Instead, you will find an intent link that will open the referenced document in the target studio (if you have access to it, and have set the
studioUrl
property). - Linking to drafts is not available across datasets. Unless the document has been published at some point, it will not show up in search.
- Depending on network conditions, searching and previewing cross-dataset reference fields might be less performant than doing the same operations on internal references.
Protip
The visibility of Cross Dataset References depends on the permissions of the current user or token. For private datasets this means that:
- A user or token can see that a reference exists if they have at least read permissions on the source document. If they don’t have read permissions on the target document, they’ll see that the reference exists but not the content of the target document.
- A user or token can fetch the referenced document if they have at least read permissions on the target document.
- A user who wants to create a reference to a document can search for and attach any documents they have read permissions on.
As with the reference
schema type, crossDatasetReference
fields are by default assumed to have bi-directional integrity which means that if you try to delete a document that is referred to by another document, the studio will alert you with a warning.
However, unlike references within a single dataset, the studio will allow you to proceed with deleting or unpublishing documents that have cross-dataset references.
If you go ahead and delete the document despite the warnings, it will show up as unavailable in any studio referencing it and will block publishing until the problem is fixed if any changes are made to the referring document.
These measures are in place so that you can feel confident about connecting your content across datasets, and that you will be notified if a referenced document disappears.
Sometimes you don't need this guarantee while you want to keep the convenience of references. This warning can be turned off by adding the weak: true
property to a reference field configuration.
You will still be notified that the document you are referring to has gone missing, but you will no longer be blocked from publishing.
Gotcha
Cross-dataset references require you to use API version v2022-03-07
or later. Read more about the Sanity API versioning scheme here.
Gotcha
Cross dataset references can only be dereferenced using GROQ queries. Dereferencing through GraphQL endpoints is not currently supported.
To GROQ, a crossDatasetReference
behaves similarly to an internal reference, except that dereferencing must always start from the “referencing” document. For example, for these two schemas, each in a different dataset:
// Movie type (movies-dataset)
{
name: 'Movie Name',
...
},
{
name: 'Actors',
title: 'Actors',
type: 'array',
of: {
type: 'crossDatasetReference',
dataset: 'people-dataset',
to: [
{
type: 'person',
preview: {
select: {
name: 'firstname'
},
},
},
]
}
}
// Person type (people-dataset)
{
name: 'firstname',
...
},
{
name: 'lastname',
...
},
...
A GROQ query starting at the Movies type can dereference the “actors” field elements to retrieve the Person type field:
*[_type == "movie"] {
...,
"actors": actors[]->{
...
firstname,
lastname,
}
}
There are no limitations on the number of levels or nesting of references supported by the dereferencing operation, but dereferencing can only be done through the ->
operator, following the “unidirectionality” of cross-dataset references - for example, if the person type had an “awards” cross-dataset reference field, it could be further dereferenced as follows:
*[_type == "movie"] {
...,
"actors": actors[]->{
...
firstname,
lastname,
awards->name
}
}
However, other ways of dereferencing, for example, using the references()
function is not supported:
// This is a NOT SUPPORTED query
*[_type == "movie"] {
...,
"actors": actors[]->{
...
firstname,
lastname,
"awards": *[_type == "awards" && references(^._id)] // <== here the reference function will not work for a cross-dataset reference
}
}
The cross-dataset reference schema type is a powerful tool for enabling Shared Content across datasets. It allows you to keep your content connected beyond its original context by extending the reference field with methods for authenticating and querying across datasets.
Further reading: