
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeGood news! When you import documents using the Sanity client, they're automatically published by default - you don't need to manually publish them in the Studio unless they have a drafts. prefix in their _id.
When importing documents, the publish state depends on the _id:
drafts. prefix (e.g., "_id": "abc-123") → Documents are published automaticallydrafts. prefix (e.g., "_id": "drafts.abc-123") → Documents remain as draftsIf you did import documents as drafts (with the drafts. prefix), you can publish them programmatically without clicking through the Studio. Here are your options:
createOrReplace (Recommended)The simplest approach is to use createOrReplace to create published versions:
import {createClient} from '@sanity/client'
const client = createClient({
projectId: 'your-project-id',
dataset: 'your-dataset',
token: 'your-token',
apiVersion: '2024-01-01',
useCdn: false
})
// Publish a draft by creating/replacing the published version
const draftId = 'drafts.abc-123'
const publishedId = draftId.replace('drafts.', '')
const draftDoc = await client.getDocument(draftId)
await client.createOrReplace({
...draftDoc,
_id: publishedId
})
// Optionally delete the draft
await client.delete(draftId)The easiest approach is to import documents without the drafts. prefix in the first place:
const documents = [
{
_id: 'post-123', // No 'drafts.' prefix
_type: 'post',
title: 'My Post',
// ... other fields
}
]
documents.forEach(doc => {
await client.createOrReplace(doc)
})There's a UI quirk that can be confusing: even for published documents, the Studio shows a "Publish" button (greyed out) rather than "Published" when you navigate back to a document. This is just a UI state - the document is still published. You can verify by querying without the previewDrafts perspective or checking if the document appears in your frontend.
As one community member discovered: "Maybe they are 'published' even though they say 'Publish' in localhost:3333 and not 'Published'. Because I can see them in graphql deploys playground"
For bulk operations, you can create a migration script:
npx sanity@latest migration create publishDraftsThen implement the migration to publish all drafts:
import {defineMigration} from 'sanity/migrate'
export default defineMigration({
title: 'Publish all draft documents',
documentTypes: ['post'], // specify your types
filter: '_id in path("drafts.**")',
migrate: {
document(doc, context) {
// Create published version
const publishedId = doc._id.replace('drafts.', '')
return {
...doc,
_id: publishedId
}
}
}
})Imported documents are published by default unless you explicitly add the drafts. prefix to their IDs. No manual Studio work required! If you need to publish drafts programmatically, use createOrReplace with the non-draft ID, or better yet, import without the draft prefix from the start.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store