Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Javascript Slugify
function slugify(text)
{
return text.toString().toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, ''); // Trim - from end of text
}
@forthehackofit

This comment has been minimized.

Copy link

@forthehackofit forthehackofit commented Jul 3, 2014

Neat! Thanks for sharing

@NorikDavtian

This comment has been minimized.

Copy link

@NorikDavtian NorikDavtian commented Aug 18, 2014

Yeh, thanks for sharing 👍

@grabcode

This comment has been minimized.

Copy link

@grabcode grabcode commented Oct 31, 2014

Thanks to google search, github, and you to make my job easy every now and then

@vafranca

This comment has been minimized.

Copy link

@vafranca vafranca commented Nov 24, 2014

Great snippet! Saved me a lot of time.

@amirouche

This comment has been minimized.

Copy link

@amirouche amirouche commented Dec 10, 2014

thx!

@alexbruno

This comment has been minimized.

Copy link

@alexbruno alexbruno commented Jan 17, 2015

Trim is much simpler than 2 regex replaces! Just do:

string.trim();

And your code works only for English!

@jasmo2

This comment has been minimized.

Copy link

@jasmo2 jasmo2 commented Mar 6, 2015

Thanks is useful, but can you give some link where I can find documentation

@hallison

This comment has been minimized.

Copy link

@hallison hallison commented Apr 28, 2015

Thanks!!!

@linfongi

This comment has been minimized.

Copy link

@linfongi linfongi commented Apr 30, 2015

This is Awesome!!

@lfalvarez

This comment has been minimized.

Copy link

@lfalvarez lfalvarez commented Jun 24, 2015

👍

@ZioMitch

This comment has been minimized.

Copy link

@ZioMitch ZioMitch commented Aug 14, 2015

Thank you!

@stevemoser

This comment has been minimized.

Copy link

@stevemoser stevemoser commented Aug 28, 2015

Cool. Here is a popular alternative for people that stumble across this page first.
https://github.com/dodo/node-slug

@macroramesh6

This comment has been minimized.

Copy link

@macroramesh6 macroramesh6 commented Oct 15, 2015

Thanks

@bandicsongor

This comment has been minimized.

Copy link

@bandicsongor bandicsongor commented Oct 27, 2015

I've completed a little:

  • with .trim() (thx. @alexbruno)
  • replace '&' to 'and'

My final version is:

return text.toString().toLowerCase().trim()
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(/&/g, '-and-')         // Replace & with 'and'
    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
    .replace(/\-\-+/g, '-');        // Replace multiple - with single -

Ex. " IT&Computer " => "it-and-computer"

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Nov 22, 2015

Just what I looked for! Many thanks!

@jpidelatorre

This comment has been minimized.

Copy link

@jpidelatorre jpidelatorre commented Dec 20, 2015

You can make it a lot shorter:

return text.toString().toLowerCase().trim()
    .replace(/&/g, '-and-')         // Replace & with 'and'
    .replace(/[\s\W-]+/g, '-')      // Replace spaces, non-word characters and dashes with a single dash (-)
@wafs

This comment has been minimized.

Copy link

@wafs wafs commented Jan 6, 2016

add

.replace(/-$/, '') // Remove last floating dash if exists

otherwise text containing smily faces at the end of them have floating dashes

@matteodem

This comment has been minimized.

Copy link

@matteodem matteodem commented Feb 26, 2016

thank u

@kganser

This comment has been minimized.

Copy link

@kganser kganser commented Mar 6, 2016

return string.toLowerCase()
  .replace(/[^\w\s-]/g, '') // remove non-word [a-z0-9_], non-whitespace, non-hyphen characters
  .replace(/[\s_-]+/g, '-') // swap any length of whitespace, underscore, hyphen characters with a single -
  .replace(/^-+|-+$/g, ''); // remove leading, trailing -
@theus

This comment has been minimized.

Copy link

@theus theus commented Apr 11, 2016

❤️

@avinayak

This comment has been minimized.

Copy link

@avinayak avinayak commented Apr 20, 2016

😗

@marcaum54

This comment has been minimized.

Copy link

@marcaum54 marcaum54 commented Apr 26, 2016

TY

I am using this, for change special char, Ex: Marcos Fábio > marcos-fabio

  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;

From: http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/

@turbojb

This comment has been minimized.

Copy link

@turbojb turbojb commented Jun 12, 2016

Noooooish!

@phocks

This comment has been minimized.

Copy link

@phocks phocks commented Jul 4, 2016

Thanks @stevemoser https://github.com/dodo/node-slug works great even in my Meteor app with the 'rfc3986' default

@shuboy2014

This comment has been minimized.

Copy link

@shuboy2014 shuboy2014 commented Jul 12, 2016

thanks

@shubhendusaurabh

This comment has been minimized.

Copy link

@shubhendusaurabh shubhendusaurabh commented Aug 15, 2016

Thanks

@ahmetkotan

This comment has been minimized.

Copy link

@ahmetkotan ahmetkotan commented Aug 31, 2016

