Creating SEO-friendly slugs is essential for URLs in Next.js applications. However, ensuring they remain unique can be trickyโespecially when dealing with dynamic content like blog posts.
In this guide, weโll explore an efficient recursive approach to generate unique slugs using Prisma and slugify in Next.js 15! ๐ฅ
๐ Why Unique Slugs Matter?
โ
SEO Optimization โ Clean, readable URLs improve search rankings
โ
User-Friendly Links โ Easy to share & understand
โ
Prevents Collisions โ Avoid duplicate slugs for different posts
๐ Implementing Recursive Slug Generation
The following function:
โ Converts a title into a slug
โ Checks if the slug already exists in the database
โ Recursively appends a suffix if the slug is taken
import db from "@/lib/db";
import slugify from "slugify";
/**
* Generates a unique slug recursively.
* @param input - The string to generate the slug from (e.g., a post title).
* @param model - The Prisma model to check for existing slugs (e.g., "post").
* @param suffix - Optional suffix to append for uniqueness (used internally in recursion).
* @returns A unique slug.
*/
export default async function generateSlug(
input: string,
model: "post",
suffix: number = 0,
): Promise<string> {
const baseSlug = slugify(input, {
lower: true,
strict: true,
trim: true,
});
const slug = suffix === 0 ? baseSlug : `${baseSlug}-${suffix}`;
const existingRecord = await db[model].findUnique({
where: { slug },
});
if (!existingRecord) {
return slug;
}
return generateSlug(input, model, suffix + 1);
}
๐ How This Works
1๏ธโฃ Converts the input string into a lowercase, URL-friendly slug
2๏ธโฃ Checks the database if a record with the same slug exists
3๏ธโฃ If found, recursively calls itself with a numeric suffix (e.g., my-post
, my-post-1
, my-post-2
...)
4๏ธโฃ Returns the first available unique slug
๐ Example Usage in Next.js 15
You can use this function when creating new posts dynamically:
const createPost = async (title: string, content: string) => {
const slug = await generateSlug(title, "post");
await db.post.create({
data: {
title,
slug,
content,
},
});
console.log(`โ
New post created with slug: ${slug}`);
};
โ
Calling createPost("My Next.js Guide", "Some content")
๐ Generates my-nextjs-guide
, or if taken, my-nextjs-guide-1
, my-nextjs-guide-2
, etc.
โก Key Benefits
๐ฅ Handles Duplicates Automatically โ Ensures slugs remain unique
โก SEO & Readability โ Clean and structured URLs
๐ Works Seamlessly with Prisma โ No extra logic needed in API routes
๐ Final Thoughts
Slugs are a critical
part of a Next.js appโs SEO and usability
. With this recursive approach, you ensure that every post, page, or product gets a unique and clean URL
, automatically.
๐ก Would you use this approach in your project? Letโs discuss in the comments! ๐