Using conditional fields to set up an object with multiple types in Sanity.io.
Great question! Unfortunately, Sanity doesn't have a built-in "union type" or of property for single object fields. The of property is exclusively available for array types, not object types. However, there are several approaches you can use to achieve similar functionality:
Option 1: Array with maxLength of 1 (Your Current Approach)
This is actually a pretty common pattern and is arguably the "cleanest" native solution:
{
name: 'lead',
type: 'array',
validation: Rule => Rule.max(1).required(),
of: [
{type: 'heroLead'},
{type: 'basicLead'}
]
}While it might feel a bit awkward, this approach has some advantages:
- Native Sanity support with no custom code
- Clear UI for selecting between different types
- Works seamlessly with validation and previews
- Supports copy/paste operations between compatible fields
Option 2: Conditional Fields with a Discriminator
You can use a string field as a "type selector" and then conditionally show/hide different object fields based on that selection using conditional fields:
{
name: 'lead',
type: 'object',
fields: [
{
name: 'leadType',
type: 'string',
options: {
list: [
{title: 'Hero Lead', value: 'hero'},
{title: 'Basic Lead', value: 'basic'}
]
}
},
{
name: 'heroLead',
type: 'heroLead',
hidden: ({parent}) => parent?.leadType !== 'hero'
},
{
name: 'basicLead',
type: 'basicLead',
hidden: ({parent}) => parent?.leadType !== 'basic'
}
]
}This creates a discriminated union pattern where only the relevant object type shows based on the selection. The downside is you'll need to handle the extra nesting in your queries and potentially add conditional validation to ensure the correct variant is filled out.
Option 3: Reference Field
If your lead types are actually separate documents (or could be), you could use a reference field that can point to multiple document types:
{
name: 'lead',
type: 'reference',
to: [
{type: 'heroLead'},
{type: 'basicLead'}
]
}This works well if the lead content should be reusable across multiple pages.
Recommendation
For your use case, I'd actually stick with Option 1 (array with max(1)). While it might seem less elegant, it's the most straightforward approach that leverages Sanity's native features without custom complexity. The Studio UI handles it well with a nice type picker, and your queries will be simpler since you're just accessing lead[0] rather than dealing with conditional field structures or checking which variant field is populated.
If the array approach really bothers you, Option 2 with conditional fields gives you a true single object field, but you'll trade that for more complex schema configuration and query logic to determine which variant is active.
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.