How to fetch draft or published document (whichever is displayed) in GROQ?
Great question! This is a common need when working with Sanity's draft/published workflow. The recommended approach is to use Sanity's built-in perspectives feature, specifically the previewDrafts perspective.
Using the previewDrafts Perspective (Recommended)
When you configure your Sanity client with perspective: 'previewDrafts', the API automatically returns draft documents when they exist and falls back to published documents when there's no draft:
const client = createClient({
// ... other config
perspective: 'previewDrafts',
useCdn: false // Important: CDN doesn't support perspectives
})Then your GROQ query can be straightforward:
*[_type == 'post' && slug.current == "my-slug"][0]The previewDrafts perspective handles all the draft-or-published logic for you automatically. This is particularly useful for preview environments where editors want to see their unpublished changes.
Alternative: Manual GROQ Pattern
If you need to handle this logic directly in your GROQ query (for example, if you can't configure the client perspective), you can use the score() function:
*[_type == 'post' && slug.current == "my-slug"]
| score(_id in path("drafts.**"))
| order(_score desc)[0]This works by:
- Filtering for your document(s) as usual
- Using
score()to assign a higher score to draft documents (those with IDs matching thedrafts.**path pattern) - Sorting by score in descending order (drafts first)
- Taking the first result
[0]
So if a draft exists, it comes first; otherwise, the published version is returned.
Why This Matters
Remember that in Sanity, draft documents have IDs prefixed with drafts. (e.g., drafts.post-123), while published documents use the base ID (e.g., post-123). Without one of these approaches, a basic query might return both versions of the same document, which is usually not what you want.
For most use cases, I'd recommend using the previewDrafts perspective as it's cleaner and more maintainable!
Show original thread6 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.