Structuring a schema to reference content within another schema's nested array in Next.js
I understand your challenge! You have artists stored as objects within a residencesData array on a residences document, and you want to reference those nested array items from your texteDePresentation schema. Unfortunately, Sanity references can only point to top-level documents, not to objects nested within arrays.
Here are your best options:
Option 1: Make Artists Top-Level Documents (Recommended)
The most Sanity-idiomatic approach is to restructure your schema so each artist is its own document:
// schemas/artist.js
{
name: 'artist',
type: 'document',
fields: [
{ name: 'title', type: 'string' },
{ name: 'slug', type: 'slug' },
{ name: 'bio', type: 'text' },
{ name: 'photoCredit', type: 'string' },
{ name: 'portfolio', type: 'url' },
{ name: 'instagram', type: 'url' },
{ name: 'mainImage', type: 'image' },
// ... other fields
]
}
// schemas/residences.js
{
name: 'residences',
type: 'document',
fields: [
{
name: 'residencesData',
type: 'array',
of: [{ type: 'reference', to: [{ type: 'artist' }] }]
}
]
}
// schemas/texteDePresentation.js
{
name: 'texteDePresentation',
type: 'document',
fields: [
{
name: 'associatedArtist',
title: 'Artiste en résidence associé',
type: 'reference', // single reference, not array
to: [{ type: 'artist' }],
validation: (Rule) => Rule.required(),
}
]
}This gives you proper references and makes your queries cleaner.
Option 2: Store the _key Value
If restructuring isn't feasible, you can store the _key of the array item and manually join the data in your queries:
// In texteDePresentation schema
{
name: 'associatedArtistKey',
title: 'Artiste en résidence associé',
type: 'string', // Store the _key as a string
validation: (Rule) => Rule.required(),
}Then in your GROQ query:
*[_type == "texteDePresentation" && slug.current == $slug][0] {
...,
"associatedArtist": *[_type == "residences"][0]
.residencesData[_key == ^.associatedArtistKey][0]
}This is more fragile and harder to maintain, but it works if you can't restructure.
Option 3: Duplicate the Reference
Store a reference to the parent residences document plus the artist's slug:
{
name: 'associatedArtist',
type: 'object',
fields: [
{
name: 'residencesDoc',
type: 'reference',
to: [{ type: 'residences' }]
},
{
name: 'artistSlug',
type: 'string'
}
]
}The first option is really the way to go if possible. Sanity's reference system is designed for document-to-document relationships, and fighting against that pattern usually creates more complexity down the road. Making artists top-level documents also gives you better content management, easier querying, and the ability to reference artists from anywhere in your content.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.