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

commented Jul 3, 2014

Neat! Thanks for sharing

@NorikDavtian

This comment has been minimized.

Copy link

commented Aug 18, 2014

Yeh, thanks for sharing 👍

@grabcode

This comment has been minimized.

Copy link

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

commented Nov 24, 2014

Great snippet! Saved me a lot of time.

@amirouche

This comment has been minimized.

Copy link

commented Dec 10, 2014

thx!

@alexbruno

This comment has been minimized.

Copy link

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

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

commented Apr 28, 2015

Thanks!!!

@linfongi

This comment has been minimized.

Copy link

commented Apr 30, 2015

This is Awesome!!

@lfalvarez

This comment has been minimized.

Copy link

commented Jun 24, 2015

👍

@ZioMitch

This comment has been minimized.

Copy link

commented Aug 14, 2015

Thank you!

@stevemoser

This comment has been minimized.

Copy link

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

commented Oct 15, 2015

Thanks

@bandicsongor

This comment has been minimized.

Copy link

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"

@edgren

This comment has been minimized.

Copy link

commented Nov 22, 2015

Just what I looked for! Many thanks!

@jpidelatorre

This comment has been minimized.

Copy link

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

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

commented Feb 26, 2016

thank u

@kganser

This comment has been minimized.

Copy link

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

commented Apr 11, 2016

❤️

@avinayak

This comment has been minimized.

Copy link

commented Apr 20, 2016

😗

@marcaum54

This comment has been minimized.

Copy link

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

commented Jun 12, 2016

Noooooish!

@phocks

This comment has been minimized.

Copy link

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

commented Jul 12, 2016

thanks

@shubhendusaurabh

This comment has been minimized.

Copy link

commented Aug 15, 2016

Thanks

@ahmetkotan

This comment has been minimized.

Copy link

commented Aug 31, 2016

thanx (:

@tsbits

This comment has been minimized.

Copy link

commented Dec 5, 2016

Thanks ! :)

@agusmakmun

This comment has been minimized.

Copy link

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

commented Feb 9, 2017

Thanks!

@benbkk

This comment has been minimized.

Copy link

commented Feb 12, 2017

Thanks for this! Super useful! :)

@joseluisq

This comment has been minimized.

Copy link

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

commented Feb 20, 2017

@joseluisq missing ã. thanks for the contribution

@bvipul

This comment has been minimized.

Copy link

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

commented Mar 20, 2017

I have visit this page many times LOL . Thank you

@MacgyverMartins

This comment has been minimized.

Copy link

commented May 8, 2017

Thank you Man !!

@gitanupam

This comment has been minimized.

Copy link

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

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

commented Jun 21, 2017

Thanks

@martinfojtik

This comment has been minimized.

Copy link

commented Jul 6, 2017

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

@eek

This comment has been minimized.

Copy link

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

commented Aug 22, 2017

Thank You

@rewebcan

This comment has been minimized.

Copy link

commented Sep 12, 2017

Thx!

@serendipitist

This comment has been minimized.

Copy link

commented Sep 13, 2017

Thx

@falmar

This comment has been minimized.

Copy link

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

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

commented Nov 6, 2017

Thanks.

@ahmethakanbesel

This comment has been minimized.

Copy link

commented Nov 10, 2017

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

@tomasdev

This comment has been minimized.

Copy link

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

commented Jan 24, 2018

Thanks! 🤓

@ekstremedia

This comment has been minimized.

Copy link

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

commented Jan 31, 2018

awesome. ty!

@yop289

This comment has been minimized.

Copy link

commented Feb 7, 2018

thanks, same me a lot of time!!!

@sairoko12

This comment has been minimized.

Copy link

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

commented Feb 19, 2018

Great! thanks (y)

@lindseybradford

This comment has been minimized.

Copy link

commented Mar 28, 2018

Nice!

@philippeoz

This comment has been minimized.

Copy link

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

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

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

commented Jun 12, 2018

Thanks for sharing :)

@sirtimid

This comment has been minimized.

Copy link

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
}
@MohammadNajjary

This comment has been minimized.

Copy link

commented Jul 8, 2018

thanks brotha.

@David-Evan

This comment has been minimized.

Copy link

commented Aug 7, 2018

Ty my friend. Very usefull !

@eusonlito

This comment has been minimized.

Copy link

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

commented Sep 11, 2018

thanks

@tallesairan

This comment has been minimized.

Copy link

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

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

commented Dec 17, 2018

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

@jairoFernandez

This comment has been minimized.

Copy link

commented Dec 28, 2018

❤️

@ngunner

This comment has been minimized.

Copy link

commented Jan 4, 2019

Awesome thread folks!

@Wraithraiser

This comment has been minimized.

Copy link

commented Jan 15, 2019

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

@jdcookie

This comment has been minimized.

Copy link

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

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

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

commented Mar 28, 2019

Thanks, bro!

@eemzet

This comment has been minimized.

Copy link

commented Apr 1, 2019

Super Cool! Thank you!

@auvansang

This comment has been minimized.

Copy link

commented Apr 7, 2019

It works fine. Thank you!

@YoshiYo

This comment has been minimized.

Copy link

commented Apr 21, 2019

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

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.