URL slug

5 июля 2026 · ~14 мин чтения

веб url seo концепция cms

URL slug

Slug (в контексте веба) — это короткий, человекочитаемый кусок адреса страницы, идентифицирующий конкретный ресурс: не случайные цифры и не хеш, а осмысленная строка вроде url-slug в конце URL https://example.com/blog/url-slug. По этой строке сервер понимает, какую именно статью, товар или профиль нужно показать.

История

У slug неожиданно длинная и красивая биография — большая её часть прошла ещё до всякого веба.

XIX век, типография. Слово «slug» в английском означало и слизняка, и болванку. В типографском ремесле slug — это отлитая на линотипе (машине для набора текста, изобретённой Оттмаром Мергенталером в 1884 году) металлическая полоска с одной строкой набора. Линотип каждую строку отливал целиком как единый брусок — и этот брусок назывался slug.

Газетное дело XX века. В редакциях slug превратился в жаргон для короткой рабочей метки материала. Когда репортёр приносил заметку в редакцию, ей давали короткое имя — «pentagon-leak», «city-hall-fire», — чтобы редактор, верстальщик и корректор понимали, о какой статье речь, ещё до финального заголовка. Финальный заголовок (headline) мог родиться в последний момент; slug служил стабильным идентификатором на всё время производства.

Начало 2000-х, приход в веб. Ранние блоги и CMS столкнулись с той же проблемой, что и газетчики: у статьи есть внутренний ID в базе (число вроде 12345) и есть заголовок, который может меняться. Нужно что-то посередине — стабильное, короткое, читаемое.

2005 — RFC 3986. В январе выходит спецификация «Uniform Resource Identifier (URI): Generic Syntax» за авторством Тима Бернерса-Ли, Роя Филдинга и Ларри Мазинтера. Именно она формально описывает, какие символы можно класть в путь URL, а какие нужно кодировать через percent-encoding. Slug живёт в рамках этих правил.

1998 — «Cool URIs don't change». Ещё до RFC 3986 Тим Бернерс-Ли публикует на сайте W3C короткое эссе с этим названием. Главный тезис: адреса должны жить вечно. Меняешь URL — ломаешь чужие ссылки, закладки и историю поисковиков. С точки зрения slug это означает: выбирай его вдумчиво, потому что менять придётся с 301-редиректом.

Наши дни. Slug — стандартный элемент любой современной CMS, статического генератора сайтов и REST-API. В рунете за ним закрепилось родственное имя — ЧПУ, «человекопонятный URL».

Что это такое

Если открыть адрес любой статьи в блоге, он часто выглядит примерно так:

https://blog.example.com/2026/07/05/url-slug
                          └─год──┘└м─┘└день┘└─── slug ───┘

Хвостовая часть, url-slug, — это и есть slug. По ней сервер понимает, что показывать. Всё остальное — дата, категория — это уже «упаковка», которая может быть, а может и не быть.

Чтобы уложить slug в голову, полезно сравнить его с ближайшими родственниками.

Slug vs числовой ID. Числовой ID — это то, что стоит в базе данных как первичный ключ: posts.id = 12345. URL вида ?p=12345 — короткий и уникальный, но человеку он ничего не говорит. Нельзя понять, что за статья, глядя на адрес; нельзя написать её ссылку от руки; нельзя приятно поделиться в чате. Slug — компромисс между уникальностью для машины и читаемостью для человека.

Slug vs UUID. UUID (Universally Unique IDentifier) — это 128-битный идентификатор вида 550e8400-e29b-41d4-a716-446655440000. UUID гарантированно уникален во вселенной, его удобно генерировать в распределённой системе, но для URL он ужасен: длинный, страшный, не запоминается. Slug — противоположный полюс: не гарантирует уникальности «сам по себе» (её надо обеспечивать вручную), зато читаем.

Slug vs percent-encoded кириллица. В теории RFC 3986 разрешает в URL и кириллицу — но только в закодированном виде. Заголовок «Про URL slug» после кодирования превращается в что-то вроде %D0%9F%D1%80%D0%BE%20URL%20slug — набор процентных escape-последовательностей. Это работает, но выглядит как пароль от аквариума. Именно поэтому большинство блогов транслитерируют slug латиницей: pro-url-slug вместо %D0%9F%D1%80%D0%BE-url-slug.

Связь с ЧПУ. ЧПУ («человекопонятный URL») — русский зонтичный термин для адресов вида /blog/pro-url-slug в противовес техническим /index.php?post_id=12345&cat=3. Slug — конкретный кирпичик, из которого ЧПУ обычно и составляют. Можно сказать так: ЧПУ — это идеология «URL должен читаться человеком», а slug — самая распространённая техника, которой этой идеологии добиваются.

Аналогии из жизни

Табличка на двери кабинета. У любого сотрудника в базе кадров есть табельный номер — уникальный, безошибочный, но бессмысленный при взгляде. А на двери кабинета висит табличка «Иванов А. П., главный бухгалтер». По ней клиент понимает, куда стучаться. Slug — это как раз такая табличка: не заменяет табельный номер, а помогает человеку.

Где ломается: если у тебя в компании пять Ивановых А. П., таблички придётся уточнять («Иванов А. П. (Финансы)», «Иванов А. П. (Логистика)»). Так же и с slug: когда в блоге две статьи с одинаковым заголовком, движок вынужден добавлять суффикс: url-slug, url-slug-2. И база всё равно хранит числовой ID параллельно — потому что slug сам по себе не гарантирует уникальности.

