Sanity Studio v3 launches Dec 8th - See it in action at Sanity Product Day →

Conditional fields

How to make fields conditionally show and hide based on other fields' values or on information about the current user.

Sometimes you want to reduce the cognitive load and the complexity of a content form by controlling the visibility of its fields, or make certain fields read-only under certain conditions. You can make fields in Sanity Studio's form appear and disappear using the hidden property, and make them read-only with the readOnly property on all field types, and also on fieldsets. This feature is commonly referred to as “conditional fields”. The hidden and readOnly properties can take a static true or false value or a callback function that contains the specific logic you want and returns true or false accordingly.

Gotcha

Conditional hidden and read-only fields require Sanity Studio versions 2.17.0 and 2.23.0, respectively. When the hidden or readOnly property uses a callback function in an earlier version of the studio, the field will always be hidden or read-only and the callback function will not be invoked (only booleans can be used for the hidden and readOnly properties in the studio prior to the version in which each was introduced).

Examples

Hide based on a value in the current document

Only show the subtitle field if the title field is truthy:

{
  name: 'subtitle',
  type: 'string',
  title: 'Subtitle',
  hidden: ({document}) => !document?.title
}

Set "read-only" based on the current user's role

Only show the productSKU field if the current user is an administrator:

{
  name: 'productSKU',
  type: 'string',
  title: 'SKU',
  readOnly: ({currentUser}) => {
    return !(currentUser.roles.find(({name}) => name === 'administrator'))
  }
}

Hide based on a value in a sibling field

Show or hide a sibling field if it's empty and the current field has a value:

{
  name: 'link',
  type: 'object',
  title: 'Link',
  fields: [
    {
      name: 'external',
      type: 'url',
      title: 'URL',
      hidden: ({ parent, value }) => !value && parent?.internal
    },
    {
      name: 'internal',
      type: 'reference',
      to: [{ type: 'route' }, { type: 'post' }],
      hidden: ({ parent, value }) => !value && parent?.external
    }
  ]
}

Set "read-only" on an entire field set

{
  name: 'product',
  type: 'document',
  title: 'Product',
	fieldsets: [
    {
      name: 'links',
      title: 'Links',
      options: {columns: 2},
      readOnly: ({document}) => document?.title === 'Hello world',
    }
  ],
  fields: [
		 {
      name: 'title',
      type: 'string',
      title: 'Title',
    },
    {
      name: 'external',
      type: 'url',
      title: 'URL',
			fieldset: 'links'
    },
    {
      name: 'internal',
      type: 'reference',
      to: [{ type: 'route' }, { type: 'post' }],
			fieldset: 'links'
    }
  ]
}

Gotcha

The hidden and readOnly properties only controls the user interface and will not remove data when active.

Gotcha

You can't return a promise to the hidden or readOnly properties. This is because of performance optimizations.

Editor Experience

Be mindful that Sanity Studio is a real-time collaborative application. That means that someone else can make a condition true that hides the field you're currently working in. You can consider mentioning if a field has a condition in its description, or by letting the content team know.

Reference

Callback properties

The hidden callback function takes an object as an argument with the following properties:

  • documentobject

    The current state of the document with all its values. Remember that it can return undefined. You can use optional chaining to avoid errors in the console, for example, document?.title.

  • parentobject | undefined

    The values of the field's parent. This is useful when the field is part of an object type. Remember that it can return undefined. You can use optional chaining to avoid errors in the console, for example, parent?.title.

    If it's a root field, it will contain the document's values.

  • valueany

    The field's current value.

  • currentUserobject

    The current user with the following fields:

    • email (string)
    • id (string)
    • name (string)
    • profileImage (string)role (string)
    • roles (array of objects with name, title, description)

Was this article helpful?