thanx (:

@tsbits

This comment has been minimized.

Copy link

@tsbits tsbits commented Dec 5, 2016

Thanks ! :)

@agusmakmun

This comment has been minimized.

Copy link

@agusmakmun agusmakmun commented Dec 11, 2016

Thank you for this.
I created a snippet Auto Slugify: https://jsfiddle.net/agaust/xht31h97/2/

@gndx

This comment has been minimized.

Copy link

@gndx gndx commented Feb 9, 2017

Thanks!

@benbkk

This comment has been minimized.

Copy link

@benbkk benbkk commented Feb 12, 2017

Thanks for this! Super useful! :)

@joseluisq

This comment has been minimized.

Copy link

@joseluisq joseluisq commented Feb 19, 2017

ES6 version with special chars replacement.

function slugify (text) {
  const a = 'àáäâèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;'
  const b = 'aaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------'
  const p = new RegExp(a.split('').join('|'), 'g')

  return text.toString().toLowerCase()
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(p, c =>
        b.charAt(a.indexOf(c)))     // Replace special chars
    .replace(/&/g, '-and-')         // Replace & with 'and'
    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
    .replace(/\-\-+/g, '-')         // Replace multiple - with single -
    .replace(/^-+/, '')             // Trim - from start of text
    .replace(/-+$/, '')             // Trim - from end of text
}
@sergiokopplin

This comment has been minimized.

Copy link

@sergiokopplin sergiokopplin commented Feb 20, 2017

@joseluisq missing ã. thanks for the contribution

@bvipul

This comment has been minimized.

Copy link

@bvipul bvipul commented Feb 23, 2017

Thank you so much for this little snippet, does a lot of work and saved a lot of time doing it by myself. Thanks once again.

@gemblue

This comment has been minimized.

Copy link

@gemblue gemblue commented Mar 20, 2017

I have visit this page many times LOL . Thank you

@MacgyverMartins

This comment has been minimized.

Copy link

@MacgyverMartins MacgyverMartins commented May 8, 2017

Thank you Man !!

@gitanupam

This comment has been minimized.

Copy link

@gitanupam gitanupam commented May 13, 2017

Great! Simple and sweet. I am using Django and needed something corresponding to Django's slugify (https://docs.djangoproject.com/en/1.11/_modules/django/utils/text/) in javascript and this looks good! Sweet, simple, needs no libraries or licenses.

@awojtczyk

This comment has been minimized.

Copy link

@awojtczyk awojtczyk commented May 19, 2017

And with the polish letters:

function slugify (str) {
  const from  = "ąàáäâãåæćęęèéëêìíïîłńòóöôõøśùúüûñçżź",
      to    = "aaaaaaaaceeeeeeiiiilnoooooosuuuunczz",
      regex = new RegExp('[' + from.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + ']', 'g');

  if (str === null) return '';

  str = String(str).toLowerCase().replace(regex, function(c) {
    return to.charAt(from.indexOf(c)) || '-';
  });

  return str.replace(/[^\w\s-]/g, '').replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
};
@createvibe

This comment has been minimized.

@djalmaaraujo

This comment has been minimized.

Copy link

@djalmaaraujo djalmaaraujo commented Jun 21, 2017

Thanks

@martinfojtik

This comment has been minimized.

Copy link

@martinfojtik martinfojtik commented Jul 6, 2017

similar solution with more letters: https://stackoverflow.com/a/5782563/4939326

@eek

This comment has been minimized.

Copy link

@eek eek commented Aug 9, 2017

Awesome, but accent removal I think it's a must, I've made one, with a one-liner accent removal, that's not using some predefined chars.

Check it out - https://gist.github.com/eek/9c4887e80b3ede05c0e39fee4dce3747

@dustinpoissant

This comment has been minimized.

Copy link

@dustinpoissant dustinpoissant commented Aug 22, 2017

Thank You

@rewebcan

This comment has been minimized.

Copy link

@rewebcan rewebcan commented Sep 12, 2017

Thx!

@serendipitist

This comment has been minimized.

Copy link

@serendipitist serendipitist commented Sep 13, 2017

Thx

@falmar

This comment has been minimized.

Copy link

@falmar falmar commented Sep 23, 2017

// if you are lazy just... add more letter and their replacements and get rid of duplicates
const reduce = () => {
  const a = ('àáäâèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;' + 'ąàáäâãåæćęęèéëêìíïîłńòóöôõøśùúüûñçżź').split('')
  const b = ('aaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------' + 'aaaaaaaaceeeeeeiiiilnoooooosuuuunczz').split('')

  return a.reduce((acc, current, index) => {
    const exist = acc.a.find((char) => char === current)

    if (exist) {
      return acc
    }

    acc.a.push(current)
    acc.b.push(b[index])

    return acc
  }, {
    a: [],
    b: []
  })
}

const reduced = reduce()
const a = reduced.a.join('') // "àáäâèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;ąãåćęłõøż"
const b = reduced.b.join('') // "aaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------aaacelooz"
const p = new RegExp(a.split('').join('|'), 'g')

export default function slugify (text) {
  return text.toString().toLowerCase()
    .replace(/\s+/g, '-')      // Replace spaces with -
    .replace(p, c =>
      b.charAt(a.indexOf(c)))  // Replace special chars
    .replace(/&/g, '-and-')    // Replace & with 'and'
    .replace(/[^\w-]+/g, '')   // Remove all non-word chars
    .replace(/--+/g, '-')      // Replace multiple - with single -
    .replace(/^-+/, '')        // Trim - from start of text
    .replace(/-+$/, '')        // Trim - from end of text
}
import slugify from './slugify'

const slug = slugify('Great snippet! Saved me a lot of time.') // great-snippet-saved-me-a-lot-of-time
@tripflex

This comment has been minimized.

Copy link

@tripflex tripflex commented Oct 3, 2017

Here's my rendition of @kganser code, stripping out any non (a-z) characters or 0-9, trimming whitespace, and replacing with underscore _

function slugify(text){

  return text.toString().toLowerCase().trim()
    .replace(/[^\w\s-]/g, '') // remove non-word [a-z0-9_], non-whitespace, non-hyphen characters
    .replace(/[\s_-]+/g, '_') // swap any length of whitespace, underscore, hyphen characters with a single _
    .replace(/^-+|-+$/g, ''); // remove leading, trailing -

}

... yeah i basically just added .trim() ... but figured I would post it, and say thank you to everyone who came before me 😛

@cjwebdev

This comment has been minimized.

Copy link

@cjwebdev cjwebdev commented Nov 6, 2017

Thanks.

@ahmethakanbesel

This comment has been minimized.

Copy link

@ahmethakanbesel ahmethakanbesel commented Nov 10, 2017

Not working for Turkish language. (ö ğ ş ü characters)

@tomasdev

This comment has been minimized.

Copy link

@tomasdev tomasdev commented Nov 15, 2017

Don't do & => -and- the purpose of friendly URLs is not for users but rather search engines. And the and word doesn't add value at all (which is why most back-end systems also remove other pronouns and prepositions from it)

@janklever

This comment has been minimized.

Copy link

@janklever janklever commented Jan 24, 2018

Thanks! 🤓

@ekstremedia

This comment has been minimized.

Copy link

@ekstremedia ekstremedia commented Jan 27, 2018

Awesome thread, thank you. Added in norwegian letters:

   slugify (text) {
    const a = 'æøåàáäâèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;';
    const b = 'aoaaaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------';
    const p = new RegExp(a.split('').join('|'), 'g');
  
    return text.toString().toLowerCase()
      .replace(/\s+/g, '-')           // Replace spaces with -
      .replace(p, c =>
          b.charAt(a.indexOf(c)))     // Replace special chars
      .replace(/&/g, '-and-')         // Replace & with 'and'
      .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
      .replace(/\-\-+/g, '-')         // Replace multiple - with single -
      .replace(/^-+/, '')             // Trim - from start of text
      .replace(/-+$/, '');             // Trim - from end of text
  }
@fixwa

This comment has been minimized.

Copy link

@fixwa fixwa commented Jan 31, 2018

awesome. ty!

@yop289

This comment has been minimized.

Copy link

@yop289 yop289 commented Feb 7, 2018

thanks, same me a lot of time!!!

@sairoko12

This comment has been minimized.

Copy link

@sairoko12 sairoko12 commented Feb 16, 2018

For a better performance:

const slugify = text => {
  // Use hash map for special characters 
  let specialChars = {"à":'a',"ä":'a',"á":'a',"â":'a',"æ":'a',"å":'a',"ë":'e',"è":'e',"é":'e', "ê":'e',"î":'i',"ï":'i',"ì":'i',"í":'i',"ò":'o',"ó":'o',"ö":'o',"ô":'o',"ø":'o',"ù":'o',"ú":'u',"ü":'u',"û":'u',"ñ":'n',"ç":'c',"ß":'s',"ÿ":'y',"œ":'o',"ŕ":'r',"ś":'s',"ń":'n',"ṕ":'p',"ẃ":'w',"ǵ":'g',"ǹ":'n',"ḿ":'m',"ǘ":'u',"ẍ":'x',"ź":'z',"ḧ":'h',"·":'-',"/":'-',"_":'-',",":'-',":":'-',";":'-'};

    return text.toString().toLowerCase()
      .replace(/\s+/g, '-')           // Replace spaces with -
      .replace(/./g,(target, index, str) => specialChars[target] || target) // Replace special characters using the hash map
      .replace(/&/g, '-and-')         // Replace & with 'and'
      .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
      .replace(/\-\-+/g, '-')         // Replace multiple - with single -
      .replace(/^-+/, '')             // Trim - from start of text
      .replace(/-+$/, '');             // Trim - from end of text
};
@dohafaridi

This comment has been minimized.

Copy link

@dohafaridi dohafaridi commented Feb 19, 2018

Great! thanks (y)

@lindseybradford

This comment has been minimized.

Copy link

@lindseybradford lindseybradford commented Mar 28, 2018

Nice!

@philippeoz

This comment has been minimized.

Copy link

