Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create slug from string in Javascript
function string_to_slug (str) {
str = str.replace(/^\s+|\s+$/g, ''); // trim
str = str.toLowerCase();
// remove accents, swap ñ for n, etc
var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
var to = "aaaaeeeeiiiioooouuuunc------";
for (var i=0, l=from.length ; i<l ; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}
str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.replace(/-+/g, '-'); // collapse dashes
return str;
}
@ariefurtado

This comment has been minimized.

Copy link

@ariefurtado ariefurtado commented Apr 13, 2018

Old but gold!

@felipeftrindade

This comment has been minimized.

Copy link

@felipeftrindade felipeftrindade commented Apr 29, 2018

Thanks, very useful!!!

Just a suggestion: include the character "ã" like this:

var from = "àáãäâèéëêìíïîòóöôùúüûñç·/_,:;";
var to   = "aaaaaeeeeiiiioooouuuunc------";
@tkrempser

This comment has been minimized.

Copy link

@tkrempser tkrempser commented Jun 19, 2018

Complete version with @felipeftrindade suggestion:

function string_to_slug (str) {
    str = str.replace(/^\s+|\s+$/g, ''); // trim
    str = str.toLowerCase();
  
    // remove accents, swap ñ for n, etc
    var from = "àáãäâèéëêìíïîòóöôùúüûñç·/_,:;";
    var to   = "aaaaaeeeeiiiioooouuuunc------";

    for (var i=0, l=from.length ; i<l ; i++) {
        str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
    }

    str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
        .replace(/\s+/g, '-') // collapse whitespace and replace by -
        .replace(/-+/g, '-'); // collapse dashes

    return str;
}
@iafiawik

This comment has been minimized.

Copy link

@iafiawik iafiawik commented Jun 24, 2018

Thanks for this function! I had to add the Swedish(?) letter Å, so this is my suggestion:

function string_to_slug(str) {
  str = str.replace(/^\s+|\s+$/g, ""); // trim
  str = str.toLowerCase();

  // remove accents, swap ñ for n, etc
  var from = "åàáãäâèéëêìíïîòóöôùúüûñç·/_,:;";
  var to = "aaaaaaeeeeiiiioooouuuunc------";

  for (var i = 0, l = from.length; i < l; i++) {
    str = str.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
  }

  str = str
    .replace(/[^a-z0-9 -]/g, "") // remove invalid chars
    .replace(/\s+/g, "-") // collapse whitespace and replace by -
    .replace(/-+/g, "-"); // collapse dashes

  return str;
}
@webarthur

This comment has been minimized.

Copy link

@webarthur webarthur commented Aug 27, 2018

Don't forget to trim '-':

function string_to_slug(str) {
  str = str.replace(/^\s+|\s+$/g, ""); // trim
  str = str.toLowerCase();

  // remove accents, swap ñ for n, etc
  var from = "åàáãäâèéëêìíïîòóöôùúüûñç·/_,:;";
  var to = "aaaaaaeeeeiiiioooouuuunc------";

  for (var i = 0, l = from.length; i < l; i++) {
    str = str.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
  }

  str = str
    .replace(/[^a-z0-9 -]/g, "") // remove invalid chars
    .replace(/\s+/g, "-") // collapse whitespace and replace by -
    .replace(/-+/g, "-") // collapse dashes
    .replace(/^-+/, "") // trim - from start of text
    .replace(/-+$/, ""); // trim - from end of text

  return str;
}
@sunil-Invesco

This comment has been minimized.

Copy link

@sunil-Invesco sunil-Invesco commented Oct 31, 2018

Has this been tested across multiple browsers and devices? This seems to be failing for iPhone/Safari users.

@flavio-silva

This comment has been minimized.

Copy link

@flavio-silva flavio-silva commented Nov 14, 2018

It is really useful for me.
I've changed this function by simplifying the trim part and adding a separator parameter.

