Cross Dataset Reference
A schema type for referencing documents in another dataset within the same project.
Cross-dataset references connect documents across datasets. They are closely related to the reference type, but they have their own distinct schema type, crossDatasetReference, and the two cannot be used interchangeably.
To set up your datasets for cross-dataset referencing, see Cross-dataset references.
This is a paid feature
This feature is available on certain Enterprise plans. Talk to sales to learn more.
Gotcha
Cross dataset references can only be dereferenced using GROQ queries. Dereferencing through GraphQL endpoints is not currently supported.
Properties
Requiredtype
Value must be set to
crossDatasetReference.Requiredname
The field name. This will be the key in the data record.
Requiredto
An array of objects naming the types from the referenced dataset that should be available in the referencing studio.
typeis required.iconandtitleare optional. For example:[{type: 'someTypeFromAnotherDataset', preview: {select: {title: 'title'}}}].Each entry also needs a
previewin practice. The referencing dataset has no access to the referenced dataset’s schema, so search and preview cannot be inferred and the Studio requires it at runtime. Note that the publishedCrossDatasetReferenceDefinitiontypes it as optional, so TypeScript will not catch a missingpreview.You may name several types in the
toarray, but each field is limited to types from a single dataset.Requireddataset
The name of the referenced dataset.
A function that is invoked with the
typeandidof the referenced document, and returns a URL string pointing directly at that document in its own studio. Used to build the intent link shown on the reference preview.Example:
studioUrl: ({type, id}) => `https://<your-studio-host>/structure/intent/edit/id=${id};type=${type}/`Default
false. If set totruethe 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).Human readable label for the field.
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.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.Short description to editors how the field is to be used.
The initial value used when creating new values of this type. Can be a literal value, or a resolver function that returns a literal value or a promise that resolves to one.
Marks a field or document type as deprecated in the studio interface and displays a user-defined message defined by the single required
reasonproperty.If you deploy a GraphQL API schema, this property will translated into the
@deprecateddirective.
Options
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,parentandparentPathproperties, and returns an object containingfilterandparams. The function may be async and return a promise resolving to that 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.
Object of parameters for the GROQ filter specified in
filter.Only valid with the string form of
filter. Whenfilteris a function it is typed asnever, because the function returns its ownparams.
Validation
Ensures that this field exists.
Creates a custom validation rule.
Sets a custom error message for the preceding validation rule.
Sets a custom warning message for the preceding validation rule. Warnings do not prevent publishing.
Info messages are purely informational and do not prevent publishing.
Gets the value of a sibling field to use in validation. Useful for rules that depend on another field.
Discards the validation rules set before it in the chain and makes the field optional. Rules chained after it still apply.
Minimal example
A minimal example of a crossDatasetReference field:
Input
import {defineType} from 'sanity'
export const personReferenceType = defineType({
title: 'Person in another dataset',
name: 'personReference',
type: 'crossDatasetReference',
dataset: 'production',
to: [
{
type: 'person',
preview: {
select: {
title: 'name',
media: 'image',
},
},
},
],
})Response
{
"_type": "personReference",
"_ref": "person_andrew-stanton",
"_dataset": "production",
"_projectId": "k1a2b3c4"
}The stored _type is the name of your field’s schema type, not the literal string crossDatasetReference. The Studio also writes _projectId on every value: it is the id of the project both datasets belong to, and preview resolution needs it.
Weak reference
Setting weak: true lets you publish a document whose cross-dataset reference points at a document that does not exist. The Studio still flags the missing target; it no longer blocks publishing.
Input
import {defineType} from 'sanity'
export const personReferenceType = defineType({
title: 'Person in another dataset',
name: 'personReference',
type: 'crossDatasetReference',
dataset: 'production',
weak: true,
to: [
{
type: 'person',
preview: {
select: {
title: 'name',
media: 'image',
},
},
},
],
})Response
{
"_type": "personReference",
"_ref": "person_andrew-stanton",
"_dataset": "production",
"_projectId": "k1a2b3c4",
"_weak": true
}Reference multiple types
The directors field is an array that can contain both person and bovinae (in the rare occasion a cow would direct a movie) references:
Input
import {defineType} from 'sanity'
export const personOrCowReferenceType = defineType({
title: 'Person or cow in another dataset',
name: 'personOrCowReference',
type: 'crossDatasetReference',
dataset: 'production',
to: [
{
type: 'person',
preview: {
select: {
title: 'name',
media: 'image',
},
},
},
{
type: 'bovinae',
preview: {
select: {
title: 'name',
media: 'avatar',
},
},
},
],
})Response
[
{
"_type": "personOrCowReference",
"_ref": "person_andrew-stanton",
"_dataset": "production",
"_projectId": "k1a2b3c4"
},
{
"_type": "personOrCowReference",
"_ref": "bovinae_ferdinand-bull",
"_dataset": "production",
"_projectId": "k1a2b3c4"
}
]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
import {defineType} from 'sanity'
export const personReferenceType = defineType({
title: 'Person in another dataset',
name: 'personReference',
type: 'crossDatasetReference',
dataset: 'production',
to: [
{
type: 'person',
preview: {
select: {
title: 'name',
media: 'image',
},
},
},
],
options: {
filter: 'role == $role',
filterParams: {role: 'director'},
},
})Response
{
"_type": "personReference",
"_ref": "person_steven-spielberg",
"_dataset": "production",
"_projectId": "k1a2b3c4"
}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
import {defineType} from 'sanity'
export const personReferenceType = defineType({
title: 'Person in another dataset',
name: 'personReference',
type: 'crossDatasetReference',
dataset: 'production',
to: [
{
type: 'person',
preview: {
select: {
title: 'name',
media: 'image',
},
},
},
],
options: {
filter: ({document}) => {
// Always check for document properties before using 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": "personReference",
"_ref": "person_steven-spielberg",
"_dataset": "production",
"_projectId": "k1a2b3c4"
}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
To resolve it:
- Check that the referenced document exists and has been published; cross-dataset references cannot resolve drafts.
- Check that the document’s
_typeis named in the field’stoarray. - If you are creating the reference before its target exists, the mutation is rejected by cross-dataset reference validation. The client accepts a
skipCrossDatasetReferenceValidationmutation option (defaultfalse) that skips that check for the mutation. It skips validation only: it does not bypass the plan gate or any API version gate, and it does not make the reference resolve.