How to slugify a string in JavaScript

By

Learn how to slugify a string in JavaScript with a small function that lowercases text, strips accents and invalid characters, and turns spaces into hyphens.

~~~

To slugify a string in JavaScript you chain a few string methods: trim it, lowercase it, strip accents and invalid characters, then turn spaces into hyphens. No library needed.

A slug is the URL-friendly version of a string. If a blog post is titled “How to Use fetch() in JavaScript”, its slug is how-to-use-fetch-in-javascript. Only lowercase letters, numbers and hyphens, so it’s safe to put in a URL.

Here’s the function I use:

export function slugify(str) {
  // Remove leading and trailing whitespace
  str = str.trim()

  // Make the string lowercase
  str = str.toLowerCase()

  // Remove accents, swap ñ for n, etc
  str = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')

  // Remove invalid characters
  str = str.replace(/[^a-z0-9 -]/g, '')

  // Replace whitespace with a hyphen
  str = str.replace(/\s+/g, '-')

  // Collapse consecutive hyphens
  str = str.replace(/-+/g, '-')

  return str
}

Let’s try it:

slugify('How to Use fetch() in JavaScript')
//'how-to-use-fetch-in-javascript'

slugify('Caffè è  buono')
//'caffe-e-buono'

What does each step do?

The order of the steps matters, so let’s walk through them.

We trim and lowercase first. Then we handle accented letters, so they survive the next step instead of being thrown away.

The “invalid characters” regex keeps only lowercase letters, numbers, spaces and hyphens. Everything else, punctuation, parentheses, emoji, gets removed. That’s why fetch() in the example became fetch in the slug.

The last two steps clean up: whitespace becomes hyphens, and runs of hyphens collapse into one, so “How to” with a double space still produces a single hyphen.

How does the accents part work?

The most cryptic line is the normalize() one.

normalize('NFD') splits each accented character into two parts: the base letter and a separate accent mark. So è becomes e plus a combining accent character.

Those combining marks all live in the Unicode range \u0300 to \u036f. The replace() right after removes them, and we’re left with the plain letter. That’s how Caffè becomes caffe instead of losing the letter entirely.

Watch out for leading and trailing hyphens

One case this function does not handle: strings that start or end with hyphens or other punctuation.

slugify('-- Draft: my new post --')
//'-draft-my-new-post-'

Those dangling hyphens look bad in a URL. The fix is one more replace() before the return:

// Remove leading and trailing hyphens
str = str.replace(/^-+|-+$/g, '')

With that line added, the same input returns draft-my-new-post.

If you just need to convert a string to kebab-case (or camelCase, snake_case…) without writing code, I built a free string case converter you can use.

~~~

Related posts about js: