How to reference nested array objects in Sanity schema?
I have a bit of a convoluted question about structuring a schema to reference content within another schema's nested array. Bear with me please, I hope to make this as clear as possible!
At the highest level, within
_type == "residences", I have an array called
residencesDatawhich defines attributes associated to a given artist in residence ("person"), such as a title, slug, bio, etc. On
/residences, I map all of the objects in this array (aka the list of artists).
Once a user navigates to a particular artist's page,
/residences/[artistName], I query for this given artist's info on that page using the query below:
export const residenciesPageQuery = groq`
*[$slug in residencesData[].slug.current][0] {
_id,
"person": residencesData[slug.current == $slug][0] {
_key,
title,
type,
bio,
photoCredit,
contributions[]->{
"imageUrl": mainImage.asset->url,
"lqip": mainImage.asset->metadata.lqip,
slug,
},
portfolio,
instagram,
"imageUrl": mainImage.asset->url,
"lqip": mainImage.asset->metadata.lqip,
"slug": slug.current,
}
}
`;texteDePresentation, which I'll need to place on
/residences/[artistName]/[texteDePresentation]My question is as follows: How can I create a reference to a given
personwithin my
texteDePresentationschema?
{
name: "associatedArtist",
title: "Artiste en résidence associé",
description:
"Ceci est nécessaire pour le bouton 'retour' trouvé à la fin du texte",
type: "array",
of: [{ type: "reference", to: { type: " ????? " } }],
validation: (Rule) => Rule.required(),
},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.
Show original thread26 replies
Was this answer helpful?
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.