Slug Generating Document Action - How to Invalidate Fields or Display an Error
When working with custom document actions in Sanity Studio, you have several options for handling validation, showing errors, and aborting the publish action. Here's what you can do:
Aborting a Publish Action
To abort a publish action, you control the flow in your custom action's onHandle method. The key is to not call the publish operation's execute() method when you want to abort:
import {useDocumentOperation} from 'sanity'
import {useToast} from '@sanity/ui'
export function CustomPublishAction(props) {
const {patch, publish} = useDocumentOperation(props.id, props.type)
const toast = useToast()
return {
disabled: publish.disabled,
label: 'Publish',
onHandle: () => {
// Validate your conditions
if (!props.draft?.slug?.current) {
// Show error and abort
toast.push({
status: 'error',
title: 'Cannot publish',
description: 'Document must have a slug before publishing'
})
// Don't call publish.execute() - this aborts the action
props.onComplete()
return
}
// If validation passes, proceed with publish
publish.execute()
props.onComplete()
}
}
}Showing Errors and User Feedback
You have multiple ways to display errors:
1. Using Toast Notifications (Recommended)
The useToast hook from @sanity/ui is the standard way to show feedback:
import {useToast} from '@sanity/ui'
const toast = useToast()
toast.push({
status: 'error', // 'success', 'warning', 'info'
title: 'Error title',
description: 'Detailed error message'
})2. Using Dialogs
For more complex validation that requires user interaction, you can use the dialog property as shown in the document actions documentation:
const [showDialog, setShowDialog] = useState(false)
return {
label: 'Publish',
onHandle: () => {
if (hasValidationErrors) {
setShowDialog(true)
return // Abort the publish
}
publish.execute()
},
dialog: showDialog && {
type: 'dialog',
header: 'Validation Error',
content: <div>Your custom error message and UI here</div>,
onClose: () => setShowDialog(false)
}
}Leveraging Built-in Validation
You can also use Sanity's built-in validation system by checking the document's validation status:
import {useValidationStatus} from 'sanity'
export function CustomPublishAction(props) {
const {validation} = useValidationStatus(props.id, props.type)
const hasErrors = validation.some(item => item.level === 'error')
return {
disabled: publish.disabled || hasErrors,
label: 'Publish',
onHandle: () => {
if (hasErrors) {
toast.push({
status: 'error',
title: 'Cannot publish',
description: 'Please fix validation errors first'
})
props.onComplete()
return
}
publish.execute()
props.onComplete()
}
}
}Key Points
- Always call
props.onComplete()when your action finishes, whether it succeeds or aborts - Don't call
execute()on the operation if you want to abort - The
disabledproperty can prevent the action from being triggered at all - Toast notifications are the most user-friendly way to show errors
- You can combine multiple validation approaches for robust error handling
The complete reference is available in the Document Actions documentation and 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.