Accessing document values in custom document actions and displaying custom error messages
Yes, you can absolutely access document values in custom document actions! The action component receives props that include both draft and published versions of the document.
Here's what you get access to in your custom document action props:
props.draft- The draft version of the document (if it exists)props.published- The published version of the document (if it exists)props.id- The document IDprops.type- The document schema type
Basic Example
Here's a simple custom publish action that accesses document values:
export function CustomPublishAction(props) {
const doc = props.draft || props.published
return {
label: 'Publish',
onHandle: () => {
// Access any field from the document
console.log('Title:', doc?.title)
console.log('Slug:', doc?.slug?.current)
// Your custom logic here
}
}
}Real-World Example: Conditional Publishing
Here's a more practical example that checks document values before publishing:
import {useState, useEffect} from 'react'
import {useDocumentOperation} from 'sanity'
export function ConditionalPublishAction(props) {
const {patch, publish} = useDocumentOperation(props.id, props.type)
const [isPublishing, setIsPublishing] = useState(false)
const doc = props.draft || props.published
const hasRequiredFields = doc?.title && doc?.slug
useEffect(() => {
if (isPublishing && !props.draft) {
setIsPublishing(false)
}
}, [props.draft])
return {
disabled: publish.disabled || !hasRequiredFields,
label: isPublishing ? 'Publishing…' : 'Publish',
onHandle: () => {
setIsPublishing(true)
// Set publishedAt based on document values
if (!doc.publishedAt) {
patch.execute([{set: {publishedAt: new Date().toISOString()}}])
}
publish.execute()
props.onComplete()
},
}
}Using with Dialogs
You can also use document values in dialog flows:
export function EditTitleAction({id, type, published, draft}) {
const doc = draft || published
const [documentTitle, setDocumentTitle] = useState(doc?.title)
return {
label: 'Edit title',
dialog: {
type: 'dialog',
header: 'Edit Title',
content: (
<input
value={documentTitle}
onChange={(e) => setDocumentTitle(e.target.value)}
/>
)
}
}
}The key thing to remember is that props.draft and props.published give you full access to all document field values, so you can read any data you need to make decisions or display information in your custom actions.
For more details, check out the Document Actions documentation and the Document Actions API reference.
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.