Solving live preview in Gatsby without $99/mo Gatsby Cloud

17 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, 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.

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.
user S
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?