How to Automatically Generate a Slug Without Using Sanity Studio
Based on what you're describing, you'll need to generate the slug programmatically since the automatic slug generation feature only works within Sanity Studio. Here's how you can handle this:
The Challenge
As mentioned in the Sanity documentation on slug generation via HTTP API, the built-in slug generation function is part of Sanity Studio itself and doesn't work when creating documents programmatically through the API.
Solution: Create Your Own Slugify Function
You have two main options:
1. Use a slugify library (recommended)
Sanity internally uses speakingurl, but you can use any slugify library. Here's an example with the popular slugify package:
import slugify from 'slugify'
// When the user submits their post
const userPost = {
title: "My Awesome Post Title!",
content: "...",
slug: {
_type: 'slug',
current: slugify(title, {
lower: true, // convert to lowercase
strict: true, // strip special characters
remove: /[*+~.()'"!:@]/g // remove specific chars
})
}
}
// Then create the document via Sanity client
await client.create(userPost)2. Write your own simple slugify function
If you don't want to add a dependency:
function createSlug(text) {
return text
.toLowerCase()
.trim()
.replace(/[^\w\s-]/g, '') // remove special chars
.replace(/[\s_-]+/g, '-') // replace spaces/underscores with hyphens
.replace(/^-+|-+$/g, ''); // remove leading/trailing hyphens
}
const slug = {
_type: 'slug',
current: createSlug(userTitle)
}Important: Slug Structure
Remember that when you're creating the slug field programmatically, you need to structure it properly as an object with _type and current properties, not just a string:
// ✅ Correct
slug: {
_type: 'slug',
current: 'my-post-slug'
}
// ❌ Wrong
slug: 'my-post-slug'Handling the Flow
For your specific use case where users submit data and then view it on the next page:
// On form submission
const handleSubmit = async (formData) => {
const newPost = {
_type: 'post',
title: formData.title,
slug: {
_type: 'slug',
current: slugify(formData.title, { lower: true, strict: true })
},
// ... other fields
}
const result = await sanityClient.create(newPost)
// Redirect to the new post using the generated slug
router.push(`/posts/${result.slug.current}`)
}This approach gives you full control over slug generation without relying on Studio's UI, which is exactly what you need for user-submitted content!
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.