function string_to_slug(str, separator) {
        str = str.trim();
        str = str.toLowerCase();

        // remove accents, swap ñ for n, etc
        const from = "åàáãäâèéëêìíïîòóöôùúüûñç·/_,:;";
        const to = "aaaaaaeeeeiiiioooouuuunc------";

        for (let i = 0, l = from.length; i < l; i++) {
            str = str.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
        }

        return str
            .replace(/[^a-z0-9 -]/g, "") // remove invalid chars
            .replace(/\s+/g, "-") // collapse whitespace and replace by -
            .replace(/-+/g, "-") // collapse dashes
            .replace(/^-+/, "") // trim - from start of text
            .replace(/-+$/, "") // trim - from end of text
            .replace(/-/g, separator);
    }
@casbloem

This comment has been minimized.

Copy link

@casbloem casbloem commented Jan 25, 2019

just a quick edit with some more characters.

export default (str) => {
    str = String(str).toString();
    str = str.replace(/^\s+|\s+$/g, ""); // trim
    str = str.toLowerCase();

    // remove accents, swap ñ for n, etc
    const swaps = {
        '0': ['°', '₀', '۰', '0'],
        '1': ['¹', '₁', '۱', '1'],
        '2': ['²', '₂', '۲', '2'],
        '3': ['³', '₃', '۳', '3'],
        '4': ['⁴', '₄', '۴', '٤', '4'],
        '5': ['⁵', '₅', '۵', '٥', '5'],
        '6': ['⁶', '₆', '۶', '٦', '6'],
        '7': ['⁷', '₇', '۷', '7'],
        '8': ['⁸', '₈', '۸', '8'],
        '9': ['⁹', '₉', '۹', '9'],
        'a': ['à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', 'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ā', 'ą', 'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', 'ἇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', 'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', 'အ', 'ာ', 'ါ', 'ǻ', 'ǎ', 'ª', 'ა', 'अ', 'ا', 'a', 'ä'],
        'b': ['б', 'β', 'ب', 'ဗ', 'ბ', 'b'],
        'c': ['ç', 'ć', 'č', 'ĉ', 'ċ', 'c'],
        'd': ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', 'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ', 'd'],
        'e': ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ', 'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ', 'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э', 'є', 'ə', 'ဧ', 'ေ', 'ဲ', 'ე', 'ए', 'إ', 'ئ', 'e'],
        'f': ['ф', 'φ', 'ف', 'ƒ', 'ფ', 'f'],
        'g': ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ', 'g'],
        'h': ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ', 'h'],
        'i': ['í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į', 'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ', 'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'і', 'ї', 'и', 'ဣ', 'ိ', 'ီ', 'ည်', 'ǐ', 'ი', 'इ', 'ی', 'i'],
        'j': ['ĵ', 'ј', 'Ј', 'ჯ', 'ج', 'j'],
        'k': ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ', 'ک', 'k'],
        'l': ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ', 'l'],
        'm': ['м', 'μ', 'م', 'မ', 'მ', 'm'],
        'n': ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န', 'ნ', 'n'],
        'o': ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ', 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő', 'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό', 'о', 'و', 'θ', 'ို', 'ǒ', 'ǿ', 'º', 'ო', 'ओ', 'o', 'ö'],
        'p': ['п', 'π', 'ပ', 'პ', 'پ', 'p'],
        'q': ['ყ', 'q'],
        'r': ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ', 'r'],
        's': ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ', 'ſ', 'ს', 's'],
        't': ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ', 'თ', 'ტ', 't'],
        'u': ['ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ', 'ự', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', 'ဉ', 'ု', 'ူ', 'ǔ', 'ǖ', 'ǘ', 'ǚ', 'ǜ', 'უ', 'उ', 'u', 'ў', 'ü'],
        'v': ['в', 'ვ', 'ϐ', 'v'],
        'w': ['ŵ', 'ω', 'ώ', 'ဝ', 'ွ', 'w'],
        'x': ['χ', 'ξ', 'x'],
        'y': ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', 'ϋ', 'ύ', 'ΰ', 'ي', 'ယ', 'y'],
        'z': ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ', 'z'],
        'aa': ['ع', 'आ', 'آ'],
        'ae': ['æ', 'ǽ'],
        'ai': ['ऐ'],
        'ch': ['ч', 'ჩ', 'ჭ', 'چ'],
        'dj': ['ђ', 'đ'],
        'dz': ['џ', 'ძ'],
        'ei': ['ऍ'],
        'gh': ['غ', 'ღ'],
        'ii': ['ई'],
        'ij': ['ij'],
        'kh': ['х', 'خ', 'ხ'],
        'lj': ['љ'],
        'nj': ['њ'],
        'oe': ['ö', 'œ', 'ؤ'],
        'oi': ['ऑ'],
        'oii': ['ऒ'],
        'ps': ['ψ'],
        'sh': ['ш', 'შ', 'ش'],
        'shch': ['щ'],
        'ss': ['ß'],
        'sx': ['ŝ'],
        'th': ['þ', 'ϑ', 'ث', 'ذ', 'ظ'],
        'ts': ['ц', 'ც', 'წ'],
        'ue': ['ü'],
        'uu': ['ऊ'],
        'ya': ['я'],
        'yu': ['ю'],
        'zh': ['ж', 'ჟ', 'ژ'],
        '(c)': ['©'],
        'A': ['Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ', 'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Å', 'Ā', 'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', 'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', 'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А', 'Ǻ', 'Ǎ', 'A', 'Ä'],
        'B': ['Б', 'Β', 'ब', 'B'],
        'C': ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ', 'C'],
        'D': ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ', 'D'],
        'E': ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ', 'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ', 'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э', 'Є', 'Ə', 'E'],
        'F': ['Ф', 'Φ', 'F'],
        'G': ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ', 'G'],
        'H': ['Η', 'Ή', 'Ħ', 'H'],
        'I': ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į', 'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ', 'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', 'Ǐ', 'ϒ', 'I'],
        'J': ['J'],
        'K': ['К', 'Κ', 'K'],
        'L': ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल', 'L'],
        'M': ['М', 'Μ', 'M'],
        'N': ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν', 'N'],
        'O': ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ', 'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ø', 'Ō', 'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', 'Ὸ', 'Ό', 'О', 'Θ', 'Ө', 'Ǒ', 'Ǿ', 'O', 'Ö'],
        'P': ['П', 'Π', 'P'],
        'Q': ['Q'],
        'R': ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ', 'R'],
        'S': ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ', 'S'],
        'T': ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ', 'T'],
        'U': ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ', 'Ự', 'Û', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', 'Ǔ', 'Ǖ', 'Ǘ', 'Ǚ', 'Ǜ', 'U', 'Ў', 'Ü'],
        'V': ['В', 'V'],
        'W': ['Ω', 'Ώ', 'Ŵ', 'W'],
        'X': ['Χ', 'Ξ', 'X'],
        'Y': ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ', 'Y'],
        'Z': ['Ź', 'Ž', 'Ż', 'З', 'Ζ', 'Z'],
        'AE': ['Æ', 'Ǽ'],
        'Ch': ['Ч'],
        'Dj': ['Ђ'],
        'Dz': ['Џ'],
        'Gx': ['Ĝ'],
        'Hx': ['Ĥ'],
        'Ij': ['IJ'],
        'Jx': ['Ĵ'],
        'Kh': ['Х'],
        'Lj': ['Љ'],
        'Nj': ['Њ'],
        'Oe': ['Œ'],
        'Ps': ['Ψ'],
        'Sh': ['Ш'],
        'Shch': ['Щ'],
        'Ss': ['ẞ'],
        'Th': ['Þ'],
        'Ts': ['Ц'],
        'Ya': ['Я'],
        'Yu': ['Ю'],
        'Zh': ['Ж'],
    };

    Object.keys(swaps).forEach((swap) => {
        swaps[swap].forEach(s => {
            str = str.replace(new RegExp(s, "g"), swap);
        })
    });
    return str
        .replace(/[^a-z0-9 -]/g, "") // remove invalid chars
        .replace(/\s+/g, "-") // collapse whitespace and replace by -
        .replace(/-+/g, "-") // collapse dashes
        .replace(/^-+/, "") // trim - from start of text
        .replace(/-+$/, "");
};
@bzkdjc

