Document operations provide methods to perform actions on documents through the Studio. All operations check permissions and document state before executing.
OperationsAPI
The operations API is returned by useDocumentOperation() and provides methods for document lifecycle management.
import {useDocumentOperation} from 'sanity'
function MyComponent({documentId, documentType}: Props) {
const ops = useDocumentOperation(documentId, documentType)
// Check if operation is available
if (!ops.publish.disabled) {
ops.publish.execute()
}
}
Operation Interface
All operations share a common interface:
interface Operation<ExtraArgs extends any[] = [], ErrorStrings extends string = string> {
disabled: false | ErrorStrings | 'NOT_READY'
execute(...extra: ExtraArgs): void
}
Returns false if the operation can be executed, or a string indicating why it’s disabled:
'NOT_READY' - Document state not yet loaded
- Operation-specific error strings (see individual operations below)
Executes the operation. Some operations accept additional arguments.
publish
Publishes the current draft version of a document.
Disabled States
'NOT_READY' - Document not loaded
'LIVE_EDIT_ENABLED' - Document type has live edit enabled
'ALREADY_PUBLISHED' - No unpublished changes
'NO_CHANGES' - Draft has no changes to publish
unpublish
Unpublishes a document, keeping only the draft version.
Disabled States
'NOT_READY' - Document not loaded
'LIVE_EDIT_ENABLED' - Document type has live edit enabled
'NOT_PUBLISHED' - Document is not published
delete
Deletes the document (both draft and published versions).
// Delete all versions
ops.delete.execute()
// Delete specific versions
ops.delete.execute(['draft'])
ops.delete.execute(['published'])
ops.delete.execute(['draft', 'published'])
Array of version identifiers to delete. If not provided, deletes all versions.
'draft' - Delete draft version
'published' - Delete published version
Disabled States
'NOT_READY' - Document not loaded
'NOTHING_TO_DELETE' - No document versions exist
discardChanges
Discards draft changes, reverting to the published version.
ops.discardChanges.execute()
Disabled States
'NOT_READY' - Document not loaded
'NO_CHANGES' - No draft changes to discard
'NOT_PUBLISHED' - Document has no published version to revert to
duplicate
Duplicates the document with a new ID.
// Simple duplication
ops.duplicate.execute('new-document-id')
// With document transformation
ops.duplicate.execute('new-document-id', {
mapDocument: (doc) => ({
...doc,
title: `${doc.title} (Copy)`,
})
})
The ID for the new duplicated document
Duplication optionsmapDocument
(doc: SanityDocumentLike) => SanityDocumentLike
Function to transform the document before creating the duplicate
Disabled States
'NOT_READY' - Document not loaded
'NOTHING_TO_DUPLICATE' - No document exists to duplicate
patch
Applies patches to a document.
ops.patch.execute([
{
set: {
title: 'New Title'
}
}
])
// With initial document for new documents
ops.patch.execute(
[{set: {title: 'Title'}}],
{_type: 'article'}
)
Array of patch operations to apply
Initial document to create if it doesn’t exist
commit
Commits pending mutations.
This operation batches and executes any pending mutations on the document.
restore
Restores a document to a previous revision.
import {type DocumentRevision} from 'sanity'
function RestoreButton({revision}: {revision: DocumentRevision}) {
const ops = useDocumentOperation(revision.documentId, revision.documentType)
return (
<button
onClick={() => ops.restore.execute(revision)}
disabled={!!ops.restore.disabled}
>
Restore this version
</button>
)
}
The document revision to restore
import {useDocumentOperation} from 'sanity'
import {Button} from '@sanity/ui'
function CustomPublishButton({id, type}: {id: string, type: string}) {
const ops = useDocumentOperation(id, type)
const canPublish = !ops.publish.disabled
const publishLabel = canPublish
? 'Publish'
: ops.publish.disabled
return (
<Button
text={publishLabel}
tone="positive"
disabled={!canPublish}
onClick={() => canPublish && ops.publish.execute()}
/>
)
}
Example: Bulk Operations
import {useClient, useDocumentOperation} from 'sanity'
function BulkPublisher({documentIds}: {documentIds: string[]}) {
const client = useClient({apiVersion: '2024-01-01'})
const publishAll = async () => {
const transaction = client.transaction()
for (const id of documentIds) {
// Build transaction with multiple publish mutations
const draftId = `drafts.${id}`
transaction.createIfNotExists({_id: id, _type: 'article'})
transaction.patch(id, patch => patch.set({
// Copy draft content to published
}))
transaction.delete(draftId)
}
await transaction.commit()
}
return <Button onClick={publishAll}>Publish All</Button>
}