Auto-generate field value from another field with button in Sanity schema
Great question! You're looking to create custom field behavior similar to the slug field's "Generate" button. This requires creating a custom input component for your field.
The slug field you mentioned is actually a built-in custom component, and you can create similar functionality for any field type. Here's how to approach this:
Basic Approach
You'll need to create a custom input component that:
- Reads the value from another field using
useFormValue - Processes/transforms that value
- Updates your field using the
onChangecallback withset()orunset() - Renders a button to trigger the generation
Key Hooks and Methods
Here are the essential pieces you'll need:
useFormValue()- Hook to read values from other fields in your documentonChange()- Callback prop provided to your component for updating the field valueset()/unset()- Methods to set or clear the field value (use withonChange)renderDefault()- Optional prop that lets you wrap the default input UI and add your button alongside it
Example Implementation
Here's a basic pattern for your custom component:
import { set, unset, useFormValue } from 'sanity'
import { Button, Stack } from '@sanity/ui'
export function MyCustomInput(props) {
const { onChange, value } = props
// Read value from another field (e.g., 'title')
const sourceValue = useFormValue(['title'])
const handleGenerate = () => {
if (!sourceValue) {
onChange(unset())
return
}
// Your custom transformation logic
const generated = transformValue(sourceValue)
// Update the field value
onChange(set(generated))
}
return (
<Stack space={2}>
{props.renderDefault(props)}
<Button onClick={handleGenerate} text="Generate" tone="primary" />
</Stack>
)
}
// Example transformation function
function transformValue(value) {
// Your custom logic here
return value.toLowerCase().replace(/\s+/g, '-')
}Then in your schema, apply this component:
defineField({
name: 'myField',
type: 'string',
components: {
input: MyCustomInput
}
})Accessing Nested or Multiple Fields
If you need to read from nested fields or combine multiple fields:
// Single nested field
const nestedValue = useFormValue(['parent', 'child', 'fieldName'])
// Multiple fields - you can call useFormValue multiple times
const title = useFormValue(['title'])
const category = useFormValue(['category'])
const handleGenerate = () => {
const generated = `${category}-${title}`.toLowerCase()
onChange(set(generated))
}Important Notes
- The
useFormValuehook only works within the form builder context (inside custom input components) - Using
renderDefault(props)lets you keep the standard input UI and just add your button alongside it - The
onChangecallback withset()andunset()is how you patch data back to the Content Lake
Where to Learn More
Check out these helpful guides for more examples:
- Your first input component for Sanity Studio v3
- Create a coupon generator string field - very similar to what you're trying to do!
- Custom input components documentation
The key is understanding that useFormValue gives you access to other field values, and onChange with set() lets you update your field programmatically - combine those with a button click handler and you've got your generate functionality!
Show original thread5 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.