GROQ: Auto-resolve all references without declaring fields?

17 replies
Last updated: Jan 27, 2026
Asking again, is it not possible for GROQ queries to resolve references without declaring the fields you want to return?
I need to query for a document by its ID, and return
all its fields – and resolve all its references – without knowing what they could be.
(The use case is creating a preview in Gatsby, so I need to mirror the GraphQL data, which does exactly this, but only at build time)
AI Update

Unfortunately, GROQ does not support automatically resolving all references recursively without explicitly specifying the fields you want. This is a fundamental difference between GROQ and the GraphQL implementation in gatsby-source-sanity.

Why GROQ Requires Explicit Field Specification

When you use the reference operator (->) in GROQ, you must explicitly project which fields you want from the referenced document. Even when using the ellipsis operator (...) to include all fields, it only spreads fields at the current level—it doesn't automatically dereference nested references.

For example, this query resolves one level of references:

*[_id == $id][0]{
  ...,
  author->,
  categories[]->
}

But if author itself contains references, those won't be automatically resolved. You'd need to explicitly nest them:

*[_id == $id][0]{
  ...,
  author->{
    ...,
    company->
  },
  categories[]->
}

How Gatsby's GraphQL Differs

The gatsby-source-sanity plugin provides special _raw fields that can automatically resolve references with the resolveReferences argument:

{
  _rawBody(resolveReferences: {maxDepth: 5})
}

This functionality is specific to the Gatsby integration and not available in Sanity's native GraphQL API or GROQ. These _raw fields are generated by the Gatsby plugin and won't appear in Sanity's standard GraphQL playground.

Workarounds for Your Use Case

For Gatsby preview functionality that mirrors the GraphQL behavior, you have a few options:

  1. Build dynamic GROQ queries: Introspect your schema to programmatically construct GROQ queries with all necessary reference resolutions. This is complex but possible if you know your content model structure.

  2. Use GROQ with known depth: If you know the maximum reference depth in your content model, write GROQ queries that explicitly resolve to that depth with nested projections.

  3. Fetch and resolve client-side: Query the document with *[_id == $id][0], then recursively fetch referenced documents by examining _ref fields and making additional queries.

  4. Use the GraphQL API for previews: Continue using Sanity's GraphQL API for preview functionality, which supports the same _raw field patterns as Gatsby (though you'll need to deploy your schema with sanity graphql deploy).

The fundamental limitation is that GROQ is designed to be explicit about data fetching for performance and predictability, while the Gatsby GraphQL integration adds automatic reference resolution as a convenience layer on top. There's no way to tell GROQ "resolve all references at all depths automatically" without specifying what those references are.

Show original thread
17 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?