Slug Generator/ URL-Friendly Names

Convert titles to URL-friendly slugs — handles accents, CJK characters, custom separators, and max length.

Separator
Max length
Input text / title
Slug
0 chars
Slug will appear here…
Try an example

Did this tool solve your problem?

What is a URL slug

A URL slug is the human-readable part of a URL that identifies a specific page, typically using lowercase letters, numbers, and hyphens. In `example.com/posts/how-to-seo`, the slug is `how-to-seo`. Good slugs are short, readable, and contain keywords — important for both SEO and user experience.

How to generate good slugs

Convert to lowercase, replace spaces and special characters with hyphens, remove stop words, and keep core keywords. For example, 'How to Learn Python Programming' becomes `how-to-learn-python`. Shorter URLs are better, but maintain readability. Avoid dates and IDs in slugs unless necessary.

Code Examples

JavaScript / Node.js
// npm install slugify
import slugify from 'slugify';

slugify('Hello World!', { lower: true })
// 'hello-world'

slugify('Cafe au Lait', { lower: true })
// 'cafe-au-lait'

// npm install limax (CJK support)
import limax from 'limax';
limax('你好世界')       // 'ni-hao-shi-jie' (pinyin)
limax('東京')           // 'dong-jing'

// Manual (no deps)
const slugify = (s) => s
  .toLowerCase()
  .normalize('NFD')
  .replace(/[\u0300-\u036f]/g, '')
  .replace(/[^a-z0-9]+/g, '-')
  .replace(/^-|-$/g, '');
Python
# pip install python-slugify
from slugify import slugify

slugify('Hello World!')
# 'hello-world'

slugify('Cafe au Lait')
# 'cafe-au-lait'

slugify('你好世界', allow_unicode=True)
# '你好世界'

# With max length
slugify('A very long title that should be truncated',
        max_length=30, word_boundary=True)
# 'a-very-long-title-that-should'
Go
// go get github.com/gosimple/slug
import "github.com/gosimple/slug"

slug.Make("Hello World!")
// "hello-world"

slug.Make("Cafe au Lait")
// "cafe-au-lait"

// Custom separator
slug.CustomMake("Hello World", "_")
// "hello_world"

// Truncate
s := slug.Make("A very long title here")
if len(s) > 50 {
    s = s[:50]
}
PHP / WordPress
<?php
// WordPress built-in
$slug = sanitize_title('Hello World! Cafe');
// 'hello-world-cafe'

// PHP custom
function to_slug(string $s): string {
    $s = mb_strtolower($s, 'UTF-8');
    $s = iconv('UTF-8', 'ASCII//TRANSLIT', $s);
    $s = preg_replace('/[^a-z0-9]+/', '-', $s);
    return trim($s, '-');
}

// Laravel
use Illuminate\Support\Str;
Str::slug('Hello World!');    // 'hello-world'
Str::slug('Hello World', '_'); // 'hello_world'

Frequently Asked Questions

What is a URL slug?
A slug is the readable part of a URL that identifies a specific page — made of lowercase letters, numbers, and hyphens, like /blog/my-first-post. Good slugs are concise, human-readable, and SEO-friendly. They avoid special characters, spaces, uppercase letters, and non-ASCII characters (unless using native-language URLs).
Why use hyphens instead of underscores in slugs?
Google treats hyphens (-) as word separators — recognizing my-blog-post as three distinct words. Underscores (_) are treated as connectors — making my_blog_post look like one word. Hyphens are therefore better for SEO. WordPress, GitHub, and Shopify all default to hyphens for the same reason.
How should I handle CJK characters in slugs?
Two main approaches: 1) Transliterate to pinyin/romaji/romanization (e.g., 你好世界 → ni-hao-shi-jie) — better for Latin-script SEO. 2) Use the native characters directly (e.g., /blog/你好世界) — modern browsers and search engines support this, but links will appear percent-encoded when shared. This tool supports both modes.
What's the ideal slug length?
SEO best practice is to keep slugs under 60-75 characters to avoid truncation in search results. Include your target keyword, drop stop words (a, the, of, etc.). For example: 'how-to-optimize-nextjs-performance' is an effective slug. Overly long slugs dilute keyword weight.
Which characters should be removed when creating a slug?
Remove or replace: spaces (-> separator), special symbols (!@#$%^&*()+=[]{}|;:',.<>?/\`~), accented characters (e->e, u->u), and control characters. Keep: letters (a-z), digits (0-9), separators (-._). Whether to keep CJK characters depends on your use case.
How do I generate slugs in Next.js or Node.js?
In Node.js: npm install slugify or limax (CJK/pinyin support). Basic manual implementation: str.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''). In Next.js file-based routing, the slug typically comes from the filename or a database field. WordPress has sanitize_title() built in.