Dereferencing nested object references in GROQ array query

5 replies
Last updated: Nov 29, 2025
Ok, this one is complicated. In the content I have "Recipe" with an array of "fresh" ingredients (objects) where the name is a reference to a "Tag" (called: ingredienttag). When I fetch the recipes in React, like:sanityClient
.fetch(

*[_type == "recipe"]{
       _id,
       title,
       slug,
       "dish": dish->{_id, name},
       fresh,
       stock,
       directions,
       "related": related[]->{title},
       "book": book->{_id, name, author},
       info,
       "tag": tag[]->{_id, name, category->{_id, name}},
      }
)
it returns the complete fresh array including <quantity, unit, ingredienttag: {_ref: "5f3bdac9e6490b05c8ba48ae", _type: "reference"}>.
Obviously I want to return the name of the referenced "tag", instead of _ref.
So instead of <fresh,> I do < "fresh": fresh[]->{quantity, unit, ingredienttag->{name}},> but it just returns an array of empty objects.
What can be wrong here? (all the rest is working as expected)
AI Update

The issue you're encountering is a common GROQ gotcha! The problem is that you're trying to dereference the fresh array itself with fresh[]->, but fresh isn't an array of references - it's an array of objects that contain a reference field (ingredienttag).

The -> dereferencing operator only works directly on reference fields, not on objects that contain references. When you use fresh[]->, GROQ tries to dereference each object in the array (not the reference inside it), which fails and returns empty objects.

Here's the solution - you need to project the array without dereferencing it, then dereference the nested reference field:

*[_type == "recipe"]{
  _id,
  title,
  slug,
  "dish": dish->{_id, name},
  "fresh": fresh[]{
    quantity,
    unit,
    "ingredienttag": ingredienttag->{name}
  },
  stock,
  directions,
  "related": related[]->{title},
  "book": book->{_id, name, author},
  info,
  "tag": tag[]->{_id, name, category->{_id, name}}
}

The key difference: use fresh[]{} (array projection) instead of fresh[]-> (array dereferencing). Inside the projection {}, you can then dereference the ingredienttag reference field with ingredienttag->{name}.

Why this works:

  • fresh[] iterates over the array elements
  • {quantity, unit, "ingredienttag": ingredienttag->{name}} projects each object, keeping quantity and unit, and dereferencing the ingredienttag reference to get its name

This pattern applies whenever you have an array of objects containing references - project the array first with []{}, then dereference the reference fields inside the projection. You can see this pattern in your working queries like "tag": tag[]->{_id, name, category->{_id, name}} where references are dereferenced, but that works because tag is an array of references directly, not an array of objects containing references.

As covered in the GROQ projections documentation, projections let you reshape data and follow references, but the syntax matters depending on your document structure!

Show original thread
5 replies

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.

Was this answer helpful?