
什么是 Slug?
Slug 是 URL 中用于标识特定页面的部分,采用人类可读且对 URL 友好的格式。它位于域名和任何路径前缀之后,代表将内容标题或主题转换为可在网址中安全使用的形式。
对于标题为“How to Bake Sourdough Bread at Home”的博客文章,其 slug 如下所示:
https://example.com/blog/how-to-bake-sourdough-bread-at-home
slug 是:how-to-bake-sourdough-bread-at-home

为什么不直接使用标题?
原始标题在 URL 中会导致几个问题:
空格 — URL 不能包含空格。浏览器会将其编码为 %20 或 +,产生像 how%20to%20bake%20sourdough%20bread 这样难看的 URL。
特殊字符 — 标点符号如撇号、逗号和问号必须进行百分号编码,使 URL 难以阅读和复制。
大写字母 — URL 在技术上是区分大小写的。某些服务器会将 /About 和 /about 视为不同页面,导致重复内容问题。
非 ASCII 字符 — 带重音的字母、中文字符、阿拉伯文字和表情符号在 URL 中都需要百分号编码。像“Über uns”这样的标题会变成 %C3%9Cber%20uns。
Slug 通过在将文本放入 URL 之前对其进行规范化来解决所有这些问题。
Slugify 的工作原理
将字符串转换为 slug 遵循一组一致的步骤:
- 全部小写 —
Hello World→hello world - Unicode 规范化 —
Ü→u,é→e,ñ→n - 将空格替换为连字符 —
hello world→hello-world - 移除非字母数字或连字符的字符 — 撇号、引号、斜杠等
- 合并多个连字符 —
hello--world→hello-world - 修剪开头和结尾的连字符 —
-hello-world-→hello-world
// JavaScript 中的简单 slug 函数
function slugify(text) {
return text
.toString()
.normalize('NFKD') // 拆分重音字符
.replace(/[\u0300-\u036f]/g, '') // 移除重音标记
.toLowerCase()
.trim()
.replace(/[^a-z0-9 -]/g, '') // 移除非字母数字字符
.replace(/\s+/g, '-') // 空格转连字符
.replace(/-+/g, '-') // 合并多个连字符
}
slugify('Hello, World! It\'s a test.') // → 'hello-world-its-a-test'
slugify('Ünternehmens-Bericht 2024') // → 'unternehmens-bericht-2024'
大多数框架(Django、Rails、Laravel、Next.js)都包含一个 slugify 工具或等效功能。你很少需要从头编写这个。

Slug 与 SEO
Slug 对搜索引擎排名有直接影响。原因如下:
URL 中的关键词 — 搜索引擎将 URL 路径作为排名信号。包含用户搜索的确切短语的 URL 比像 /posts/12345 这样的通用 ID 权重更高。
可读性影响点击率 — 搜索结果中的用户更有可能点击他们能阅读和理解的 URL。与页面标题匹配的 slug 让用户确信他们要去正确的地方。
链接分享 — 当有人在聊天或推文中粘贴 URL 时,有意义的 slug 无需用户点击即可传达主题。
规范化 — 如果你有多个可能指向相同内容的 URL(带尾部斜杠、不带、带查询字符串),一致的 slug 结构使规范化标签和重定向更易于管理。
Slug 设计规则
使用连字符,不要用下划线 — Google 将连字符视为单词分隔符。下划线将单词连接在一起,因此 my_page 被读作一个单词 mypage,而 my-page 被读作两个单词。使用连字符。
保持 slug 简短但具有描述性 — 目标为 3 到 5 个有意义的单词。how-to-format-json-online 比完整标题和裸 json 都好。
尽可能避免停用词 — 像“a”、“an”、“the”、“and”、“of”这样的词会增加长度而没有关键词价值。python-list-comprehension-guide 优于 a-guide-to-list-comprehensions-in-python。
一旦 slug 上线,切勿更改 — 每次更改 slug 都会破坏现有链接,损失反向链接权重,并产生 404 错误,除非你设置永久重定向。在发布前规划好 slug 结构。
除非必要,避免在 slug 中使用日期 — 日期会使内容显得过时,并在更新文章时需要重定向。javascript-async-await-guide 比 javascript-async-await-guide-2023 更持久。

不同平台中的 Slug
| 平台 | Slug 行为 |
|---|---|
| WordPress | 从标题自动生成,发布前可编辑 |
| Shopify | 为产品和集合自动生成 |
| Next.js / Nuxt | 基于文件的路由:文件名即为 slug |
| Django | SlugField + admin 中的 prepopulate_fields |
| Rails | FriendlyId gem 或自定义 to_param |
常见错误
使用文章 ID 作为 slug — 像 /blog/4839 这样的 URL 没有向搜索引擎传达任何关于内容的信息。如果必须包含 ID,请附加可读的 slug:/blog/4839-how-to-format-json。
重复的 slug — 两个具有相同 slug 的帖子会导致一个覆盖另一个或返回 500 错误。保存前务必检查唯一性。
更改 slug 而不设置重定向 — 更改 slug 而不设置 301 重定向会产生 404 并孤立任何入站链接。如果必须更改 slug,请立即设置永久重定向。
过长的 slug — 超过约 60 个字符的 slug 会在搜索结果中被截断,并且难以记忆。果断裁剪。
→ 使用 Slugify 字符串工具 将任何标题立即转换为干净、对 URL 安全的 slug。