Index
Edit

Validation

The content studio allows you to specify validation rules on your document types and fields. Field-level validation is the most specific and gives the content studio a better chance to help the user understand where the validation failed and why, whereas the document-level validation provides slightly more control since it can validate based on the values of the entire document.

Pro-tip

Validation is currently only done client side (within the content studio). In the future, non-custom rules will be synchronized and run on the server as well. This is why we recommend you use the built-in validation methods as much as possible, resorting to custom validation only where absolutely necessary.

Basics

Validation is defined by setting the validation property on a document type or field. It takes a function which receives a Rule as the first argument. By calling methods on this rule, you add new validation modifiers. Here's an example which validates that a string field has a value and that the string is between 10 and 80 characters long:

{
  title: 'Title',
  name: 'title',
  type: 'string',
  validation: Rule => Rule.required().min(10).max(80)
}

Without the required() call, the title is also considered valid if it does not have a value.

Error levels and error messages

By default, values that do not pass the validation rules are considered errors - these will block the draft from being published until they have been resolved. You can also set a rule to be a warning, simply by calling warning() on the rule. Similarily, you can customize the error message displayed by passing a string to the warning() or error() method:

{
  title: 'Title',
  name: 'title',
  type: 'string',
  validation: Rule => Rule.max(50).warning('Shorter titles are usually better')
}

If you want to combine both warnings and errors in the same validation set, you can use an array:

{
  title: 'Title',
  name: 'title',
  type: 'string',
  validation: Rule => [
    Rule.required().min(10).error('A title of min. 10 characters is required'),
    Rule.max(50).warning('Shorter titles are usually better')
  ]
}

Referencing other fields

Sometimes you may want to build a rule that is based on the value of a different field. By calling the Rule.valueOfField method, you can achieve this.

{
  title: 'Start date',
  name: 'startDate',
  type: 'datetime',
  validation: Rule => Rule.required().min('2018-03-01T15:00:00.000Z')
},
{
  title: 'End date',
  name: 'endDate',
  type: 'datetime',
  validation: Rule => Rule.required().min(Rule.valueOfField('startDate'))
}

Note however that it only allows referencing sibling fields. If you need to refer to things outside of this scope, you will have to use document-level validation.

Custom validation

Sometimes you will need to validate values beyond what Sanity provides. The custom() method allows you to do this. It takes a function as the first argument, and should return either true (in case of a valid value) or an error message as a string in the case of an invalid value. You may also return a promise which resolves with the same return values should you need to do asyncronous operations:

{
  name: 'location',
  type: 'geopoint',
  title: 'Location of bar',
  description: 'Required, must be in Norway',
  validation: Rule =>
    Rule.required().custom(geoPoint =>
      someGeoService
        .isWithinBounds(
          {
            latitude: geoPoint.lat,
            longitude: geoPoint.lng
          },
          someGeoService.BOUNDS_NORWAY
        )
        .then(isWithinBounds => (isWithinBounds ? true : 'Location must be in Norway, somewhere'))
    )
}

Please note that custom validators are also run on undefined values, unless the rule is explicitly set as optional by calling Rule.optional(). This allows for conditionally allowing undefined values based on some external factor, with the slight drawback that you need to make sure your functions check for undefined values. Here's an example:

{
  name: 'breweryName',
  type: 'string',
  title: 'Brewery name',
  validation: Rule => Rule.custom(name => {
    if (typeof name === 'undefined') {
      return true // Allow undefined values
    }
    
    // This would crash if we didn't check
    // for undefined values first
    return name.startsWith('Brew')
      ? 'Please be more creative'
      : true
  })
}

Disabling validation

Sometimes you can set validation: false on a document or a field to disable it.

Gotcha

Validation is run whenever changes are made to the document. We will provide a way to only validate on publish in the future. Keep this in mind when doing asyncronous operations against external APIs and similar.

Reference

Validation rules are available based on the underlying data type of the field or document.

Common (all data types)

  • required() - Ensures that this field exists. Disallowed values differ slightly per type:
    • Strings: undefined, null, ''
    • Objects: undefined, null, {}
    • Arrays: undefined, null, []
    • All others: undefined, null
  • custom(fn) - Creates a custom validation rule. More information above.

String

  • min(minLength) - Minimum length of string
  • max(maxLength) - Maximum length of string
  • length(exactLength) - Required, exact length of string
  • uppercase() - All characters must be uppercase
  • lowercase() - All characters must be lowercase
  • regex(pattern[, name, options]) - String must match the given pattern.
    • Providing a name will make the message more understandable to the user ("Does not match the <name>-pattern")
    • options is an optional object, currently you can set options.invert to true in order to allow any value that does NOT match the pattern.

Number

  • min(minNumber) - Minimum value (inclusive)
  • max(maxNumber) - Maximum value (inclusive)
  • lessThan(limit) - Value must be less than the given limit
  • greaterThan(limit) - Value must be greater than the given limit
  • integer() - Value must be an integer (no decimals)
  • precision(limit) - Specifies the maximum number of decimal places allowed
  • positive() - Requires the number to be positive (>= 0)
  • negative() - Requires the number to be negative (< 0)

Datetime

  • min(minDate) - Minimum date (inclusive). minDate should be in ISO 8601 format.
  • max(maxDate) - Maximum date (inclusive). maxDate should be in ISO 8601 format.

Array

  • unique() - Requires all values within the array to be unique. Does a deep comparison, only excluding the _key property when comparing objects.
  • min(minLength) - Minimum number of elements in array
  • max(maxLength) - Maximum number of elements in array
  • length(exactLength) - Exact number of array elements to allow

URL

  • uri(options) - Validates a URI with the given options. By default, allows only http/https URLs.
    • scheme - String, RegExp or Array of schemes to allow (default: ['http', 'https'])
    • allowRelative - Whether or not to allow relative URLs (default: false)
    • relativeOnly - Whether to only allow relative URLs (default: false)

Previous: Preview content on siteNext: Drafts