Strategies for draft changes visible in preview but not production

4 replies
Last updated: Apr 22, 2020
Curious, what are some of your guys strategies for saving some changes in the studio as a draft, and thus make them visible in a site preview build, but not published to the live one?
AI Update

Great question! The key to this workflow is using perspectives to control which version of your content gets fetched. Here's how teams typically handle this:

The Core Strategy: Perspectives

Sanity's perspectives feature lets you query different views of your content. The most important ones for your use case are:

  • published - Only returns published documents (for your live site)
  • previewDrafts - Returns draft versions when they exist, otherwise falls back to published (for your preview builds)

Implementation with Next.js

The most common approach uses Next.js Draft Mode (formerly Preview Mode) to handle this automatically:

1. Set up different query configurations:

For your live site, use the published perspective:

const client = createClient({
  projectId: 'your-project',
  dataset: 'production',
  useCdn: true,
  apiVersion: '2025-02-19',
  perspective: 'published' // Only published content
})

For your preview build, use previewDrafts with authentication:

const previewClient = createClient({
  projectId: 'your-project',
  dataset: 'production',
  useCdn: false,
  token: process.env.SANITY_API_READ_TOKEN, // Required for drafts
  apiVersion: '2025-02-19',
  perspective: 'previewDrafts' // Drafts + published fallback
})

2. Enable Draft Mode in Next.js:

When editors click a preview link from Studio, it activates Draft Mode via a cookie, which tells your app to use the preview client instead of the production one. This means:

  • Draft changes appear in your preview deployment
  • Published content stays unchanged on your live site
  • No manual switching required

Alternative: GROQ Query Filtering

If you're not using Draft Mode, you can filter drafts directly in your GROQ queries:

For production (exclude drafts):

*[_type == 'post' && !(_id in path("drafts.**"))]

For preview (prioritize drafts):

*[_type == 'post'] | score(_id in path("drafts.**")) | order(_score desc)

This second query ranks draft documents higher, so they appear first when both versions exist.

How Draft/Published Documents Work

When you make changes in Studio without publishing, Sanity creates a draft document with an ID like drafts.post-123, while the published version stays as post-123. They exist as separate documents until you hit publish, which merges the draft into the published version.

The previewDrafts perspective automatically handles this by showing the draft version when it exists, or falling back to published if there's no draft—perfect for preview environments.

Best Practices

  1. Use environment variables to control which client/perspective gets used based on deployment environment
  2. Secure your preview token - never expose it in client-side code
  3. Consider using Visual Editing if you want editors to preview changes directly in Studio with the Presentation tool

This setup gives you the flexibility to iterate on drafts while keeping your live site stable!

Show original thread
4 replies
Hi Igor, are you looking to save a newly created document as a draft via Sanity’s HTTP API, for example? In that case you could prefix the document’s
_id
with
drafts.
as described over here: https://www.sanity.io/docs/http-mutations#create-c732f27330a4
Let me know if you were looking for something different
🙂
hi
user M
. Not sure this is quite it. For context, my use case is with gatsby.
This solution you pointed to, this is just for articles that have not yet been published right? What would be ideal I think is if I had some way to "publish" pages to a draft status, that a front-end could either build or not build, based on some flags set for prod or preview environments.

The issue to me really is that I don't know of a way to check what a page looks like in the front end without publishing the content. This leads to unfinished work being "published", and the hazard that it may get pushed out along with some other change that we want to push live
Thanks for the extra context! Indeed, what I suggested is just for when you create new documents using the API.
If I understand correctly, what you’re essentially looking for is a way to preview drafts in development and only published documents in production. When you make changes to a document in the Sanity Studio, these changes are saved in the draft version of the document until you hit “Publish”.

Assuming you’re using `gatsby-source-sanity`: have you tried adding a
token
and setting
overlayDrafts
to true? This will let you ‘overlay’ the draft version over the regular version of the document in development. If you want it to update on every keypress, you can also set
watchMode
to true.
The auth
token
you can create via manage.sanity.io > Your project > Settings > API. You’ll want to create a token with Read permissions in this case. Here is some additional information on keeping tokens secure, just in case: https://www.sanity.io/docs/keeping-your-data-safe
By settings things up this way, you should be able to preview drafts in development while only using published documents (and not drafts) in production.
Sounds like an intriguing option, thanks
user M
, going to try it out!

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?