
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeUnfortunately, Sanity Studio doesn't provide a built-in way to automatically hide the "Add Item" button when an array reaches its maximum validation length. The validation system will prevent publishing if the limit is exceeded, but the UI won't automatically adapt to disable or hide the add functionality.
However, you can achieve this with a custom input component that conditionally renders the array interface based on the current length. Here's the proper approach:
The key is to create a custom component that checks the array length against your validation rules and uses renderDefault with modified props to control the array's behavior:
// customArrayInput.js
import {ArrayOfObjectsInputProps} from 'sanity'
import {Stack, Text} from '@sanity/ui'
export function LimitedArrayInput(props: ArrayOfObjectsInputProps) {
const {value = [], schemaType} = props
// Extract max length from validation rules
const maxRule = schemaType.validation
?.flatMap(v => v._rules || [])
?.find(rule => rule.flag === 'max')
const maxLength = maxRule?.constraint
const currentLength = value.length
const isAtMax = maxLength && currentLength >= maxLength
// When at max, render with readOnly to prevent adding more items
if (isAtMax) {
return (
<Stack space={3}>
{props.renderDefault({
...props,
readOnly: true // This makes the entire array read-only
})}
<Text size={1} muted>
Maximum of {maxLength} items reached. Remove an item to add more.
</Text>
</Stack>
)
}
// Otherwise render normally
return props.renderDefault(props)
}Add the custom component to your array field definition using the components.input property:
import {defineField, defineArrayMember} from 'sanity'
import {LimitedArrayInput} from './customArrayInput'
export default defineField({
name: 'myArray',
type: 'array',
title: 'My Limited Array',
of: [
defineArrayMember({type: 'string'})
],
validation: Rule => Rule.max(2),
components: {
input: LimitedArrayInput
}
})The approach above uses readOnly: true, which makes the entire array read-only when the limit is reached. This means:
If you need users to be able to remove items while at the max (so they can swap items), you'll need a more complex solution that fully reimplements the array input rather than using renderDefault.
Another approach is to use conditional fields to make the entire array field read-only based on its length:
defineField({
name: 'myArray',
type: 'array',
of: [{type: 'string'}],
validation: Rule => Rule.max(2),
readOnly: ({value}) => (value || []).length >= 2
})This has the same limitation as above – the entire field becomes read-only at the limit.
The reason there's no simple "hide add button" option is that Sanity's array input component is complex, handling drag-and-drop reordering, item editing, validation display, and more. The renderDefault function gives you the complete default component, but you can't easily modify just one aspect of it (like hiding a specific button) without reimplementing the entire component.
For most use cases, the read-only approach above strikes a good balance between customization effort and user experience – it clearly communicates that the limit has been reached while preventing further additions.
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.
Content backend


The only platform powering content operations


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store