How to perform a "publish" through the API/JavaScript client in Sanity.io

2 replies
Last updated: Jul 21, 2020
Is there a way to perform a “publish” through the API/JavaScript client? (We’d like to add a “publish all drafts” button)
AI Update

Yes, you can absolutely perform a "publish" through the API/JavaScript client! In Sanity, publishing is essentially copying a draft document to its published version by manipulating the document IDs.

How Publishing Works in Sanity

Sanity uses a draft/publish system where:

  • Draft documents have IDs prefixed with drafts. (e.g., drafts.my-document-id)
  • Published documents have the same ID without the prefix (e.g., my-document-id)

Publishing via the API

To publish a document programmatically using the JavaScript client, you can use the createOrReplace mutation. Here's how:

import {createClient} from '@sanity/client'

const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  token: 'your-token-with-write-access',
  apiVersion: '2025-01-01',
  useCdn: false
})

// Publish a single document
async function publishDocument(documentId) {
  // Fetch the draft
  const draft = await client.getDocument(`drafts.${documentId}`)
  
  if (!draft) {
    throw new Error('Draft not found')
  }
  
  // Remove the drafts. prefix from _id
  const {_id, ...documentWithoutId} = draft
  
  // Create or replace the published version
  return client.createOrReplace({
    ...documentWithoutId,
    _id: documentId,
    _type: draft._type
  })
}

Publishing All Drafts

For your "publish all drafts" button, you could do something like this:

async function publishAllDrafts() {
  // Query all draft documents
  const drafts = await client.fetch(
    `*[_id in path("drafts.**")]`
  )
  
  // Create a transaction to publish them all
  const transaction = client.transaction()
  
  drafts.forEach(draft => {
    const publishedId = draft._id.replace('drafts.', '')
    const {_id, ...doc} = draft
    
    transaction.createOrReplace({
      ...doc,
      _id: publishedId
    })
  })
  
  return transaction.commit()
}

Important Considerations

  1. Authentication: You'll need a token with write permissions to publish documents
  2. Validation: The API doesn't enforce Studio-defined schema rules, so you may want to validate documents before publishing
  3. Transactions: Using transactions ensures atomic operations when publishing multiple documents
  4. References: Make sure any references in your documents point to published documents (or use weak references if referencing drafts)

This approach gives you full programmatic control over publishing, which is perfect for building custom workflows, scheduled publishing, or bulk operations like your "publish all drafts" button!

One way to accomplish this would be using the
@sanity/react-hooks
package to run a
publish.execute()
operation using
useDocumentOperation(id, type)
- https://www.sanity.io/docs/studio-react-hooks#usedocumentoperation-c3cb2ad19cf3
Or you could probably just remove the
drafts.
prefix from the
_id
value to achieve the same 🙂
ah thanks peter, I’ll take a look

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?