Adding validation for featured content and sorting an array by date in Sanity schema.

3 replies
Last updated: Dec 10, 2021
Hello there, i have a schema in which a field of
boolean
contain named as isFeatured. Now i want to do validation like if isFeatured is true in any doument, i shouldn't be able to make isFeatured true in any other document and it should show which document has already isFeatured true. How to add this kinda validation. Thanks.
AI Update

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:

  1. getClient() access: The validation context provides access to the Sanity client via context.getClient(), which allows you to query your dataset during validation.

  2. Excluding current document: The query uses _id != $id to exclude the current document, so you can save a document that already has isFeatured set to true without triggering a validation error.

  3. Informative error message: The error message tells the editor which document is already featured, making it easy to find and update if needed.

  4. Only validates when true: The validation only runs when isFeatured is true, 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 _type and field names to match your schema.
  • Replace title in the query with whatever field you want to display in the error message (or just use _id if 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.

Would be better to use a reference to the featured item from the content type on which another appears as featured? For example, if you wanted to feature a blog post on the home page, the home page would have a field for FeaturedItem where the content manager could select the appropriate blog post as a reference.
This is how i approach featured content 95% of the time. It saves on maintenance because you only have to go to one place to select the new featured item and you lose the risk that people will select too many items as featured.
Hi
user J
Thanks for your response, another thing i want to ask is that i have an array of object and i want to order by
dateOfPublication
which is a value in objects. I am unable to write query for it.
Here's the structure,


{

"_createdAt":"2021-12-08T09:17:40Z"

"_id":"73957312-c282-4cb3-be44-1069277610dd"

"_rev":"XXZQtLc37Lz6XK4fvqH5Wt"

"_type":"newsArticleBlock"

"_updatedAt":"2021-12-09T12:51:56Z"

"newsBlockTitle":"News Cards for Home Page"

"newsCardBlock":*[*

{

"_key":"85b48badc2c2"

"_type":"newsArticle"

"articleDescription":*[*...*]*_1 item_

"articleImage":*{*...*}*

"ctaLink":*{*...*}*

"dateOfPublication":"2021-12-09T08:02:00.000Z"

"headline":"The NRP Group Breaks Ground on a Record 21 Multifamily Apartment Communities in 2020"

"isFeatured":true

"selectedCategory":*{*...*}*_2 items_

"slug":*{*...*}*_2 items_

"subHeadline":"The NRP Group subheading"

}

*{*...*}*

*{*...*}*

*{*...*}*

]

}
Hi Mohammad. You can sort your array using the
order()
function. There are some details here but if you want to post your schema we can probably show you where you’d add it.

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.

Was this answer helpful?