Is there a way to conditionally render fields in a document?

3 replies
Last updated: Sep 25, 2020
Hey everyone. In the studio, I want the user to choose between uploading an image, or a file. Is there a way to conditionally render fields in a document?
AI Update

Yes, you can absolutely conditionally render fields in Sanity Studio using the conditional fields feature. This is exactly what you need for your image vs. file upload scenario.

Here's how you can set it up:

{
  name: 'uploadType',
  type: 'string',
  title: 'Upload Type',
  options: {
    list: [
      {title: 'Image', value: 'image'},
      {title: 'File', value: 'file'}
    ]
  }
},
{
  name: 'imageUpload',
  type: 'image',
  title: 'Image',
  hidden: ({parent}) => parent?.uploadType !== 'image'
},
{
  name: 'fileUpload',
  type: 'file',
  title: 'File',
  hidden: ({parent}) => parent?.uploadType !== 'file'
}

The hidden property accepts a callback function that receives useful parameters like parent (the parent object), document (the entire document), and value (the current field value). When the callback returns true, the field is hidden; when it returns false, the field is shown.

In this example, the user first selects their upload type from a dropdown, and then only the relevant upload field appears. This keeps the interface clean and focused on what's actually needed.

Important note about validation: If you mark either upload field as required, be aware that hidden required fields still enforce validation. You'll need to implement conditional validation like this:

{
  name: 'imageUpload',
  type: 'image',
  hidden: ({parent}) => parent?.uploadType !== 'image',
  validation: (Rule) =>
    Rule.custom((currentValue, {parent}) => {
      return parent?.uploadType === 'image' && !currentValue
        ? 'An image is required when upload type is image.'
        : true
    })
}

This feature has been available since Studio v2.17.0 and works great for reducing cognitive load by showing users only the fields they need!

Hi Erlend ๐Ÿ‘‹ Conditional fields will be easier in the future, but you can already set this up using a custom input component. This snippet lets you use a boolean type field as a condition for another field or object to show: https://github.com/sanity-io/sanity-recipes/blob/39d2fb0d079fec3a60dc1f13d6abbf6f4e3ae037/snippets/conditionalFieldsCustomInputComponent.js
There are variations of the above in case you need something more flexible, so just let me know if this isnโ€™t enough for your use case
๐Ÿ™‚
Thank you! ๐Ÿ™‚
Curious if there's a way to acheive this without the need to create a custom component. Something along the lines of:

export default {
  name: "page",
  title: "Page",
  type: "document",
  fields: [
    {
      name: "mood",
      type: "string",
      description: "How do you feel?",
      options: {
        list: [
          { title: "Good", value: "good" },
          { title: "Bad", value: "bad" },
        ],
      },
    },
    {
      name: "details",
      type: "string",
      description: "Why?",
      options: {
        condition: mood === 'bad',
      },
    },
  ],
};

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?