Joint session with Vercel: How to build intelligent storefronts (May 15th)

How to reference nested array objects in Sanity schema?

26 repliesLast updated: Nov 29, 2025

Hi all,
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
residencesData
which 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,
    }
  }
`;
Crucially, this person (the artist in residence) also contributes to a presentation text,
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
person
within my
texteDePresentation
schema?

    {
      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(),
    },
AI Update

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:

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 thread
26 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.

Related contributions