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
Where to Learn More
Check out these helpful guides for more examples:
- Create a coupon generator string field - very similar to what you're trying to do!
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
Was this answer helpful?
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.