This comment has been minimized.

Copy link

@bzkdjc bzkdjc commented Feb 17, 2019

This last version is not browser-friendly. As many browsers out there (including mine) do not know const, Array.forEach() nor => (arrow functions), this seems to be only for nodejs !

@ypsilon-p

This comment has been minimized.

Copy link

@ypsilon-p ypsilon-p commented Feb 21, 2019

You can use babel or something else to get a browser friendly version.

@nikolayandreev

This comment has been minimized.

Copy link

@nikolayandreev nikolayandreev commented Jun 19, 2019

If you need it for cyrillic.

function slugify(str) {
            str = str.replace(/^\s+|\s+$/g, ''); // trim
            str = str.toLowerCase();

            let from = [
                'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф',
                'х', 'ц', 'ч', 'ш','щ', 'ъ', 'ь', 'ю', 'я'];
            let to = [
                'a', 'b', 'v', 'g', 'd', 'e', 'zh', 'z', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f',
                'h', 'c', 'ch', 'sh','sht', 'y', '', 'iu', 'ia'];
            for (let key in from) {
                str = str.replace(new RegExp(from[key], 'g'), to[key])
            }

            str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
                     .replace(/\s+/g, '-') // collapse whitespace and replace by -
                     .replace(/-+/g, '-'); // collapse dashes

            return str;
        }
