Sanity preview: draft revisions inconsistent and sometimes unavailable
I can see the issue you're running into. Using _rev for draft previews isn't the recommended approach, and this explains the inconsistent behavior you're experiencing.
Why _rev Doesn't Work Well for Previews
The _rev field is an internal revision identifier that changes with every mutation, and there are a couple of problems with using it:
Revisions don't persist after publishing: When you publish a document, the draft revision history is essentially collapsed. Old
_revvalues from drafts become inaccessible once the document is published, which explains why "publishing new revisions makes old revisions go away." According to the History API documentation, after your plan's retention period (3-365 days depending on your plan), older revisions are truncated, but more importantly for your case, the draft revision chain doesn't survive publishing in a queryable way via_rev==.Race conditions with
_rev: The_revvalue you see in the Studio might not be the latest by the time you click the preview link, especially if there are multiple edits happening quickly or if the document is being auto-saved. This explains why you sometimes get no data back - the revision you're querying for may have already been superseded by a newer save.
The Right Approach: Use Perspectives
Instead of using _rev, you should use Sanity's perspective system. This is specifically designed for draft previews:
// In your data fetching code
const perspective = searchParams.get('perspective') === 'previewDrafts'
? 'previewDrafts'
: 'published';
const data = await client.fetch(query, params, {
perspective,
// Include your token for authentication
});The previewDrafts perspective automatically returns draft versions when they exist (documents with IDs prefixed by drafts.), falling back to published versions when they don't. This is much more reliable than trying to target specific revisions.
When you configure the Presentation Tool, it passes the perspective through to your preview URL, and your app should use that to determine which version of the content to fetch - not _rev.
Alternative: History API for True Historical Access
If you truly need to access specific historical revisions (not just current drafts), you should use the History API instead of _rev in queries. The History API provides dedicated endpoints like:
https://${projectId}.apicdn.sanity.io/v1/data/history/${dataset}/documents/${docId}?time=${time}This gives you consistent access to document states at specific points in time, but note that this is for historical access, not real-time draft previewing. The History API is more appropriate for features like "view this page as it was on December 1st" rather than "preview my current draft."
Why Perspectives Are Better
- No race conditions: The perspective system always gets the current draft state, not a specific revision that might be stale
- Survives publishing: Draft access doesn't break when you publish - the perspective just starts returning the published version
- Built for this use case: It's the official way to handle draft previews and works seamlessly with the Presentation Tool
- Simpler queries: No need to manually handle
_rev==conditions in your GROQ queries
The _rev parameter was never intended for preview functionality, which is why you're seeing these consistency issues. Switch to perspectives and your preview system should work reliably. The Presentation Tool is designed to work with perspectives out of the box, so you'll be working with the grain of the platform rather than against it.
Show original thread1 reply
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.