Add Generate Button to String Field for ShortID Generation

2 replies
Last updated: Jul 29, 2020
Is it possible to add a “generate” button for a string type? My use case is I created a “shortID” field that I use for url-friendly unique id. I already have it as initial value but would like to generate as well
AI Update

Yes, absolutely! You can add a "generate" button to your shortID string field by creating a custom input component. This is a perfect use case for custom input components in Sanity Studio.

Here's how to implement it:

Basic Implementation

In your schema, add a custom input component to your shortID field:

import {Button, Stack, TextInput} from '@sanity/ui'
import {set, unset} from 'sanity'

const ShortIDInput = (props) => {
  const {elementProps, onChange, value} = props
  
  const generateShortID = () => {
    // Your ID generation logic here
    const newID = Math.random().toString(36).substring(2, 9)
    onChange(set(newID))
  }
  
  return (
    <Stack space={3}>
      <TextInput
        {...elementProps}
        value={value || ''}
        onChange={(event) => 
          onChange(event.currentTarget.value ? set(event.currentTarget.value) : unset())
        }
      />
      <Button
        text="Generate ID"
        tone="primary"
        onClick={generateShortID}
      />
    </Stack>
  )
}

// In your schema:
{
  name: 'shortID',
  type: 'string',
  components: {
    input: ShortIDInput
  },
  initialValue: () => Math.random().toString(36).substring(2, 9)
}

Complete Example with Better Structure

For a more production-ready version that includes proper spacing and respects read-only states:

import {Button, Stack, TextInput} from '@sanity/ui'
import {set, unset} from 'sanity'

const ShortIDInput = (props) => {
  const {
    elementProps,
    onChange,
    value = '',
    readOnly
  } = props
  
  const generateShortID = () => {
    // Use your preferred ID generation method
    const newID = Math.random().toString(36).substring(2, 9)
    onChange(set(newID))
  }
  
  return (
    <Stack space={3}>
      <TextInput
        {...elementProps}
        value={value}
        readOnly={readOnly}
        onChange={(event) => 
          onChange(event.currentTarget.value ? set(event.currentTarget.value) : unset())
        }
      />
      <Button
        text="Generate New ID"
        tone="primary"
        onClick={generateShortID}
        disabled={readOnly}
        mode="ghost"
      />
    </Stack>
  )
}

The key points from the custom input components documentation:

  • Use the onChange prop with set() to update the field value
  • Use unset() when clearing the value
  • The component receives value, onChange, readOnly, and other useful props
  • Use Stack from @sanity/ui for proper spacing between elements
  • Respect the readOnly state to disable the button when appropriate

You can customize the ID generation logic to match your needs - whether that's using a library like nanoid, shortid, or your own custom algorithm for creating URL-friendly unique identifiers. Since you already have it working as an initialValue, you can reuse that same generation logic in your generate button handler!

Show original thread
2 replies
Could you use the slug schema type and name different to the page slug? At least as a stopgap workaround.
Thanks! Now that I think about, slug would actually be much better

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?