How to allow unique values in an array in Sanity.io schema.

6 replies
Last updated: Sep 21, 2023
how to allow this only one time for each,

export default defineType({

title: 'Component Builder',

name: 'pageBuilder',

type: 'array',

of: [

{

type: 'header',

validation: Rule => Rule.unique()

},

{

type: 'footer',

validation: Rule => Rule.unique()

},

],

})
AI Update

Looking at your code, you're trying to ensure that only one header and one footer can be added to the array. The Rule.unique() method you're using is actually for ensuring array items are unique within that array, but what you want is to limit each type to appearing only once.

Here's the correct approach - use custom validation on the array itself:

export default defineType({
  title: 'Component Builder',
  name: 'pageBuilder',
  type: 'array',
  of: [
    {
      type: 'header',
    },
    {
      type: 'footer',
    },
  ],
  validation: Rule => Rule.custom((items) => {
    if (!items) return true;
    
    const headerCount = items.filter(item => item._type === 'header').length;
    const footerCount = items.filter(item => item._type === 'footer').length;
    
    if (headerCount > 1) {
      return 'Only one header is allowed';
    }
    if (footerCount > 1) {
      return 'Only one footer is allowed';
    }
    
    return true;
  })
})

This custom validation function:

  1. Filters the array items by _type to count how many of each type exist
  2. Returns an error message if more than one header or footer is found
  3. Otherwise returns true to indicate the validation passed

The validation will run whenever someone tries to add items to the array and will prevent publishing if they try to add multiple headers or footers. The editor will see a clear error message telling them what the limit is.

Note that Rule.unique() is meant for ensuring values within an array don't duplicate (like ensuring all items in a tags array are different), not for limiting how many times a specific type appears. That's why you need the custom validation approach shown above.

You can create a custom validation on the array
https://www.sanity.io/docs/validation
already have
validation: Rule => Rule.unique()
but isnt working
done, thank you!
why don’t just add the header and the footer in separate fields?…. and the other components in the array?
^ or even better, create some setting documents containing all the header/footer info. Fetch it once and use it through the entire app. No need to rerender the header and footer on every route change (assuming you use some kind of frontend framework)

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?