Название вагона в поезде. В расписании поезд идёт под номером — например, «098А». Но пассажир мыслит по-другому: «Москва — Санкт-Петербург, ночной». Официальный номер стабилен и уникален, «название» — читаемо и удобно. Slug играет роль такого «названия»: чтобы можно было сказать другу «открой /pro-slug», не диктуя пятизначные ID.

Где ломается: если поезд поменяет маршрут, «Москва — Санкт-Петербург, ночной» перестанет соответствовать реальности. С slug то же самое: если заголовок статьи радикально поменялся, а slug остался старым, читатель может запутаться. Обновлять slug — можно, но с редиректом со старого на новый.

Дорожный знак с названием посёлка. Съезд с трассы можно было бы отмечать номером километра («съезд на 143-м км») — сухо и точно. Но обычно вешают табличку с названием: «Малые Вязёмы». Так водитель понимает, куда съедет.

Где ломается: два разных посёлка с одним именем существуют в природе — «Александровка» встречается в каждом втором районе. Пришлось бы добавлять уточнение: «Александровка (Тульская обл.)». Это ровно та же проблема коллизий slug — когда одинаковые названия конфликтуют, приходится вводить дополнительный контекст (категория, регион, дата).

Как это работает

Внутри веб-приложения slug живёт по всей цепочке: от превращения заголовка в строку до маршрутизации запроса.

Шаг 1. Slugify — превращение заголовка в slug.

На вход — произвольная строка вроде «Про URL slug и почему он такой». На выходе — pro-url-slug-i-pochemu-on-takoj (или подобное). Стандартный процесс:

  1. Нижний регистр. «Про URL slug» → «про url slug». Заглавные и строчные в URL формально различаются, но их проще делать одинаковыми, чтобы /Про-Url и /про-url не считались разными адресами.
  2. Транслитерация или Unicode-нормализация. Если политика — латиница, буквы переводятся по таблице (например, ГОСТ, ISO 9 или упрощённая «народная»): «про» → «pro», «почему» → «pochemu». Django, WordPress и nodejs-библиотеки типа slugify умеют это из коробки. Если политика — Unicode-slug, то применяется нормализация NFC/NFKC (стандарт консорциума Unicode), чтобы одинаковые визуально символы приводились к каноническому виду.
  3. Удаление спецсимволов. Точки, запятые, восклицательные знаки, скобки, кавычки, апострофы — прочь. Остаются только буквы, цифры и пробелы.
  4. Замена пробелов на разделители. Пробел превращается в дефис. Именно дефис, а не подчёркивание — Google Search Central явно рекомендует дефисы, потому что поисковик воспринимает их как границы слов, а подчёркивания — как «склейку» слова в одно.
  5. Обрезка длины. Обычно slug ограничивают 60–100 символами — иначе URL становится нечитаемым и хуже переносится в мессенджерах.

Шаг 2. Уникальность и коллизии.

Готовый slug сохраняется в базу как отдельная колонка (в Django — поле SlugField, в WordPress — post_name). Обычно на неё вешают уникальный индекс. Если пользователь опубликовал две статьи с одинаковыми заголовками, движок обнаруживает конфликт и добавляет суффикс: url-slug, url-slug-2, url-slug-3. Реже используют случайный короткий хвост: url-slug-a3f.

Шаг 3. Маршрутизация.

Когда пользователь открывает https://blog.example.com/2026/07/05/url-slug, происходит примерно следующее:

  1. Браузер отправляет HTTP-запрос на сервер.
  2. Сервер (nginx, Apache, встроенный в фреймворк роутер) читает путь и по правилу маршрутизации вытаскивает slug: например, паттерн /{year}/{month}/{day}/{slug} вычленяет url-slug.
  3. Приложение делает запрос в базу: «найди пост, у которого дата = 2026-07-05 И slug = 'url-slug'».
  4. Если находит — рендерит страницу. Если нет — возвращает 404.

Slug тут выступает как «естественный ключ» для запроса. Никакого числового ID в URL не видно, но при этом в базе он всё равно есть, и внешние ссылки (комментарии, лайки, аналитика) обычно завязаны именно на него, а не на slug — чтобы можно было безопасно переименовывать.

Шаг 4. Смена slug и 301-редирект.

Если slug пришлось поменять — сменилась тема статьи, исправлена опечатка, — грамотный движок сохранит старый slug в отдельной таблице redirects и при запросе старого URL вернёт HTTP-статус 301 Moved Permanently с новым адресом. Так чужие ссылки не сломаются, а поисковик перенесёт вес страницы на новый адрес.

Это прямое следствие принципа «Cool URIs don't change»: адрес живёт вечно, а если очень надо поменять — только с редиректом.

Где встречается в обычной жизни

Где встречается в IT и бизнесе

Кто пользуется

Альтернативы и конкуренты

Когда НЕ стоит использовать

Связанные понятия

Литература и источники

Где встретилось у меня

За последние сутки slug постоянно всплывал в работе над личной системой ежедневного дайджеста: он там задаёт имя markdown-файла статьи, путь на сервере и одновременно служит ключом идемпотентности — при повторном запуске за тот же день оркестратор ищет файл по slug и не даёт продублировать статью. По сути одна короткая строка — и имя файла, и URL, и предохранитель от двойного запуска: удобная демонстрация того, зачем slug вообще придуман.

Краткое резюме