@joaomantovani

This comment has been minimized.

Copy link

@joaomantovani joaomantovani commented Mar 28, 2020

A more functional approach

function slugify(text) {
  const from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;"
  const to = "aaaaaeeeeeiiiiooooouuuunc------"

  const newText = text.split('').map(
    (letter, i) => letter.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)))

  return newText
    .toString()                     // Cast to string
    .toLowerCase()                  // Convert the string to lowercase letters
    .trim()                         // Remove whitespace from both sides of a string
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(/&/g, '-y-')           // Replace & with 'and'
    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
    .replace(/\-\-+/g, '-');        // Replace multiple - with single -
}
@thierryc

This comment has been minimized.

Copy link

@thierryc thierryc commented Apr 7, 2020

Do you try to use the normalize() method ?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
The normalize() method returns the Unicode Normalization Form of a given string.

function slugify(text) {
  return text
    .toString()                     // Cast to string
    .toLowerCase()                  // Convert the string to lowercase letters
    .normalize('NFD')       // The normalize() method returns the Unicode Normalization Form of a given string.
    .trim()                         // Remove whitespace from both sides of a string
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
    .replace(/\-\-+/g, '-');        // Replace multiple - with single -
}
@dimassilva

This comment has been minimized.

Copy link

@dimassilva dimassilva commented Apr 16, 2020

let string = "Pedro Alvares Cabral";
let slug = string.toLocaleLowerCase().replace(' ','').split('').join('-'); // converte para minúsculas, remove espaço, separa as letras e junta separando por traço.

@codeguy

This comment has been minimized.

Copy link
Owner Author

@codeguy codeguy commented Apr 20, 2020

I forgot this gist existed. Thanks everyone for their suggestions! If someone wants to steal all of this and put it into an official repo that'd be fine with me!

@juanlanus

This comment has been minimized.

Copy link

@juanlanus juanlanus commented Jun 6, 2020

This version includes an accents removal function for all the UNICODE spectrum.
The normalize function (standard in JS) separates accented letters from their accents. the replace step replaces al the accents by nothing, thus leaving the base letters alone. Based on @thierryc 's version, not yet tested:

slugify = ( text ) => {
    return text
    .toString()
    .normalize( 'NFD' )                   // split an accented letter in the base letter and the acent
    .replace( /[\u0300-\u036f]/g, '' )   // remove all previously split accents
    .toLowerCase()
    .trim()
    .replace(/\s+/g, '-')
    .replace(/[^\w\-]+/g, '')
    .replace(/\-\-+/g, '-'); 
  };
@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Jun 15, 2020

Today you can just yarn add limax then:

import slugify from "limax"

const burgundy = slugify('i ♥ lamp'); // i-love-lamp

https://github.com/lovell/limax

@arnoson

This comment has been minimized.

Copy link

@arnoson arnoson commented Jul 2, 2020

