How to automatically generate slugs for a large set of articles?
Great question! Yes, there's definitely a better way than manually clicking through every article. You can use Sanity's migration tooling to bulk-generate slugs for all your existing articles.
Create a Migration Script
First, generate a new migration using the CLI:
npx sanity@latest migration create "generate slugs for articles"This will create a migration file in your migrations directory. Open the generated index.ts file and replace it with something like this:
import {defineMigration, at, setIfMissing} from 'sanity/migrate'
// Helper function to create URL-friendly slugs
function slugify(text: string): string {
return text
.toLowerCase()
.replace(/[^\w\s-]/g, '') // Remove special characters
.replace(/\s+/g, '-') // Replace spaces with hyphens
.replace(/--+/g, '-') // Replace multiple hyphens with single
.trim()
}
export default defineMigration({
title: 'Generate slugs for articles',
documentTypes: ['article'], // Replace with your document type
migrate: {
document(doc, context) {
// Only generate if there's a title and slug is missing
if (doc.title && !doc.slug?.current) {
return [
at('slug', setIfMissing({
_type: 'slug',
current: slugify(doc.title)
}))
]
}
return []
}
}
})Test It First (Dry Run)
Before making any changes, run it in dry-run mode to see what would happen:
npx sanity migration run generate-slugs-for-articlesThis won't actually change anything - it just shows you what would be updated. Review the output to make sure it looks good!
Run the Migration
Once you're happy with the dry run results, execute it for real:
npx sanity migration run generate-slugs-for-articles --dataset productionReplace production with your dataset name (often production or development).
The migration toolkit automatically handles batching, rate limits, and gives you progress feedback. The setIfMissing operation ensures you won't overwrite any slugs that already exist, so it's safe to run even if some articles already have slugs.
Important Notes
- The migration uses
setIfMissing, so it won't overwrite existing slugs - only adds them where missing - You might want to add uniqueness checking if your slugs need to be unique (the basic example above doesn't handle duplicates)
- Consider backing up your dataset first if you're working with production data
- The migration is idempotent, meaning you can safely run it multiple times without creating problems
This approach is way better than clicking through hundreds of articles! 😄
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.