Accessing validation rules in Sanity v3 custom components

3 replies
Last updated: Jan 27, 2026
I know I've asked this before... but I can't find the answer anywhere, apologies.
In v2, when creating custom components, we could access the validation rules of a field to provide data back to the custom components. (see
here for v2 docs example)
Schema data example:

validation: Rule => Rule.max(100)

and in the custom component example:


import { TextInput, Stack, Text } from '@sanity/ui'

...

const MaxConstraint = type.validation[0]._rules.filter(rule => rule.flag == 'max')[0].constraint

const handleChange = React.useCallback(
  (event) => {
    const inputValue = event.currentTarget.value
      onChange(PatchEvent.from(inputValue ? set(inputValue) : unset()))
  },
  [onChange]
)

...

<Text muted size={1}>{value ? value.length : '0'} / {MaxConstraint}</Text>
Unfortunately, the v3 docs don't provide much insight into accessing the validation rules now. Any examples that someone could share?
AI Update

In Sanity Studio v3, accessing validation rules in custom input components works differently than in v2. The internal _rules structure you used in v2 is no longer directly accessible in the same way.

In v3, custom input components receive their props through a different structure. Here's what you need to know:

The v3 Approach

Your custom input component receives a schemaType prop that contains schema information about the field. While you can't directly access the internal _rules array like you could in v2, you have a couple of options:

Option 1: Access validation through schemaType

The schemaType prop contains the validation rules, though the structure is different from v2. Here's how you can work with it:

import { TextInput, Stack, Text } from '@sanity/ui'
import { set, unset } from 'sanity'

export const MyCustomInput = (props) => {
  const { elementProps, onChange, value = '', schemaType } = props
  
  // Access validation from schemaType
  const validation = schemaType.validation
  
  // You can inspect the validation rules
  // Note: The structure is different from v2's _rules
  let maxConstraint = null
  
  if (validation && Array.isArray(validation)) {
    validation.forEach(rule => {
      // The rule structure in v3 is different - you'll need to inspect it
      // You might need to call the rule to get constraints
      const ruleSpec = rule(schemaType)
      // Extract max constraint from ruleSpec
    })
  }
  
  const handleChange = (event) => {
    const inputValue = event.currentTarget.value
    onChange(inputValue ? set(inputValue) : unset())
  }
  
  return (
    <Stack space={2}>
      <TextInput {...elementProps} onChange={handleChange} value={value} />
      <Text muted size={1}>
        {value ? value.length : '0'} {maxConstraint && `/ ${maxConstraint}`}
      </Text>
    </Stack>
  )
}

Rather than trying to extract validation rules from the schema, the v3 approach encourages you to be more explicit. If you need a max constraint in your custom component, pass it as an option:

// In your schema
defineField({
  name: 'title',
  type: 'string',
  validation: Rule => Rule.max(100),
  components: {
    input: MyCustomInput
  },
  options: {
    maxLength: 100  // Explicitly pass the constraint
  }
})

Then access it via schemaType.options:

export const MyCustomInput = (props) => {
  const { elementProps, onChange, value = '', schemaType } = props
  const maxLength = schemaType.options?.maxLength
  
  // Now you can use maxLength in your component
  return (
    <Stack space={2}>
      <TextInput {...elementProps} onChange={handleChange} value={value} />
      <Text muted size={1}>
        {value ? value.length : '0'} {maxLength && `/ ${maxLength}`}
      </Text>
    </Stack>
  )
}

Why the change?

In v3, Sanity moved away from exposing internal implementation details like _rules. The validation system is more abstracted now, which makes it more flexible but also means you can't peek into its internals the same way.

The options approach is cleaner and more maintainable - you're being explicit about what your custom component needs rather than relying on parsing internal validation structures.

If you absolutely need to extract validation constraints programmatically, you may need to inspect the schemaType.validation array more carefully, but be aware this is working against the grain of v3's design philosophy and may be fragile across updates.

Show original thread
3 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.

Was this answer helpful?