Validate unique boolean field across documents in Sanity schema
You can achieve this with a custom validation rule that queries your dataset to check if any other document has isFeatured set to true. Here's how to implement it:
defineField({
name: 'isFeatured',
type: 'boolean',
title: 'Featured',
validation: (Rule) =>
Rule.custom(async (value, context) => {
// Only validate if isFeatured is being set to true
if (!value) return true
// Get the Sanity client
const client = context.getClient({ apiVersion: '2023-01-01' })
// Query for other documents with isFeatured = true
// Exclude the current document using its _id
const query = `*[_type == $type && isFeatured == true && _id != $id][0...2] {
_id,
title
}`
const params = {
type: context.document?._type,
id: context.document?._id || ''
}
const existingFeatured = await client.fetch(query, params)
// If another document is already featured, show an error
if (existingFeatured && existingFeatured.length > 0) {
const doc = existingFeatured[0]
return `Only one document can be featured at a time. "${doc.title || doc._id}" is already featured.`
}
return true
})
})Key points about this implementation:
getClient()access: The validation context provides access to the Sanity client viacontext.getClient(), which allows you to query your dataset during validation.Excluding current document: The query uses
_id != $idto exclude the current document, so you can save a document that already hasisFeaturedset to true without triggering a validation error.Informative error message: The error message tells the editor which document is already featured, making it easy to find and update if needed.
Only validates when true: The validation only runs when
isFeaturedistrue, so it doesn't unnecessarily query the database for every document save.
Important considerations:
- This validation only runs client-side in the Studio. If you're updating documents via the API, you'll need to implement the same logic server-side.
- Make sure to adjust the
_typeand field names to match your schema. - Replace
titlein the query with whatever field you want to display in the error message (or just use_idif you don't have a title field).
This approach uses custom validation with async operations, which is perfect for cases where you need to validate against other documents in your dataset.
Show original thread3 replies
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.