How to lock slug field and customize apostrophe handling in Sanity slugs?

10 replies
Last updated: Nov 29, 2025
A couple of questions as I couldn't find anything using the docs search, is it possible to lock an input? For example the slug field, once generated I don't want the editor to change it. I thought it was demoed in the last open house but I couldn't find anything. My second question along the same lines, when I have a title like
VMI's RB staying for an extra year
, the slug will be something like
vmi-s-rb-staying-for-an-extra-year
. Is there a way to tell sanity that if a word has an
'
, don't put a hyphen? So something like
vmis-rb-staying-for-an-extra-year
?
AI Update

Great questions! Let me address both of them.

Locking/Making Fields Read-Only

Yes, you can absolutely lock a field like slug once it's generated! Sanity supports the readOnly option on fields, and it can accept either a boolean or a callback function to conditionally lock fields. For your slug use case, you could do something like this:

{
  name: 'slug',
  type: 'slug',
  options: {
    source: 'title'
  },
  readOnly: ({document}) => {
    // Lock the slug once it has been generated
    return !!document?.slug?.current
  }
}

Or if you want to lock it only after the document is published:

{
  name: 'slug',
  type: 'slug',
  options: {
    source: 'title'
  },
  readOnly: ({document}) => {
    // Lock after first publish
    return document?._id && !document._id.startsWith('drafts.')
  }
}

The readOnly callback receives parameters like document, parent, value, and currentUser, giving you full control over when the field should be locked.

Custom Slug Handling for Apostrophes

For your second question about handling apostrophes in slugs (so "VMI's RB" becomes vmis-rb instead of vmi-s-rb), you can use the slugify option on your slug field. The slug type supports custom slugification logic through this option:

{
  name: 'slug',
  type: 'slug',
  options: {
    source: 'title',
    slugify: input => input
      .toLowerCase()
      .replace(/'/g, '') // Remove apostrophes first
      .replace(/\s+/g, '-') // Replace spaces with hyphens
      .replace(/[^\w\-]+/g, '') // Remove all non-word chars except hyphens
      .replace(/\-\-+/g, '-') // Replace multiple hyphens with single hyphen
      .replace(/^-+/, '') // Trim hyphens from start
      .replace(/-+$/, '') // Trim hyphens from end
  }
}

This custom function strips out apostrophes before converting spaces to hyphens, so "VMI's RB staying for an extra year" will become vmis-rb-staying-for-an-extra-year instead of vmi-s-rb-staying-for-an-extra-year.

You can customize this function further to handle any other special characters or patterns specific to your content needs!

Show original thread
10 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.

Was this answer helpful?