Auto-generate field value from another field with button in Sanity schema

5 replies
Last updated: Aug 18, 2021
Hi there, got another Sanity question. I am trying to have a field within a schema that is being auto-generated --perhaps when a button next to it is being pressed-- based on another's field value. Quite similar to how slug is being generated with the out-of-the-box slugify functionality, when the 'Generate' button is pressed. I am a bit lost and don't know where to even start looking. Can anyone point me towards the right direction? Thank you.
AI Update

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:

  1. Reads the value from another field using useFormValue
  2. Processes/transforms that value
  3. Updates your field using the onChange callback with set() or unset()
  4. 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 document
  • onChange() - Callback prop provided to your component for updating the field value
  • set() / unset() - Methods to set or clear the field value (use with onChange)
  • 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 useFormValue hook 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 onChange callback with set() and unset() is how you patch data back to the Content Lake

Where to Learn More

Check out these helpful guides for more examples:

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 thread
5 replies
Hi there! Sounds like you want to create a custom input, so I would start with this documentation: https://www.sanity.io/docs/custom-input-widgets
It includes information about how to access other fields in the same documents at the bottom of the article, and to make it look native to the Studio, you can build it with
https://www.sanity.io/ui ! Hope that helps, let me know if you need more help! 👍
That's all I needed I think, many thanks 🙏
Great! Also, here’s an example of how to use Sanity UI to get the styles looking like the slug input 👍 https://www.sanity.io/ui/arcade?mode=jsx&amp;jsx=eJxVT9sKwjAMfZ5fEfoDRX1NB24gCD76A8V2W8[…]kSsNgYdXlyiKSgj84b1XZxZKV%2FNtmzQJ0Lod4aCxKQXyo%2FpydCAg%3D%3D
Great! Also, here’s an example of how to use Sanity UI to get the styles looking like the slug input 👍 https://www.sanity.io/ui/arcade?mode=jsx&amp;jsx=eJxVT9sKwjAMfZ5fEfoDRX1NB24gCD76A8V2W8[…]kSsNgYdXlyiKSgj84b1XZxZKV%2FNtmzQJ0Lod4aCxKQXyo%2FpydCAg%3D%3D
Hi there! Sounds like you want to create a custom input, so I would start with this documentation: https://www.sanity.io/docs/custom-input-widgets
It includes information about how to access other fields in the same documents at the bottom of the article, and to make it look native to the Studio, you can build it with
https://www.sanity.io/ui ! Hope that helps, let me know if you need more help! 👍

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?