npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

slugify-multilang

v1.0.3

Published

Multi-language slug generator with CJK, Arabic, Cyrillic, and locale support.

Readme

slugify-multilang

A multi-language, dependency-free slug generator for JavaScript and TypeScript. This is a faithful frontend port of the repository's C# Slugify.MultiLang library: it shares the same character map, locale overrides, defaults, and Unicode handling.

It transliterates accented Latin, Greek, Cyrillic, Armenian, Georgian, Vietnamese, currencies, and common symbols. Scripts without meaningful romanization—including Chinese, Japanese, Korean, Arabic, Thai, and Devanagari—are preserved so generated URLs remain readable.

Features

  • No runtime dependencies; works in browser applications and Node.js.
  • Unicode NFC normalization for equivalent composed/decomposed input.
  • Transliteration for Latin Extended, Greek, Cyrillic (including Kazakh), Armenian, Georgian, and Vietnamese.
  • Locale-specific overrides for Bulgarian, German, Spanish, French, Portuguese, Ukrainian, Vietnamese, Danish, Norwegian Bokmål, Italian, Dutch, and Swedish.
  • Readable passthrough for CJK, Arabic, Thai, and Devanagari letters.
  • Configurable separator, casing, strict filtering, trimming, removal regex, and global character-map extensions.

Install

npm install slugify-multilang

Usage

import { extend, slugify, SlugifyHelper } from "slugify-multilang";

slugify("Hello, World!");
// "hello-world"

slugify("Café au lait & cròissant");
// "cafe-au-lait-and-croissant"

slugify("傅总:你的马甲 又又又掉了!");
// "傅总-你的马甲-又又又掉了"

slugify("Müller & Söhne", { Locale: "de" });
// "mueller-und-soehne"

slugify("Some Text", "_");
// "some_text"

extend({ "☂": "umbrella" });
SlugifyHelper.Slugify("☂ rain");
// "umbrella-rain"

The package supports both ESM and CommonJS:

const { slugify } = require("slugify-multilang");

Options

Option names intentionally match the C# API.

| Option | Type | Default | Description | | --- | --- | --- | --- | | Replacement | string | "-" | Replaces whitespace and separators. | | Remove | RegExp \| null | null | Custom character-removal expression. | | Lower | boolean | true | Lowercases the final slug. | | Strict | boolean | true | Retains Unicode letters, numbers, and whitespace only. | | Trim | boolean | true | Removes leading and trailing whitespace. | | Locale | string \| null | null | Applies locale-specific overrides. |

Locale maps are available for bg, de, es, fr, pt, uk, vi, da, nb, it, nl, and sv.

slugify("Müller & Söhne", {
  Locale: "de",       // ü → ue, ö → oe, & → und
  Replacement: "-",
  Lower: true,
  Strict: true,
  Trim: true,
});
// "mueller-und-soehne"

Unknown locale codes use the global character map without throwing an error.

Extend the Character Map

extend changes the module-wide map for later calls. It accepts either a plain object or a Map whose keys are individual characters.

import { extend, slugify } from "slugify-multilang";

extend({
  "☂": "umbrella",
  "♛": "queen",
});

slugify("☂ ♛");
// "umbrella-queen"

How It Works

Each input is NFC-normalized, translated character by character (locale map, then global map, then passthrough), filtered, optionally strict-filtered, trimmed, converted to the replacement separator, and optionally lowercased. With default strict mode, combining marks are stripped while Unicode letters such as Arabic and CJK characters are preserved.

| Input | Output | | --- | --- | | "Café au lait & cròissant" | "cafe-au-lait-and-croissant" | | "Директор Фу" | "direktor-fu" | | "傅总:你的马甲" | "傅总-你的马甲" | | "المدير فو" | "المدير-فو" |

When Strict is false, characters retained by the removal pattern, such as underscores, remain in the result. With Strict: true (the default), only Unicode letters, numbers, and whitespace remain before separators are applied.

23-Language Examples

The following examples use the same source phrase in each language. Outputs match the C# and Python ports in this repository.

Locale-specific overrides

| Language | Locale | Input | Output | | --- | --- | --- | --- | | Spanish | es | Director Fu: Tu cuenta alternativa ha quedado expuesta otra vez | director-fu-tu-cuenta-alternativa-ha-quedado-expuesta-otra-vez | | Portuguese | pt | Diretor Fu: Sua conta alternativa foi exposta de novo | diretor-fu-sua-conta-alternativa-foi-exposta-de-novo | | French | fr | Directeur Fu: Votre compte alternatif a été exposé encore | directeur-fu-votre-compte-alternatif-a-ete-expose-encore | | German | de | Direktor Fu: Dein Alternativkonto ist aufgeflogen | direktor-fu-dein-alternativkonto-ist-aufgeflogen | | Italian | it | Direttore Fu: Il tuo account alternativo è stato smascherato | direttore-fu-il-tuo-account-alternativo-e-stato-smascherato | | Swedish | sv | Direktör Fu: Ditt alternativa konto har avslöjats | direktoer-fu-ditt-alternativa-konto-har-avsloejats | | Danish | da | Direktør Fu: Din alternative konto er blevet afsløret | direktoer-fu-din-alternative-konto-er-blevet-afsloeret | | Dutch | nl | Directeur Fu: Uw alternatieve account is ontmaskerd | directeur-fu-uw-alternatieve-account-is-ontmaskerd | | Vietnamese | vi | Giám đốc Phú: Tài khoản phụ của bạn đã bị lộ | giam-doc-phu-tai-khoan-phu-cua-ban-da-bi-lo |

Global character-map fallback

These locale labels have no dedicated override map (except nb for Norwegian Bokmål), so the global map provides the transliteration.

| Language | Locale | Input | Output | | --- | --- | --- | --- | | Polish | pl | Dyrektorze Fu: Twoje alternatywne konto zostało zdemaskowane | dyrektorze-fu-twoje-alternatywne-konto-zostalo-zdemaskowane | | Norwegian | no | Direktor Fu: Den alternative kontoen din har blitt avslørt | direktor-fu-den-alternative-kontoen-din-har-blitt-avslort | | Turkish | tr | Müdür Fu: Sahte hesabın deşifre oldu | mudur-fu-sahte-hesabin-desifre-oldu | | Malay | ms | Pengarah Fu: Akaun tiruan anda telah terdedah | pengarah-fu-akaun-tiruan-anda-telah-terdedah | | Indonesian | id | Direktur Fu: Akun samaran Anda telah terbongkar | direktur-fu-akun-samaran-anda-telah-terbongkar | | Filipino | tl | Direktor Fu: Ang iyong account ay nabunyag | direktor-fu-ang-iyong-account-ay-nabunyag | | English | en | Director Fu: Your alt account got exposed again | director-fu-your-alt-account-got-exposed-again |

Unicode script preservation

These scripts have no global transliteration map. Their letters remain in the slug, while mapped punctuation becomes the configured separator.

| Language | Locale | Input | Output | | --- | --- | --- | --- | | Arabic | ar | المدير فو: تم كشف حسابك البديل | المدير-فو-تم-كشف-حسابك-البديل | | Japanese | ja | 傅総:あなたのサブアカウントがバレちゃった | 傅総-あなたのサブアカウントがバレちゃった | | Korean | ko | 푸 총재: 당신의 부계정이 들통났어요 | 푸-총재-당신의-부계정이-들통났어요 | | Thai | th | ผู้อำนวยการฟู: บัญชีอำพรางของคุณถูกเปิดเผย | ผอำนวยการฟ-บญชอำพรางของคณถกเปดเผย | | Hindi | hi | निदेशक फू: आपका वैकल्पिक खाता उजागर हो गया | नदशक-फ-आपक-वकलपक-खत-उजगर-ह-गय | | Simplified Chinese | zh | 傅总:你的马甲又掉了 | 傅总-你的马甲又掉了 | | Traditional Chinese | zh-tw | 傅總:你的馬甲又掉了 | 傅總-你的馬甲又掉了 |

Thai and Devanagari combining vowel and tone marks are removed by default strict mode. Set Strict: false if retaining those marks is more important than strict URL filtering.

API

function slugify(input: string, replacement?: string): string;
function slugify(input: string, options?: SlugifySlugOptions): string;
function extend(customMap: Record<string, string> | Map<string, string>): void;

For callers that prefer the original static-class naming, SlugifyHelper exposes SlugifyHelper.Slugify and SlugifyHelper.Extend.

Compatibility

The package ships ESM, CommonJS, and TypeScript declaration files. It is intended for Vue, React, Angular, vanilla browser bundlers, and Node.js. Browser environments must support ES2020 and Unicode property escapes.

License

MIT