@philippeoz philippeoz commented Apr 13, 2018

Thanks @mathewbyrne!
And if it's useful to someone, the code...

String.prototype.removeAcento = function () {       
    var text = this.toLowerCase();                                                         
    text = text.replace(new RegExp('[ÁÀÂÃ]','gi'), 'a');
    text = text.replace(new RegExp('[ÉÈÊ]','gi'), 'e');
    text = text.replace(new RegExp('[ÍÌÎ]','gi'), 'i');
    text = text.replace(new RegExp('[ÓÒÔÕ]','gi'), 'o');
    text = text.replace(new RegExp('[ÚÙÛ]','gi'), 'u');
    text = text.replace(new RegExp('[Ç]','gi'), 'c');
    return text;                 
};

String.prototype.slugify = function () {
    return this.toString().toLowerCase().removeAcento().trim()
      .replace(/\s+/g, '-')           // Replace spaces with -
      .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
      .replace(/\-\-+/g, '-')         // Replace multiple - with single -
      .replace(/^-+/, '')             // Trim - from start of text
      .replace(/-+$/, '');            // Trim - from end of text
}
@dani3lsz

This comment has been minimized.

Copy link

@dani3lsz dani3lsz commented May 13, 2018

I like the grouping of @philippeoz. With the use of this wikipedia page (https://en.wikipedia.org/wiki/Wikipedia:Language_recognition_chart) I collected all characters that resonate to latin characters. Here is my function:

slugify(text) {
    text = text.toString().toLowerCase().trim();

    const sets = [
      {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'},
      {to: 'c', from: '[ÇĆĈČ]'},
      {to: 'd', from: '[ÐĎĐÞ]'},
      {to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'},
      {to: 'g', from: '[ĜĞĢǴ]'},
      {to: 'h', from: '[ĤḦ]'},
      {to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]'},
      {to: 'j', from: '[Ĵ]'},
      {to: 'ij', from: '[IJ]'},
      {to: 'k', from: '[Ķ]'},
      {to: 'l', from: '[ĹĻĽŁ]'},
      {to: 'm', from: '[Ḿ]'},
      {to: 'n', from: '[ÑŃŅŇ]'},
      {to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]'},
      {to: 'oe', from: '[Œ]'},
      {to: 'p', from: '[ṕ]'},
      {to: 'r', from: '[ŔŖŘ]'},
      {to: 's', from: '[ߌŜŞŠ]'},
      {to: 't', from: '[ŢŤ]'},
      {to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]'},
      {to: 'w', from: '[ẂŴẀẄ]'},
      {to: 'x', from: '[ẍ]'},
      {to: 'y', from: '[ÝŶŸỲỴỶỸ]'},
      {to: 'z', from: '[ŹŻŽ]'},
      {to: '-', from: '[·/_,:;\']'}
    ];

    sets.forEach(set => {
      text = text.replace(new RegExp(set.from,'gi'), set.to)
    });

    return text
      .replace(/\s+/g, '-')    // Replace spaces with -
      .replace(/[^\w-]+/g, '') // Remove all non-word chars
      .replace(/--+/g, '-')    // Replace multiple - with single -
      .replace(/^-+/, '')      // Trim - from start of text
      .replace(/-+$/, '')      // Trim - from end of text
  }
@wearecharette

This comment has been minimized.

Copy link

@wearecharette wearecharette commented Jun 8, 2018

Nice everyone! @dani3lsz version with personal preference & to -and-

slugify(text) {
    text = text.toString().toLowerCase().trim();

    const sets = [
      {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'},
      {to: 'c', from: '[ÇĆĈČ]'},
      {to: 'd', from: '[ÐĎĐÞ]'},
      {to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'},
      {to: 'g', from: '[ĜĞĢǴ]'},
      {to: 'h', from: '[ĤḦ]'},
      {to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]'},
      {to: 'j', from: '[Ĵ]'},
      {to: 'ij', from: '[IJ]'},
      {to: 'k', from: '[Ķ]'},
      {to: 'l', from: '[ĹĻĽŁ]'},
      {to: 'm', from: '[Ḿ]'},
      {to: 'n', from: '[ÑŃŅŇ]'},
      {to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]'},
      {to: 'oe', from: '[Œ]'},
      {to: 'p', from: '[ṕ]'},
      {to: 'r', from: '[ŔŖŘ]'},
      {to: 's', from: '[ߌŜŞŠ]'},
      {to: 't', from: '[ŢŤ]'},
      {to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]'},
      {to: 'w', from: '[ẂŴẀẄ]'},
      {to: 'x', from: '[ẍ]'},
      {to: 'y', from: '[ÝŶŸỲỴỶỸ]'},
      {to: 'z', from: '[ŹŻŽ]'},
      {to: '-', from: '[·/_,:;\']'}
    ];

    sets.forEach(set => {
      text = text.replace(new RegExp(set.from,'gi'), set.to)
    });

    return text.toString().toLowerCase()
      .replace(/\s+/g, '-')           // Replace spaces with -
      .replace(/&/g, '-and-')         // Replace & with 'and'
      .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
      .replace(/\--+/g, '-')         // Replace multiple - with single -
      .replace(/^-+/, '')             // Trim - from start of text
      .replace(/-+$/, '');             // Trim - from end of text
  }
@thisugee

This comment has been minimized.

Copy link

@thisugee thisugee commented Jun 12, 2018

Thanks for sharing :)

@sirtimid

This comment has been minimized.

Copy link

@sirtimid sirtimid commented Jun 14, 2018

My version with special characters replacements included greek

const slugify = str => {
	str = str || ''
	const a = 'àáäâèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;άαβγδεέζήηθιίϊΐκλμνξοόπρσςτυϋύΰφχψωώ'
	const b = 'aaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------aavgdeeziitiiiiklmnxooprsstyyyyfhpoo'
	const p = new RegExp(a.split('').join('|'), 'g')

	return str.toString().trim().toLowerCase()
		.replace(/ου/g, 'ou')
		.replace(/ευ/g, 'eu')
		.replace(/θ/g, 'th')
		.replace(/ψ/g, 'ps')
		.replace(/\//g, '-')
		.replace(/\s+/g, '-')           // Replace spaces with -
		.replace(p, c => b.charAt(a.indexOf(c)))     // Replace special chars
		.replace(/&/g, '-and-')         // Replace & with 'and'
		.replace(/[^\w\-]+/g, '')       // Remove all non-word chars
		.replace(/\-\-+/g, '-')         // Replace multiple - with single -
		.replace(/^-+/, '')             // Trim - from start of text
		.replace(/-+$/, '')             // Trim - from end of text
}
@devNajjary

This comment has been minimized.

Copy link

@devNajjary devNajjary commented Jul 8, 2018

thanks brotha.

@David-Evan

This comment has been minimized.

Copy link

@David-Evan David-Evan commented Aug 7, 2018

Ty my friend. Very usefull !

@eusonlito

This comment has been minimized.

Copy link

@eusonlito eusonlito commented Aug 9, 2018

Continue with @wearecharette version, added a separator option if you want to use different slug separators.

slugify(text, separator) {
    text = text.toString().toLowerCase().trim();

    const sets = [
        {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'},
        {to: 'c', from: '[ÇĆĈČ]'},
        {to: 'd', from: '[ÐĎĐÞ]'},
        {to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'},
        {to: 'g', from: '[ĜĞĢǴ]'},
        {to: 'h', from: '[ĤḦ]'},
        {to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]'},
        {to: 'j', from: '[Ĵ]'},
        {to: 'ij', from: '[IJ]'},
        {to: 'k', from: '[Ķ]'},
        {to: 'l', from: '[ĹĻĽŁ]'},
        {to: 'm', from: '[Ḿ]'},
        {to: 'n', from: '[ÑŃŅŇ]'},
        {to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]'},
        {to: 'oe', from: '[Œ]'},
        {to: 'p', from: '[ṕ]'},
        {to: 'r', from: '[ŔŖŘ]'},
        {to: 's', from: '[ߌŜŞŠ]'},
        {to: 't', from: '[ŢŤ]'},
        {to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]'},
        {to: 'w', from: '[ẂŴẀẄ]'},
        {to: 'x', from: '[ẍ]'},
        {to: 'y', from: '[ÝŶŸỲỴỶỸ]'},
        {to: 'z', from: '[ŹŻŽ]'},
        {to: '-', from: '[·/_,:;\']'}
    ];

    sets.forEach(set => {
        text = text.replace(new RegExp(set.from,'gi'), set.to);
    });

    text = text.toString().toLowerCase()
        .replace(/\s+/g, '-')         // Replace spaces with -
        .replace(/&/g, '-and-')       // Replace & with 'and'
        .replace(/[^\w\-]+/g, '')     // Remove all non-word chars
        .replace(/\--+/g, '-')        // Replace multiple - with single -
        .replace(/^-+/, '')           // Trim - from start of text
        .replace(/-+$/, '');          // Trim - from end of text

    if ((typeof separator !== 'undefined') && (separator !== '-')) {
        text = text.replace(/-/g, separator);
    }

    return text;
}
@jacobzlogar

This comment has been minimized.

Copy link

@jacobzlogar jacobzlogar commented Sep 11, 2018

thanks

@tallesairan

This comment has been minimized.

Copy link

@tallesairan tallesairan commented Oct 3, 2018

Continue with @wearecharette version, added a separator option if you want to use different slug separators.

slugify(text, separator) {
    text = text.toString().toLowerCase().trim();

    const sets = [
        {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'},
        {to: 'c', from: '[ÇĆĈČ]'},
        {to: 'd', from: '[ÐĎĐÞ]'},
        {to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'},
        {to: 'g', from: '[ĜĞĢǴ]'},
        {to: 'h', from: '[ĤḦ]'},
        {to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]'},
        {to: 'j', from: '[Ĵ]'},
        {to: 'ij', from: '[IJ]'},
        {to: 'k', from: '[Ķ]'},
        {to: 'l', from: '[ĹĻĽŁ]'},
        {to: 'm', from: '[Ḿ]'},
        {to: 'n', from: '[ÑŃŅŇ]'},
        {to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]'},
        {to: 'oe', from: '[Œ]'},
        {to: 'p', from: '[ṕ]'},
        {to: 'r', from: '[ŔŖŘ]'},
        {to: 's', from: '[ߌŜŞŠ]'},
        {to: 't', from: '[ŢŤ]'},
        {to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]'},
        {to: 'w', from: '[ẂŴẀẄ]'},
        {to: 'x', from: '[ẍ]'},
        {to: 'y', from: '[ÝŶŸỲỴỶỸ]'},
        {to: 'z', from: '[ŹŻŽ]'},
        {to: '-', from: '[·/_,:;\']'}
    ];

    sets.forEach(set => {
        text = text.replace(new RegExp(set.from,'gi'), set.to);
    });

    text = text.toString().toLowerCase()
        .replace(/\s+/g, '-')         // Replace spaces with -
        .replace(/&/g, '-and-')       // Replace & with 'and'
        .replace(/[^\w\-]+/g, '')     // Remove all non-word chars
        .replace(/\--+/g, '-')        // Replace multiple - with single -
        .replace(/^-+/, '')           // Trim - from start of text
        .replace(/-+$/, '');          // Trim - from end of text

    if ((typeof separator !== 'undefined') && (separator !== '-')) {
        text = text.replace(/-/g, separator);
    }

    return text;
}

<3
Thanks

@Allan-Nava

This comment has been minimized.

Copy link

@Allan-Nava Allan-Nava commented Dec 15, 2018

Continue with @wearecharette version, added a separator option if you want to use different slug separators.

slugify(text, separator) {
    text = text.toString().toLowerCase().trim();

    const sets = [
        {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'},
        {to: 'c', from: '[ÇĆĈČ]'},
        {to: 'd', from: '[ÐĎĐÞ]'},
        {to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'},
        {to: 'g', from: '[ĜĞĢǴ]'},
        {to: 'h', from: '[ĤḦ]'},
        {to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]'},
        {to: 'j', from: '[Ĵ]'},
        {to: 'ij', from: '[IJ]'},
        {to: 'k', from: '[Ķ]'},
        {to: 'l', from: '[ĹĻĽŁ]'},
        {to: 'm', from: '[Ḿ]'},
        {to: 'n', from: '[ÑŃŅŇ]'},
        {to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]'},
        {to: 'oe', from: '[Œ]'},
        {to: 'p', from: '[ṕ]'},
        {to: 'r', from: '[ŔŖŘ]'},
        {to: 's', from: '[ߌŜŞŠ]'},
        {to: 't', from: '[ŢŤ]'},
        {to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]'},
        {to: 'w', from: '[ẂŴẀẄ]'},
        {to: 'x', from: '[ẍ]'},
        {to: 'y', from: '[ÝŶŸỲỴỶỸ]'},
        {to: 'z', from: '[ŹŻŽ]'},
        {to: '-', from: '[·/_,:;\']'}
    ];

    sets.forEach(set => {
        text = text.replace(new RegExp(set.from,'gi'), set.to);
    });

    text = text.toString().toLowerCase()
        .replace(/\s+/g, '-')         // Replace spaces with -
        .replace(/&/g, '-and-')       // Replace & with 'and'
        .replace(/[^\w\-]+/g, '')     // Remove all non-word chars
        .replace(/\--+/g, '-')        // Replace multiple - with single -
        .replace(/^-+/, '')           // Trim - from start of text
        .replace(/-+$/, '');          // Trim - from end of text

    if ((typeof separator !== 'undefined') && (separator !== '-')) {
        text = text.replace(/-/g, separator);
    }

    return text;
}

it works! ;)

@alejandroxlopez

This comment has been minimized.

Copy link

@alejandroxlopez alejandroxlopez commented Dec 17, 2018

Wow everyone! what a great job making a great slugify function. Thanks!

@jairoFernandez

This comment has been minimized.

Copy link

@jairoFernandez jairoFernandez commented Dec 28, 2018

❤️

@ngunner

This comment has been minimized.

Copy link

@ngunner ngunner commented Jan 4, 2019

Awesome thread folks!

@Wraithraiser

This comment has been minimized.

Copy link

@Wraithraiser Wraithraiser commented Jan 15, 2019

Great job saved me a lot of time ! Thanks everyone :)

@jdcookie

This comment has been minimized.

Copy link

@jdcookie jdcookie commented Feb 13, 2019

Continue with @wearecharette version, added a separator option if you want to use different slug separators.

slugify(text, separator) {
    text = text.toString().toLowerCase().trim();

    const sets = [
        {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'},
        {to: 'c', from: '[ÇĆĈČ]'},
        {to: 'd', from: '[ÐĎĐÞ]'},
        {to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]'},
        {to: 'g', from: '[ĜĞĢǴ]'},
        {to: 'h', from: '[ĤḦ]'},
        {to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]'},
        {to: 'j', from: '[Ĵ]'},
        {to: 'ij', from: '[IJ]'},
        {to: 'k', from: '[Ķ]'},
        {to: 'l', from: '[ĹĻĽŁ]'},
        {to: 'm', from: '[Ḿ]'},
        {to: 'n', from: '[ÑŃŅŇ]'},
        {to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]'},
        {to: 'oe', from: '[Œ]'},
        {to: 'p', from: '[ṕ]'},
        {to: 'r', from: '[ŔŖŘ]'},
        {to: 's', from: '[ߌŜŞŠ]'},
        {to: 't', from: '[ŢŤ]'},
        {to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]'},
        {to: 'w', from: '[ẂŴẀẄ]'},
        {to: 'x', from: '[ẍ]'},
        {to: 'y', from: '[ÝŶŸỲỴỶỸ]'},
        {to: 'z', from: '[ŹŻŽ]'},
        {to: '-', from: '[·/_,:;\']'}
    ];

    sets.forEach(set => {
        text = text.replace(new RegExp(set.from,'gi'), set.to);
    });

    text = text.toString().toLowerCase()
        .replace(/\s+/g, '-')         // Replace spaces with -
        .replace(/&/g, '-and-')       // Replace & with 'and'
        .replace(/[^\w\-]+/g, '')     // Remove all non-word chars
        .replace(/\--+/g, '-')        // Replace multiple - with single -
        .replace(/^-+/, '')           // Trim - from start of text
        .replace(/-+$/, '');          // Trim - from end of text

    if ((typeof separator !== 'undefined') && (separator !== '-')) {
        text = text.replace(/-/g, separator);
    }

    return text;
}

superb

@roipoussiere

This comment has been minimized.

Copy link

@roipoussiere roipoussiere commented Feb 18, 2019

Thank you for these suggestions!

I personally prefer to replace æ and Æ by ae instead of a.

You can do this by replacing:

    {to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'},

with:

    {to: 'a', from: '[ÀÁÂÃÄÅĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]'}, // note the Æ removing
    {to: 'ae', from: '[Æ]'},

Also, I think the first .toLowerCase() is not necessary, since the regex performs a case-insensitive search.

@rolero

This comment has been minimized.

Copy link

@rolero rolero commented Mar 28, 2019

Seems this is not working with Chinese characters: 商务计划模板

Replaced:
.replace(/[^\w\-]+/g, '') // Remove all non-word chars

with

.replace(/[^a-zA-Z0-9_\u3400-\u9FBF\s-]/g, '') // Remove all non-word chars

Also have a look at this:
https://stackoverflow.com/questions/25698733/how-to-generate-url-slug-from-chinese-characters

@RodrigoPauletti

This comment has been minimized.

Copy link

@RodrigoPauletti RodrigoPauletti commented Mar 28, 2019

Thanks, bro!

@xndrdev

This comment has been minimized.

Copy link

@xndrdev xndrdev commented Apr 1, 2019

Super Cool! Thank you!

@auvansang

This comment has been minimized.

Copy link

@auvansang auvansang commented Apr 7, 2019

It works fine. Thank you!

@YoshiYo

This comment has been minimized.

Copy link

@YoshiYo YoshiYo commented Apr 21, 2019

The last one mentioned by @jdcookie is very cool!
Thank you :)

@vineeth030

This comment has been minimized.

Copy link

@vineeth030 vineeth030 commented Jul 17, 2019

Thanks man : ) 👍 👍

@rajeshisnepali

This comment has been minimized.

Copy link

@rajeshisnepali rajeshisnepali commented Aug 12, 2019

Thanks.

@caiojhonny

This comment has been minimized.

Copy link

@caiojhonny caiojhonny commented Oct 7, 2019

Thank you!

@jasonwiener

This comment has been minimized.

Copy link

@jasonwiener jasonwiener commented Jan 31, 2020

thanks for this!

@kjetilge

This comment has been minimized.

Copy link

@kjetilge kjetilge commented Feb 27, 2020

In Norwegian "Å" is also often replaced width aa. In order to do this we need to include:

{to: 'aa', from: '[a°]'}

Somehow "å" becomes the sequence: "a" followed by degree "°"

@jdahdah

This comment has been minimized.

Copy link

@jdahdah jdahdah commented Jun 25, 2020

For better support for German, here's a modification on top of @eusonlito's script with the expected mappings of umlauts and ß (ä -> ae, ß-> ss, etc):

function slugify(text, separator) {
  text = text.toString().toLowerCase().trim()

  const sets = [
    { to: "a", from: "[ÀÁÂÃÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]" },
    { to: "ae", from: "[Ä]" },
    { to: "c", from: "[ÇĆĈČ]" },
    { to: "d", from: "[ÐĎĐÞ]" },
    { to: "e", from: "[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]" },
    { to: "g", from: "[ĜĞĢǴ]" },
    { to: "h", from: "[ĤḦ]" },
    { to: "i", from: "[ÌÍÎÏĨĪĮİỈỊ]" },
    { to: "j", from: "[Ĵ]" },
    { to: "ij", from: "[IJ]" },
    { to: "k", from: "[Ķ]" },
    { to: "l", from: "[ĹĻĽŁ]" },
    { to: "m", from: "[Ḿ]" },
    { to: "n", from: "[ÑŃŅŇ]" },
    { to: "o", from: "[ÒÓÔÕØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]" },
    { to: "oe", from: "[΅]" },
    { to: "p", from: "[ṕ]" },
    { to: "r", from: "[ŔŖŘ]" },
    { to: "s", from: "[ŚŜŞŠ]" },
    { to: "ss", from: "[ß]" },
    { to: "t", from: "[ŢŤ]" },
    { to: "u", from: "[ÙÚÛŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]" },
    { to: "ue", from: "[Ü]" },
    { to: "w", from: "[ẂŴẀẄ]" },
    { to: "x", from: "[ẍ]" },
    { to: "y", from: "[ÝŶŸỲỴỶỸ]" },
    { to: "z", from: "[ŹŻŽ]" },
    { to: "-", from: "[·/_,:;']" },
  ]

  sets.forEach((set) => {
    text = text.replace(new RegExp(set.from, "gi"), set.to)
  })

  text = text
    .toString()
    .toLowerCase()
    .replace(/\s+/g, "-") // Replace spaces with -
    .replace(/&/g, "-and-") // Replace & with 'and'
    .replace(/[^\w\-]+/g, "") // Remove all non-word chars
    .replace(/\--+/g, "-") // Replace multiple - with single -
    .replace(/^-+/, "") // Trim - from start of text
    .replace(/-+$/, "") // Trim - from end of text

  if (typeof separator !== "undefined" && separator !== "-") {
    text = text.replace(/-/g, separator)
  }

  return text
}
@kheob

This comment has been minimized.

Copy link

@kheob kheob commented Aug 7, 2020

Nice thanks for sharing

@ImMaax

This comment has been minimized.

Copy link

@ImMaax ImMaax commented Sep 26, 2020

Thanks a lot!

@mkMoSs

This comment has been minimized.

Copy link

@mkMoSs mkMoSs commented Oct 21, 2020

Extending @jdahdah 's version with support for Greek

function slugify(text, separator) {
        text = text.toString().toLowerCase().trim()

        const sets = [
            {to: "a", from: "[ÀÁÂÃÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶΑΆ]"},
            {to: "b", from: "[Β]"},
            {to: "ae", from: "[Ä]"},
            {to: "c", from: "[ÇĆĈČ]"},
            {to: "d", from: "[ÐĎĐÞΔ]"},
            {to: "e", from: "[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆΕΈ]"},
            {to: "f", from: "[Φ]"},
            {to: "g", from: "[ĜĞĢǴΓ]"},
            {to: "h", from: "[ĤḦ]"},
            {to: "i", from: "[ÌÍÎÏĨĪĮİỈỊΗΉΙΊΪΐ]"},
            {to: "j", from: "[Ĵ]"},
            {to: "ij", from: "[IJ]"},
            {to: "k", from: "[ĶΚ]"},
            {to: "ks", from: "[Ξ]"},
            {to: "l", from: "[ĹĻĽŁΛ]"},
            {to: "m", from: "[ḾΜ]"},
            {to: "n", from: "[ÑŃŅŇΝ]"},
            {to: "o", from: "[ÒÓÔÕØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠΟΌΩΏ]"},
            {to: "oe", from: "[΅]"},
            {to: "p", from: "[ṕΠ]"},
            {to: "ps", from: "[Ψ]"},
            {to: "r", from: "[ŔŖŘΡ]"},
            {to: "s", from: "[ŚŜŞŠΣς]"},
            {to: "ss", from: "[ß]"},
            {to: "t", from: "[ŢŤΤ]"},
            {to: "th", from: "[Θ]"},
            {to: "u", from: "[ÙÚÛŨŪŬŮŰŲỤỦỨỪỬỮỰƯΥΎΫΰ]"},
            {to: "ue", from: "[Ü]"},
            {to: "w", from: "[ẂŴẀẄ]"},
            {to: "x", from: "[ẍΧ]"},
            {to: "y", from: "[ÝŶŸỲỴỶỸ]"},
            {to: "z", from: "[ŹŻŽΖ]"},
            {to: "-", from: "[·/_,:;']"},
        ]

        sets.forEach((set) => {
            text = text.replace(new RegExp(set.from, "gi"), set.to)
        })

        text = text
          .toString()
          .toLowerCase()
          .replace(/\s+/g, "-") // Replace spaces with -
          .replace(/&/g, "-and-") // Replace & with 'and'
          .replace(/[^\w\-]+/g, "") // Remove all non-word chars
          .replace(/\--+/g, "-") // Replace multiple - with single -
          .replace(/^-+/, "") // Trim - from start of text
          .replace(/-+$/, "") // Trim - from end of text

        if(typeof separator !== "undefined" && separator !== "-") {
            text = text.replace(/-/g, separator)
        }

        return text
    }
@yeet-bix

This comment has been minimized.

Copy link

@yeet-bix yeet-bix commented Oct 21, 2020

❤️ :shipit:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.