slugify is a free, open source browsers & extensions project written in JavaScript and released under MIT. It has 2,702 GitHub stars, 95 forks and 2 open issues, and was last pushed 9 days ago. On this registry it ranks #88 of 133 tracked projects in Browsers & Extensions, with 5 head-to-head comparisons available.

What is slugify?

slugify is a small, MIT-licensed JavaScript package published on npm as @sindresorhus/slugify that turns arbitrary text into URL-safe, filename-safe, ID-safe slugs, and it is aimed at developers writing web applications, static site generators, Node.js tooling, and form handling code that needs predictable identifiers derived from human-readable strings.

What it is

The package exports a single default function, slugify(string, options?), that normalises input before producing a slug. It converts I ♥ Dogs to i-love-dogs, strips accents so Déjà Vu! becomes deja-vu, splits camelCase so fooBar 123 $#% becomes foo-bar-123, and normalises typographic punctuation so Conway’s Law becomes conways-law. Non-Latin scripts are handled too, with the README demonstrating Russian input such as я люблю единорогов producing ya-lyublyu-edinorogov. It runs in Node.js and in the browser, and it depends on @sindresorhus/transliterate for language-specific conversion of Unicode characters to ASCII.

The concrete problem it solves is the hand-written chain of replace calls and regular expressions that would otherwise live inside routing, file-naming, or ID-generation code. Those chains tend to break on diacritics, on scripts outside Latin-1, on emoji, and on punctuation that survives a naive lowercase-and-strip pass. slugify centralises that work behind one call, so a page title, a product name, or a user-supplied label can be turned into a stable identifier without each caller reinventing the rules. The transliteration layer covers most major languages, including German umlauts, Vietnamese, Arabic, and Russian, with a locale option for language-specific behaviour.

Key capabilities

  • slugify(string, options?) is the sole exported entry point, imported as import slugify from '@sindresorhus/slugify'.
  • The separator option defaults to -, and accepts alternatives such as '_' or the empty string, which produces barandbaz from BAR and baz.
  • lowercase defaults to true; setting it to false yields Deja-Vu instead of deja-vu.
  • decamelize defaults to true, internally turning fooBar into foo bar; disabling it yields foobar.
  • customReplacements accepts an array of pairs, defaulting to mappings such as ['&', ' and '], and runs on the original string before other transformations.
  • preserveLeadingUnderscore and preserveTrailingDash default to false, letting callers keep _foo-bar or foo-bar- when those characters are intentional.
  • preserveCharacters keeps specified characters that are not the separator, and locale selects language-specific transliteration through @sindresorhus/transliterate.

Who uses it and how

  • Node.js applications and npm-package authors use it to generate route segments, cache keys, and identifiers from titles and labels.
  • Browser-side code uses it, per the package topic list, for client-side slug previews without a server round trip.
  • Form authors use preserveTrailingDash so a trailing dash is retained, which the README describes as allowing validation on an input field while not preventing the user from continuing to type.
  • File-naming code uses preserveLeadingUnderscore, since leading underscores are sometimes deliberate, for example filenames representing hidden paths on a website.
  • URL handling code uses preserveCharacters: ['#'] to keep an HTML fragment intact, turning foo_bar#baz into foo-bar#baz.

Getting started

Install with npm install @sindresorhus/slugify, then call slugify() from Node.js or browser code. The README documents no service, container, or hosted deployment.

How it compares

No comparable alternatives are named in the facts, so slugify stands alone in this registry as a general-purpose slug and transliteration library. Its only named companion is the @sindresorhus/transliterate package, which it uses for language-specific transliteration and which carries the full list of supported languages.

When to use it — and when not to

Nothing has to be operated: there is no database, storage layer, or mail service behind this package, only a function that runs in the caller's process. It is a poor fit for teams wanting a network service, an HTTP endpoint, or a hosted slug API, and for anyone who needs the package to guarantee byte-identical output across every locale, because language-specific rules depend on @sindresorhus/transliterate. The README is an API reference rather than a guide, and the documented option behaviour for transliterate: false is cut off in the excerpt, so a self-hoster should read the full documentation before relying on non-ASCII preservation.

project readme (upstream, from github) — read inline

slugify

Slugify a string

Useful for URLs, filenames, and IDs.

It handles most major languages, including German (umlauts), Vietnamese, Arabic, Russian, and more.

Install

npm install @sindresorhus/slugify

Usage

import slugify from '@sindresorhus/slugify';

slugify('I ♥ Dogs');
//=> 'i-love-dogs'

slugify('  Déjà Vu!  ');
//=> 'deja-vu'

slugify('fooBar 123 $#%');
//=> 'foo-bar-123'

slugify('Conway’s Law');
//=> 'conways-law'

slugify('я люблю единорогов');
//=> 'ya-lyublyu-edinorogov'

API

slugify(string, options?)

string

Type: string

String to slugify.

options

Type: object

separator

Type: string
Default: '-'

import slugify from '@sindresorhus/slugify';

slugify('BAR and baz');
//=> 'bar-and-baz'

slugify('BAR and baz', {separator: '_'});
//=> 'bar_and_baz'

slugify('BAR and baz', {separator: ''});
//=> 'barandbaz'
lowercase

Type: boolean
Default: true

Make the slug lowercase.

import slugify from '@sindresorhus/slugify';

slugify('Déjà Vu!');
//=> 'deja-vu'

slugify('Déjà Vu!', {lowercase: false});
//=> 'Deja-Vu'
decamelize

Type: boolean
Default: true

Convert camelcase to separate words. Internally it does fooBarfoo bar.

import slugify from '@sindresorhus/slugify';

slugify('fooBar');
//=> 'foo-bar'

slugify('fooBar', {decamelize: false});
//=> 'foobar'
customReplacements

Type: Array
Default: [ ['&', ' and '], ['🦄', ' unicorn '], ['♥', ' love '] ]

Add your own custom replacements.

The replacements are run on the original string before any other transformations.

This only overrides a default replacement if you set an item with the same key, like &.

import slugify from '@sindresorhus/slugify';

slugify('Foo@unicorn', {
	customReplacements: [
		['@', 'at']
	]
});
//=> 'fooatunicorn'

Add a leading and trailing space to the replacement to have it separated by dashes:

import slugify from '@sindresorhus/slugify';

slugify('foo@unicorn', {
	customReplacements: [
		['@', ' at ']
	]
});
//=> 'foo-at-unicorn'

Another example:

import slugify from '@sindresorhus/slugify';

slugify('I love 🐶', {
	customReplacements: [
		['🐶', 'dogs']
	]
});
//=> 'i-love-dogs'
preserveLeadingUnderscore

Type: boolean
Default: false

If your string starts with an underscore, it will be preserved in the slugified string.

Sometimes leading underscores are intentional, for example, filenames representing hidden paths on a website.

import slugify from '@sindresorhus/slugify';

slugify('_foo_bar');
//=> 'foo-bar'

slugify('_foo_bar', {preserveLeadingUnderscore: true});
//=> '_foo-bar'
preserveTrailingDash

Type: boolean
Default: false

If your string ends with a dash, it will be preserved in the slugified string.

For example, using slugify on an input field would allow for validation while not preventing the user from writing a slug.

import slugify from '@sindresorhus/slugify';

slugify('foo-bar-');
//=> 'foo-bar'

slugify('foo-bar-', {preserveTrailingDash: true});
//=> 'foo-bar-'
preserveCharacters

Type: string[]
Default: []

Preserve certain characters.

It cannot contain the separator.

The apostrophe in a word-final 's or 't is still dropped, even if you preserve '.

For example, if you want to slugify URLs, but preserve the HTML fragment # character.

import slugify from '@sindresorhus/slugify';

slugify('foo_bar#baz', {preserveCharacters: ['#']});
//=> 'foo-bar#baz'
locale

Type: string
Default: undefined

The locale to use for language-specific transliteration.

See the @sindresorhus/transliterate package for more info.

import slugify from '@sindresorhus/slugify';

slugify('Räksmörgås');
//=> 'raeksmoergas'

slugify('Räksmörgås', {locale: 'sv'});
//=> 'raksmorgas'
transliterate

Type: boolean
Default: true

Whether to transliterate Unicode characters to ASCII.

When false, non-ASCII characters will be preserved instead of being transliterated. This can improve performance when you don't need transliteration.

import slugify from '@sindresorhus/slugify';

slugify('Déjà Vu');
//=> 'deja-vu'

slugify('Déjà Vu', {transliterate: false});
//=> 'déjà-vu'

slugifyWithCounter()

Returns a new instance of slugify(string, options?) with a counter to handle multiple occurrences of the same string.

Example
import {slugifyWithCounter} from '@sindresorhus/slugify';

const slugify = slugifyWithCounter();

slugify('foo bar');
//=> 'foo-bar'

slugify('foo bar');
//=> 'foo-bar-2'

slugify.reset();

slugify('foo bar');
//=> 'foo-bar'
Use-case example of counter

If, for example, you have a document with multiple sections where each subsection has an example.

## Section 1

### Example

## Section 2

### Example

You can then use slugifyWithCounter() to generate unique HTML id's to ensure anchors will link to the right headline.

slugify.reset()

Reset the counter

Example
import {slugifyWithCounter} from '@sindresorhus/slugify';

const slugify = slugifyWithCounter();

slugify('foo bar');
//=> 'foo-bar'

slugify('foo bar');
//=> 'foo-bar-2'

slugify.reset();

slugify('foo bar');
//=> 'foo-bar'

Related

  • slugify-cli - CLI for this module
  • transliterate - Convert Unicode characters to Latin characters using transliteration
  • filenamify - Convert a string to a valid safe filename

Frequently asked questions

Is slugify free to use?

slugify is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does slugify do?

Slugify a string

What is slugify written in?

slugify is primarily written in JavaScript. Its source is publicly available at https://github.com/sindresorhus/slugify, and it has 2,702 GitHub stars.