@juanlanus answer worked for me, shortened it a bit further

const slugify = text =>
  text
    .toString()
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .toLowerCase()
    .trim()
    .replace(/\s+/g, '-')
    .replace(/[^\w-]+/g, '')
    .replace(/--+/g, '-')
@batara666

This comment has been minimized.

Copy link

@batara666 batara666 commented Aug 12, 2020

jeez, too many implementation

@edgvi10

This comment has been minimized.

Copy link

@edgvi10 edgvi10 commented Aug 21, 2020

And if we implements this?

String.prototype.slugify = function (separator = "-") {
    return this
        .toString()
        .normalize('NFD')                   // split an accented letter in the base letter and the acent
        .replace(/[\u0300-\u036f]/g, '')   // remove all previously split accents
        .toLowerCase()
        .trim()
        .replace(/[^a-z0-9 ]/g, '')   // remove all chars not letters, numbers and spaces (to be replaced)
        .replace(/\s+/g, separator);
};

Ex:

"Exportação de _ peças - avícolas para Você".slugify() // exportacao-de-pecas-avicolas-para-voce

let text = "Café é o combustível para programação!!"
text.slugify("_") // cafe_e_o_combustivel_para_programacao
@juanlanus

This comment has been minimized.

Copy link

@juanlanus juanlanus commented Aug 21, 2020

If I did, then I could slugify a string with ease, which happens in one place in my programs, but would need to be aware that the String object has an addition in the other 999 code lines where I use strings for other purposes.
I would do what Eduarso says if I were slugifying everywhere in my program.

@max10rogerio

This comment has been minimized.

Copy link

@max10rogerio max10rogerio commented Jan 20, 2021

And if we implements this?

String.prototype.slugify = function (separator = "-") {
    return this
        .toString()
        .normalize('NFD')                   // split an accented letter in the base letter and the acent
        .replace(/[\u0300-\u036f]/g, '')   // remove all previously split accents
        .toLowerCase()
        .trim()
        .replace(/[^a-z0-9 ]/g, '')   // remove all chars not letters, numbers and spaces (to be replaced)
        .replace(/\s+/g, separator);
};

Ex:

"Exportação de _ peças - avícolas para Você".slugify() // exportacao-de-pecas-avicolas-para-voce

let text = "Café é o combustível para programação!!"
text.slugify("_") // cafe_e_o_combustivel_para_programacao

Nice!!!
I write in typescript without separator... looks:

export const slugify = (...args: (string | number)[]): string => {
    const value = args.join(' ')

    return value
        .normalize('NFD') // split an accented letter in the base letter and the acent
        .replace(/[\u0300-\u036f]/g, '') // remove all previously split accents
        .toLowerCase()
        .trim()
        .replace(/[^a-z0-9 ]/g, '') // remove all chars not letters, numbers and spaces (to be replaced)
        .replace(/\s+/g, '-') // separator
}

https://gist.github.com/max10rogerio/c67c5d2d7a3ce714c4bc0c114a3ddc6e

@shridharkalagi

This comment has been minimized.

Copy link

@shridharkalagi shridharkalagi commented Mar 9, 2021

Thanks for this!

@andreasnuesslein

This comment has been minimized.

Copy link

@andreasnuesslein andreasnuesslein commented Mar 16, 2021

And if we implements this?

String.prototype.slugify = function (separator = "-") {
    return this
        .toString()
        .normalize('NFD')                   // split an accented letter in the base letter and the acent
        .replace(/[\u0300-\u036f]/g, '')   // remove all previously split accents
        .toLowerCase()
        .trim()
        .replace(/[^a-z0-9 ]/g, '')   // remove all chars not letters, numbers and spaces (to be replaced)
        .replace(/\s+/g, separator);
};

Ex:

"Exportação de _ peças - avícolas para Você".slugify() // exportacao-de-pecas-avicolas-para-voce

let text = "Café é o combustível para programação!!"
text.slugify("_") // cafe_e_o_combustivel_para_programacao

Nice!!!
I write in typescript without separator... looks:

export const slugify = (...args: (string | number)[]): string => {
    const value = args.join(' ')

    return value
        .normalize('NFD') // split an accented letter in the base letter and the acent
        .replace(/[\u0300-\u036f]/g, '') // remove all previously split accents
        .toLowerCase()
        .trim()
        .replace(/[^a-z0-9 ]/g, '') // remove all chars not letters, numbers and spaces (to be replaced)
        .replace(/\s+/g, '-') // separator
}

https://gist.github.com/max10rogerio/c67c5d2d7a3ce714c4bc0c114a3ddc6e

awesome.

@iMakedonsky

This comment has been minimized.

Copy link

@iMakedonsky iMakedonsky commented Apr 9, 2021

awesome

@nfrette

This comment has been minimized.

Copy link

@nfrette nfrette commented Jun 10, 2021

Nice!!

@amranwebdeveloper

This comment has been minimized.

Copy link

@amranwebdeveloper amranwebdeveloper commented Jun 12, 2021

Complete version with @felipeftrindade suggestion:

function string_to_slug (str) {
    str = str.replace(/^\s+|\s+$/g, ''); // trim
    str = str.toLowerCase();
  
    // remove accents, swap ñ for n, etc
    var from = "àáãäâèéëêìíïîòóöôùúüûñç·/_,:;";
    var to   = "aaaaaeeeeiiiioooouuuunc------";

    for (var i=0, l=from.length ; i<l ; i++) {
        str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
    }

    str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
        .replace(/\s+/g, '-') // collapse whitespace and replace by -
        .replace(/-+/g, '-'); // collapse dashes

    return str;
}

Thanks for this idea

@Oleg-Imanilov

This comment has been minimized.

Copy link

@Oleg-Imanilov Oleg-Imanilov commented Aug 31, 2021

There is a lot of implementations for slugify over the internet right now. The thing that caught my attention is: so many years all custom versions copying same wrong patterns:

In this part:

    // remove accents, swap ñ for n, etc
    var from = "àáãäâèéëêìíïîòóöôùúüûñç·/_,:;";
    var to   = "aaaaaeeeeiiiioooouuuunc------";

Why do you converting anything to '-' over here by costly loop, if you taking care of all non alphanumerics later.

The right version would be:

    // remove accents, swap ñ for n, etc
    var from = "àáãäâèéëêìíïîòóöôùúüûñç";
    var to   = "aaaaaeeeeiiiioooouuuunc";

Cleaning non alphanumerics

    str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
        .replace(/\s+/g, '-') // collapse whitespace and replace by -
        .replace(/-+/g, '-'); // collapse dashes

1st - it will connect several words if separated by invalid chars only
2nd - you taking care of ' ' & '-' two times

The more optimal way to fix it:

    str = str.replace(/[^a-z0-9]/g, '-') // remove all except alphanumerics & replace all with '-'
        .replace(/-+/g, '-'); // collapse dashes
@juanlanus

This comment has been minimized.

Copy link

@juanlanus juanlanus commented Sep 1, 2021

@Oleg-Imanilov:
You are right if you needed to support IE.
Else the "normalize" approach is preferable because it does not depends on the developer providing two synchronized lengthy character strings:

    ...
    .normalize( 'NFD' )                   // split an accented letter in the base letter and its acent
    .replace( /[\u0300-\u036f]/g, '' )   // remove all previously split accents
    ...

This is a native JS Unicode function.

@M4TH76

This comment has been minimized.

Copy link

@M4TH76 M4TH76 commented Nov 26, 2021

Great!!!
And if with we move trim() down and add "-" to the exclusion

"five-year-old ?".slugify() 
//result:   "five-year-old" instead of "fiveyearold-" 
String.prototype.slugify = function (separator = "-") {
    return this
        .toString()
        .normalize('NFD')                   // split an accented letter in the base letter and the acent
        .replace(/[\u0300-\u036f]/g, '')   // remove all previously split accents
        .toLowerCase()
        .replace(/[^a-z0-9 -]/g, '')   // remove all chars not letters, numbers and spaces (to be replaced)
        .trim()
        .replace(/\s+/g, separator);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment