March 6, 2023
O. Wolfson
The function described in this article takes a string as input and generates a URL-friendly slug from it. The function also checks if there are any existing posts with the same slug and appends a number to the end of the slug to make it unique if necessary.
Example, we can change 'My Title' to 'my-title'.
jsconst specialCharsRegex = /[^\w\s]/gi;
const whitespaceRegex = /\s+/g;
If you want to know more about how this regex works, please click here.
jsasync function generateSlug(title) {
// function body
}
jsconst slug = title.toLowerCase().replace(specialCharsRegex, "");
jsconst formattedSlug = slug.replace(whitespaceRegex, "-");
jsconst existingPosts = await checkForExistingPosts(formattedSlug);
jsif (existingPosts.length > 0) {
const formattedSlugWithCount = `${formattedSlug}-${existingPosts.length}`;
return formattedSlugWithCount;
} else {
return formattedSlug;
}
jsreturn formattedSlug;
Here's the full code example with comments explaining each step:
js// Define regular expressions for special characters and whitespace
const specialCharsRegex = /[^\w\s]/gi;
const whitespaceRegex = /\s+/g;
// Define the async function that generates a slug from a title
async function generateSlug(title) {
// Convert the title to lowercase and remove special characters
const slug = title.toLowerCase().replace(specialCharsRegex, "");
// Replace whitespace with hyphens
const formattedSlug = slug.replace(whitespaceRegex, "-");
// Check for existing posts with the same slug
const existingPosts = await checkForExistingPosts(formattedSlug);
// If there are existing posts, append the number of existing posts to the slug
if (existingPosts.length > 0) {
const formattedSlugWithCount = `${formattedSlug}-${existingPosts.length}`;
return formattedSlugWithCount;
} else {
return formattedSlug;
}
}
// Define the function that checks for existing posts with the same title
async function checkForExistingPosts(slug) {
// Make an API call to check for existing posts with the same slug.
// Example API call:
// const existingPosts = await fetch(`https://example.com/api/posts?slug=${slug}`);
return new Promise((resolve, reject) => {
existingPosts = [];
(existingPosts);
});
}
title = ;
(title)
.( {
.();
})
.( {
.(, error);
});
In this example, we define the generateSlug function and the checkForExistingPosts function. The generateSlug function takes a title parameter as input, generates a slug from the title, and checks for existing posts with the same title. If there are any existing posts, the function appends a number to the end of the slug to make it unique.
We also define a checkForExistingPosts function that returns a Promise that resolves to an empty array, since we don't have an API to call in this example.
Finally, we call the generateSlug function with a title parameter, and log the formatted slug to the console. If an error occurs while generating the slug, we log an error message to the console.
The formatted slug for "How to Generate a Unique URL-Friendly Slug in JavaScript", assuming that there are no existing posts with the same title, the output of the example code I provided would look something like this:
bash"how-to-generate-a-unique-url-friendly-slug-in-javascript".
The formatted slug for "How to Generate a Unique URL-Friendly Slug in JavaScript", if there were existing posts with the same title, the output might look something like this:
bash"how-to-generate-a-unique-url-friendly-slug-in-javascript-3".
In this case, the number 3 is appended to the end of the slug to make it unique.
The first regular expression specialCharsRegex /[^\w\s]/gi matches any character that is not a word character (\w) or whitespace (\s). The ^ character inside the square brackets means "not", so [^\w\s] matches any character that is not a word character or whitespace. The g flag at the end of the regex indicates that the search should be global, meaning it should match all occurrences of the pattern in the input string. The i flag indicates that the search should be case-insensitive, so it will match both uppercase and lowercase letters. For example, given the input string "Hello, world! 123", specialCharsRegex would match the , and ! characters. We use this expression to remove any special (non-url-friendly) characters from the input string.
The second regular expression whitespaceRegex /\s+/g matches one or more consecutive whitespace characters. The \s meta-character matches any whitespace character, such as spaces, tabs, and line breaks. The + character after \s means "one or more occurrences of the previous character or group", so \s+ matches one or more consecutive whitespace characters. The g flag again indicates that the search should be global, meaning it should match all occurrences of the pattern in the input string. We use this expression to replace any whitespace characters with hyphens.