Using GROQ queries for live preview in Gatsby without knowing fields

18 replies
Last updated: Jun 25, 2020
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, no, GROQ does not support automatically resolving all references without specifying fields. The dereference operator (->) requires you to explicitly indicate which fields you want from referenced documents.

Why This Limitation Exists

GROQ is designed to be explicit about data fetching. When you use the -> operator, you need to either:

  1. Project specific fields from the referenced document:
*[_type == "event"] {
  venue->{
    name,
    address
  }
}
  1. Use spread operators to get all fields at that level:
*[_type == "event"] {
  venue->{
    ...
  }
}

However, even with spread operators, you'd need to manually traverse nested references and specify fields at each level. There's no "resolve everything recursively" option in GROQ itself.

Your Gatsby Preview Use Case

For your specific Gatsby preview scenario, you're trying to mirror what GraphQL does automatically. The good news is that gatsby-source-sanity has a solution: the _raw fields with resolveReferences.

According to the gatsby-source-sanity documentation, the plugin generates special _raw fields that can automatically resolve references:

{
  allSanityProject {
    edges {
      node {
        _rawTasks(resolveReferences: {maxDepth: 5})
      }
    }
  }
}

The key options here:

  • _raw<FieldName>: These fields contain the raw JSON data from Sanity
  • resolveReferences: When enabled with a maxDepth, this will automatically traverse and resolve references within the raw field data
  • maxDepth: Controls how many levels deep to resolve references (prevents infinite loops)

Practical Solution for Your Preview

For your document-by-ID query with full reference resolution:

query PreviewQuery($id: String!) {
  sanityYourType(_id: {eq: $id}) {
    _id
    _type
    _rawBody(resolveReferences: {maxDepth: 10})
    _rawExcerpt(resolveReferences: {maxDepth: 10})
    # Add _raw versions of any other fields that might contain references
  }
}

This approach:

  • Returns all data in its raw Sanity format
  • Automatically resolves references up to the specified depth
  • Doesn't require you to know the structure ahead of time
  • Mirrors what GraphQL's normal field resolution does

Important Caveats

  1. _raw fields are Gatsby-specific: They're generated by gatsby-source-sanity and won't work in Sanity's GraphQL playground
  2. Reference resolution is opt-in: You must explicitly add resolveReferences: {maxDepth: N} to each _raw field
  3. Performance consideration: Deep reference resolution can be expensive, so choose an appropriate maxDepth
  4. Top-level only: The documentation notes this is only done for "top-level nodes (documents)"

Alternative: Multiple Queries

If _raw fields don't meet your needs, you'd need to construct multiple GROQ queries or use GROQ's projection syntax with explicit field listing—there's simply no automatic "give me everything with all references resolved" option in GROQ itself. The GROQ reference access operator always requires you to specify what you want from the referenced document.

Correct. It’s a feature request that comes up once in a while, but it requires some design decisions, e.g. what to do with recursion.
1. Why don’t you use the preview feature in the plugin?
2. Don’t you know your content model? It may be some work, but it should be possible to “
know” where references occur in your model? We can point you in the right direction
Correct. It’s a feature request that comes up once in a while, but it requires some design decisions, e.g. what to do with recursion.
1. Why don’t you use the preview feature in the plugin?
2. Don’t you know your content model? It may be some work, but it should be possible to “
know” where references occur in your model? We can point you in the right direction
1. Are you talking about the Gatsby Cloud preview? I’m trying to avoid $99/mo for a small business to get a preview.2. I do know the content model, I’m trying to avoid writing it once in GROQ and once in GraphQL because that’s not very DRY.
Have you looked at running your own gatsby-preview instance? https://www.gatsbyjs.org/docs/running-a-gatsby-preview-server/
If you run it on heroku I think you can get away with a $7 dyno (you need a bit of RAM)
https://render.com/pricing might also be an option
I hadn’t, will give it a look.
Sanity must’ve solved this for their own GraphQL implementation though, right?
(Getting * fields and resolving * references)
Yeah, I guess you're right - we analyze your schema and use it to compile the GROQ queries. We might open source parts of this at some point, but we're not completely there yet
But I'd look into just running your own gatsby preview. Less code, less work, probably better experience since it allows global preview (since we replace the nodes in the Gatsby datastore)
Thanks I might have a go at that.
[could even become a much sought after blog post]
Whoa.
I just got this working.
Simeon Griggs
Curious how you resolved this?
In the end, I didn’t. My use case was trying to use GROQ to create a live preview page in my Gatsby site, but I was able to solve this by setting up a real live preview version of the site that runs on Heroku…

https://www.simeongriggs.dev/roll-your-own-gatsby-live-preview-for-sanity
This is great! Thanks for writing the guide. Do you mind if I ask what size of site you are working on and what you ended up spending a month on Heroku? This is exactly what I need but budget is always really difficult to come by especially at the moment.
Also, your blog site is really nice. I like it a lot.
The site we used this on is very small, 30ish pages. So it works okay on a free Heroku plan. But others have said it doesn’t hold up for larger sites.
And thanks! I just threw the blog together!

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?