Troubleshooting a groq query with a reference in Sanity.io
This is a classic issue with perspectives and draft documents in Sanity! Based on similar cases in the community, here's what's happening:
The Problem: Vision Shows Drafts by Default
The Vision plugin in Sanity Studio queries with a different default perspective than your client code. Vision typically shows you draft documents (documents with IDs prefixed by drafts.), while your client code by default only queries published documents.
When you dereference with the -> operator (like link->slug.current), Vision successfully resolves the reference because it can see the draft document. But your client code can't see that draft, so the dereferencing fails silently and you don't get the slug field.
The Solution: Align Your Perspectives
You have a few options:
1. Publish Your Documents (Simplest)
Make sure the documents you're referencing are actually published (not just drafts). In Studio, click the "Publish" button on any draft documents. This is what happened in the community thread I found - the generalSettings document had _id: "drafts.us-generalSettings" which wasn't visible to the unauthenticated client.
2. Use an Authenticated Client with Token (For Preview Mode)
If you need to see drafts in your application (like for preview functionality), configure your client with a read token and use the previewDrafts perspective:
import {createClient} from '@sanity/client'
const client = createClient({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2024-01-01',
useCdn: false,
token: process.env.SANITY_API_READ_TOKEN, // Required for drafts
perspective: 'previewDrafts', // This prioritizes drafts over published
})3. Check Your API Version Perspective Default
As of the 2025-02-19 API version, the default perspective changed to published (previously raw). Make sure you're explicitly setting the perspective you want:
const result = await client.fetch(query, params, {
perspective: 'published' // or 'previewDrafts' for preview mode
})Why This Happens
The reference access operator (->) internally executes a subquery to fetch the referenced document. If that document only exists as a draft (ID: drafts.your-doc-id) and your client is querying with the published perspective, the reference resolves to null, and you won't see any fields from it.
Quick Diagnostic
Run this query in both Vision and your client to see what's being returned:
*[_type == "page" && slug.current == 'values-and-beliefs'][0] {
blocks[] {
_type,
"linkRef": link._ref,
"linkResolved": link->{_id, slug}
}
}If Vision shows the resolved data but your client doesn't, you've confirmed it's a perspective/draft issue. Look for any _id fields starting with drafts. - those are your culprits!
Show original thread26 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.