How to Differentiate between an Unpublished Document and a Published Draft from the API

7 replies
Last updated: Nov 21, 2024
Is there a way to differentiate between an
unpublished
document and a
published draft
from the sanity api?
AI Update

Yes! You can differentiate between an unpublished document and a published draft using perspectives and document IDs.

The key distinction is:

  • Unpublished document: Only exists as a draft with ID like drafts.post-123 (no published version exists)
  • Published draft: Both versions exist - post-123 (published) and drafts.post-123 (draft with changes)

Using Perspectives

The most straightforward approach is to use the published perspective when querying. This returns only published documents:

const client = createClient({
  // ... config
  perspective: 'published'
})

With this perspective:

  • Unpublished documents won't appear at all
  • Published documents appear even if they have drafts

Checking in Your Query Results

You can also check programmatically by looking at the _id:

  • If _id starts with drafts., it's a draft version
  • If the same document ID exists both with and without the drafts. prefix, it's a published document with draft changes
  • If only drafts.{id} exists (no corresponding published version), it's unpublished

GROQ Queries for Detection

To find only unpublished documents (never been published):

*[_id in path("drafts.**") && count(*[^._id == "drafts." + _id]) == 0]

To find published documents with draft changes:

*[count(*[_id in [^._id, "drafts." + ^._id]]) > 1]

To exclude all drafts from production queries:

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

The previewDrafts perspective is also useful for preview environments - it automatically prioritizes drafts over published versions when both exist, which is perfect for showing the latest changes before they go live.

oh actually, just realized that the draft creates a duplicate document - very clever
🙌 There's more about it here: https://www.sanity.io/docs/drafts
thanks
user Y
! 🎉
In the Studio interface, though, in the document list, there is no visual way to know which are draft vs published draft, is there?
like this?
Right, but if it's already published, and now is a new draft vs a non-published draft.
For anyone landing on this article from the public internet, it's probably a good idea to join the slack community. In there, you'll find more similar questions to this one, and you're more likely to end up finding the solution you're looking for.
For me, it was this query to find *unpublished drafts*:

*[_type == "yourSchemaType" && _id in path("drafts.**") && count(*[^._id == "drafts." + _id]) == 0]{_id}

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?