← All notes
CMS Implementation7 min

A content release is not a draft

Campaign launches used to live in Studio as a pile of drafts labeled DO NOT PUBLISH, or as a staging dataset nobody trusted. Sanity Content Releases give those changes a separate version dimension: a named bundle you can preview, schedule, and publish together. We still see teams treat a release like a draft — flip previewDrafts / the drafts perspective, open Presentation, and call it the launch. That view applies every in-flight Studio edit. A release is a stack. A draft is someone's unfinished save.

Two different unfinished states

A draft document is the working copy of one record. It sits on the drafts. path, pairs with a published sibling when one exists, and disappears into the live document when you hit Publish. That model is right for "I am editing the about page."

A Content Release holds versions of many documents that should go live together — homepage hero, three notes, a case study tile, a nav label. Those versions live under versions.* IDs. Publishing the release applies the bundle; publishing a single draft does not.

Collapsing the two into "unpublished content" is how editors lose the launch shape. The unfinished about-page typo and the intentional Black Friday swap are not the same kind of pending. The Content Lake already separates them. Your preview client has to respect that separation.

Preview the release with a perspective stack

Perspectives let the same GROQ run against a different view of the dataset. published is what production should use. drafts (formerly previewDrafts) returns the dataset as if every draft were published. A release preview is neither: you pass a stack of release names, layered left to right, with published automatically under the bottom.

That stack is the launch. Query with perspective: ['black-friday-2026'] and you see published content plus only the documents in that release. Add a second release to the left if two campaigns overlap and you need a known precedence. Append drafts only when you deliberately want personal in-progress edits on top — which is rarely what stakeholders mean by "show me the campaign."

We already keep preview credentials and draft-aware fetches on the request, not on a shared public client. The same discipline applies here: the release id belongs in the preview session that Presentation or a signed preview URL opens, not in the default client every visitor shares.

Why drafts perspective lies about a launch

Enable drafts and you get every Studio scratch pad: half-written notes, abandoned hero experiments, the FAQ someone opened and never closed. Stakeholders reviewing a release see noise that is not in the release. They either lose trust in preview or ask you to "clean Studio" before the demo — which is the old DO NOT PUBLISH ritual with better tooling nearby.

The failure is category error, not a bug in Presentation. drafts answers "what if everything currently being edited went live?" A release answers "what if this named set of versions went live on top of published?" Those questions share a UI surface and almost never share an answer.

API version 2025-02-19 made published the default perspective for a reason. Older snippets that omit perspective or still assume raw will mix drafts, versions, and published in authenticated queries. Pin the API version, set published in production, and reserve stacks for preview routes that know which release they are showing.

What we wire on a Sanity site

Production client: perspective published, CDN on, no draft token. Preview route: validate a short-lived secret, then withConfig a client with useCdn: false and perspective set to the release name from the preview payload — or to drafts only for "my current edits," never as a stand-in for a named release.

Studio Presentation gets the release context from the release tool / Actions API so the overlay opens the version document in that release, not the ambient draft. If click-to-edit lands on drafts. while the banner says you are previewing a release, the stack and the edit intent have drifted.

Scheduling stays a content concern. A release with a publish time is still content-layer scheduling — the same idea as filtering on publishedAt — not a redeploy. The frontend does not need a cron that "turns on" the campaign if publish already moved the versions into published.

What we check before calling release preview done

Open the release preview URL. Confirm a document that exists only as a personal draft and is not in the release does not appear. Confirm a document in the release does. Publish is still blocked from that view; the stack is read-through, not a soft publish.

Flip the same route to drafts perspective once as a negative test. If the page suddenly fills with unrelated WIP, you have proved the two modes diverge — and that stakeholders must never be handed the drafts link labeled as the launch.

Document the three clients in the handover: published for production, release stack for campaign QA, drafts for editor self-preview. If the team only has one "Preview" bookmark, they will keep treating the release like a draft, and the tooling will keep agreeing with them.

Questions

When should we still use the drafts perspective?
When an editor wants to see their own in-progress saves on the real layout before those changes join a release or get published. That is self-preview. It is not campaign QA.
How is this different from scheduling with publishedAt?
A publishedAt filter hides a single document until a clock passes. A release coordinates many document versions as one publish action and one preview stack. Use both when a note has its own go-live time and a campaign still needs a bundle.
Is raw ever right for the public site?
No. raw returns drafts, versions, and published side by side for authenticated queries. Production should use published. Keep raw for tooling that needs to inspect every ID path.

Sources

  1. Sanity Perspectives for Content Lake — published / drafts / raw and release perspective stacks; published default since API 2025-02-19.
  2. Introducing Content Releases — Coordinated versions, Actions API, and why DO NOT PUBLISH drafts were the old pattern.
  3. Content Releases cheat sheet — Perspective arrays, layering order, drafts append behavior.
  4. Related: Preview drafts belong on the request
  5. Related: Scheduled posts are a query filter, not a redeploy

Have something to build?

Tell us what you're working on and we'll tell you honestly whether we're the right fit.

Work with us