Auto-fill subtitle field from title field in Sanity schema
Yes, you can auto-fill one field based on another in Sanity! There are several approaches depending on what you need:
1. Custom Input Component with useFormValue (Real-time Updates)
The most powerful approach is creating a custom input component that uses the useFormValue hook to read values from other fields in real-time:
import {useCallback} from 'react'
import {Stack, Text, TextInput} from '@sanity/ui'
import {set, unset, useFormValue} from 'sanity'
const AutoFillSubtitle = (props) => {
const {elementProps, onChange, value = ''} = props
const title = useFormValue(['title']) // Read the title field
const handleChange = useCallback((event) => {
const nextValue = event.currentTarget.value
onChange(nextValue ? set(nextValue) : unset())
}, [onChange])
// Show title as placeholder when subtitle is empty
const displayValue = value || ''
const placeholderText = title ? `Auto-filled from title: ${title}` : 'Enter subtitle'
return (
<Stack space={2}>
<TextInput
{...elementProps}
onChange={handleChange}
value={displayValue}
placeholder={placeholderText}
/>
{!value && title && (
<Text size={1} muted>
Will use title if left empty: "{title}"
</Text>
)}
</Stack>
)
}
export default AutoFillSubtitleThen add it to your schema:
{
name: 'subtitle',
title: 'SubTitle (Recommended)',
type: 'string',
components: {
input: AutoFillSubtitle
}
}The useFormValue hook lets you access any field in the current document by passing the field path as an array (['title'] for top-level fields, or ['parent', 'child', 'field'] for nested ones). This updates in real-time as users type.
Important: The set and unset functions are imported from sanity (not as separate packages) and are used to create patch operations that update the Content Lake.
2. Frontend Fallback (Simplest)
Often the easiest solution is handling this in your frontend code rather than the Studio:
const subtitle = document.subtitle || document.titleAdd a description to your subtitle field like "If left empty, the title will be used." This keeps your Studio simple while still giving editors override capability. This is often the most pragmatic approach.
3. initialValue (One-time Default)
For a one-time default when creating new documents, you can use initialValue:
{
name: 'subtitle',
type: 'string',
initialValue: (context) => {
// Note: This only works at document creation
// and won't have access to the title field at that time
return ''
}
}Note: initialValue runs when the document is first created, so it won't have access to the title field yet. This approach is less useful for copying from sibling fields.
Using renderDefault for Light Modifications
If you want to keep most of the default behavior and just add hints, you can use renderDefault:
import {useFormValue} from 'sanity'
const SubtitleWithHint = (props) => {
const title = useFormValue(['title'])
return props.renderDefault({
...props,
elementProps: {
...props.elementProps,
placeholder: title ? `Leave empty to use: ${title}` : 'Enter subtitle'
}
})
}Important Considerations
- User Experience: Auto-filling can be confusing if the title changes later. Will the subtitle update automatically or stay as set? Make this clear to editors.
- Override Capability: Always let editors manually override auto-filled values.
- Complexity Trade-off: Custom components require more code. Consider whether the Studio convenience is worth it versus handling it in your frontend.
The custom input component with useFormValue is the most complete solution for real-time auto-filling in Studio v3, but it does require understanding React and Sanity's form component APIs. Start with the frontend approach if you're new to custom components!
Show original thread38 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.