Using groq is there a way to resolve all references inside your data no matter how deep?

4 replies
Last updated: Dec 3, 2020
Using groq is there a way to resolve all references inside your data no matter how deep? So i don't have to manually resolve all my references ?
AI Update

Unfortunately, GROQ doesn't have built-in recursive dereferencing - there's no automatic way to resolve all references at any depth without manually specifying each level. The reference access operator (->) in GROQ only resolves one level at a time.

This means if you have nested references (a document references another document that references another), you need to explicitly chain the -> operator for each level:

*[_type == "article"] {
  title,
  author->,                    // Resolves 1 level
  author->{                    // Resolves 2 levels
    name,
    department->
  },
  author->{                    // Resolves 3 levels
    name,
    department->{
      name,
      manager->
    }
  }
}

Why This Limitation Exists

GROQ is designed this way for good reasons:

  1. Performance: Recursive resolution could create expensive queries that cascade through many documents
  2. Circular references: Without depth limits, circular references (A → B → A) would cause infinite loops
  3. Intentional data modeling: It encourages you to think about what data you actually need

Practical Workarounds

1. Resolve what you need in your query

Be explicit about the depth you need for each use case:

*[_type == "event"] {
  title,
  venue->{
    name,
    location
  },
  speakers[]->{
    name,
    company->{ name }
  }
}

2. Handle additional resolution client-side

Fetch the data with some references resolved, then make additional queries for deeper data if needed. This gives you more control over loading states and performance.

3. Denormalize strategic data

For frequently accessed nested data, consider duplicating it at query time or storing computed values. You could use Sanity Functions to maintain denormalized data when documents change.

4. Use projections to limit payload size

When you do resolve references, use projections to only fetch the fields you need rather than entire documents:

*[_type == "post"] {
  title,
  "authorName": author->name,
  "categoryTitle": category->title
}

While it would be convenient to have automatic deep dereferencing, the manual approach gives you better control over query performance and helps you think intentionally about your data structure. The key is to resolve references to the depth your UI actually needs, not necessarily all possible references.

Show original thread
4 replies
I would also like to know this. Our data is deeply nested and not a uniform shape since pages are randomly composed of many different types of objects.
Not at the moment I'm afraid. Recursive joining for GROQ comes up as a feature request now and then, so we're looking into it.
Thanks
user Y
the equivalent of
raw
in graphql would be ideal for this use case.
user Y
is it possible to get all data for a single document, with every reference resolved, using the doc endpoint? https://www.npmjs.com/package/@sanity/client#fetch-a-single-document we only need to fetch a single document on demand (gatsby client route), but we don't necessarily know the shape of the nested data, so being able to get everything in one simple request is the ideal outcome.

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?