URL slug
URL slug
Slug (в контексте веба) — это короткий, человекочитаемый кусок адреса страницы, идентифицирующий конкретный ресурс: не случайные цифры и не хеш, а осмысленная строка вроде
url-slugв конце URLhttps://example.com/blog/url-slug. По этой строке сервер понимает, какую именно статью, товар или профиль нужно показать.
История
У slug неожиданно длинная и красивая биография — большая её часть прошла ещё до всякого веба.
XIX век, типография. Слово «slug» в английском означало и слизняка, и болванку. В типографском ремесле slug — это отлитая на линотипе (машине для набора текста, изобретённой Оттмаром Мергенталером в 1884 году) металлическая полоска с одной строкой набора. Линотип каждую строку отливал целиком как единый брусок — и этот брусок назывался slug.
Газетное дело XX века. В редакциях slug превратился в жаргон для короткой рабочей метки материала. Когда репортёр приносил заметку в редакцию, ей давали короткое имя — «pentagon-leak», «city-hall-fire», — чтобы редактор, верстальщик и корректор понимали, о какой статье речь, ещё до финального заголовка. Финальный заголовок (headline) мог родиться в последний момент; slug служил стабильным идентификатором на всё время производства.
Начало 2000-х, приход в веб. Ранние блоги и CMS столкнулись с той же проблемой, что и газетчики: у статьи есть внутренний ID в базе (число вроде 12345) и есть заголовок, который может меняться. Нужно что-то посередине — стабильное, короткое, читаемое.
- 2003 — WordPress. Одна из первых массовых CMS, где термин «post slug» стал частью документации и интерфейса. WordPress по умолчанию строил slug из заголовка поста, приводил его к нижнему регистру, заменял пробелы на дефисы. Это до сих пор одна из настроек «Permalinks» в админке.
- 2005 — Django. Веб-фреймворк на Python, открытый в июле 2005-го, ввёл
SlugField— специальный тип поля в модели, и утилитуslugify()вdjango.utils.text. С тех пор slug — стандартная часть словаря веб-разработчика.
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 (или подобное). Стандартный процесс:
- Нижний регистр. «Про URL slug» → «про url slug». Заглавные и строчные в URL формально различаются, но их проще делать одинаковыми, чтобы
/Про-Urlи/про-urlне считались разными адресами. - Транслитерация или Unicode-нормализация. Если политика — латиница, буквы переводятся по таблице (например, ГОСТ, ISO 9 или упрощённая «народная»): «про» → «pro», «почему» → «pochemu». Django, WordPress и nodejs-библиотеки типа
slugifyумеют это из коробки. Если политика — Unicode-slug, то применяется нормализация NFC/NFKC (стандарт консорциума Unicode), чтобы одинаковые визуально символы приводились к каноническому виду. - Удаление спецсимволов. Точки, запятые, восклицательные знаки, скобки, кавычки, апострофы — прочь. Остаются только буквы, цифры и пробелы.
- Замена пробелов на разделители. Пробел превращается в дефис. Именно дефис, а не подчёркивание — Google Search Central явно рекомендует дефисы, потому что поисковик воспринимает их как границы слов, а подчёркивания — как «склейку» слова в одно.
- Обрезка длины. Обычно 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, происходит примерно следующее:
- Браузер отправляет HTTP-запрос на сервер.
- Сервер (nginx, Apache, встроенный в фреймворк роутер) читает путь и по правилу маршрутизации вытаскивает slug: например, паттерн
/{year}/{month}/{day}/{slug}вычленяетurl-slug. - Приложение делает запрос в базу: «найди пост, у которого дата = 2026-07-05 И slug = 'url-slug'».
- Если находит — рендерит страницу. Если нет — возвращает 404.
Slug тут выступает как «естественный ключ» для запроса. Никакого числового ID в URL не видно, но при этом в базе он всё равно есть, и внешние ссылки (комментарии, лайки, аналитика) обычно завязаны именно на него, а не на slug — чтобы можно было безопасно переименовывать.
Шаг 4. Смена slug и 301-редирект.
Если slug пришлось поменять — сменилась тема статьи, исправлена опечатка, — грамотный движок сохранит старый slug в отдельной таблице redirects и при запросе старого URL вернёт HTTP-статус 301 Moved Permanently с новым адресом. Так чужие ссылки не сломаются, а поисковик перенесёт вес страницы на новый адрес.
Это прямое следствие принципа «Cool URIs don't change»: адрес живёт вечно, а если очень надо поменять — только с редиректом.
Где встречается в обычной жизни
- Адреса статей в СМИ. Открой любую заметку на Meduza, RBC, «Ленте» — в конце URL человекочитаемая строка вроде
/news/2026/07/05/pochemu-vse-slomalos. Даже если ты не знаешь, о чём заметка, из slug можно догадаться. Это и есть его главное назначение. - Ссылки на Wikipedia.
https://ru.wikipedia.org/wiki/Единорог— заголовок статьи прямо в URL. Wikipedia использует нативные Unicode-slug на кириллице, что тоже вариант. Правда, при копировании в чат браузер автоматически кодирует «Единорог» в%D0%95%D0%B4%D0%B8%D0%BD%D0%BE%D1%80%D0%BE%D0%B3— компромисс между читаемостью в адресной строке и уродством при пересылке. - Товары в магазинах. У Ozon, Wildberries, Amazon в URL товара часто есть slug-часть:
/product/iphone-16-pro-titan-256gb-1234567. Первая часть — человекочитаемая для SEO, финальные цифры — числовой ID для гарантированной уникальности. Гибрид. - Профили в соцсетях. Twitter/X, Instagram, Telegram, GitHub — везде URL профиля построен на username:
https://github.com/torvalds,https://t.me/durov. Формально это тоже slug — только пользователь его выбирает сам, а не движок генерирует из заголовка. - Публикации в блог-платформах. Substack, Medium, Ghost, «Дзен» — все под капотом используют slug для статей. Иногда с числовым хвостом (Medium:
/story-title-a1b2c3d4), иногда без.
Где встречается в IT и бизнесе
- SEO (поисковая оптимизация). Одна из общеизвестных практик: ключевые слова из заголовка попадают в slug, а slug — в URL. Google Search Central явно указывает, что читаемые URL с осмысленными словами лучше воспринимаются пользователями и, косвенно, влияют на CTR (доля кликов из выдачи). Slug — самый прямой инструмент этого влияния. Нужно, когда: продвигаешь публичный контент.
- CMS и блог-движки. WordPress, Ghost, Strapi, Directus, Bitrix, «1С-Битрикс» — везде slug (или «символьный код» на языке Bitrix) — базовая сущность. Нужно, когда: публикуешь контент, где заголовки важны и людям, и поисковику.
- Статические генераторы сайтов. Hugo, Jekyll, Eleventy, Astro, Next.js — все они превращают имя markdown-файла или значение
slugиз frontmatter в путь HTML-страницы. Файлarticles/2026-07-05-url-slug.md→built/url-slug/index.html→ URL/url-slug. Нужно, когда: сайт собирается заранее и раздаётся статикой. - REST-API. Многие API используют slug как «естественный ключ» ресурса вместо числового ID. Например, GitHub API:
/repos/{owner}/{repo}— тут и owner, и repo — по сути slug. Нужно, когда: API публичное и по URL хочется понимать, что за ресурс. - Шаринг ссылок и запоминание. Продукт с «шеринговым» контентом (Notion, Google Docs с публичным доступом, Figma community) заботится о том, чтобы ссылка была читаемой. Slug помогает:
/share/quarterly-report-q3куда лучше, чем/share/f8d3b21c-9a4e-4b0f-a8e2-1c9d3f4b5a6e.
Кто пользуется
- WordPress. С 2003 года — эталонный пример slug в вебе. По разным оценкам, WordPress работает под очень большой долей всех сайтов в мире; slug там называется «post slug» и настраивается в разделе «Permalinks».
- Wikipedia. Использует slug для всех статей — на всех языках. При этом Wikipedia — редкий пример, где slug идут прямо на языке статьи (Unicode-slug), а не через транслитерацию.
- GitHub. Использует slug и для пользователей (
/torvalds), и для репозиториев (/linux), и для организаций. URL видаgithub.com/{user}/{repo}— это два slug подряд. Числовые ID (repo_id) тоже есть, но их видно только через API. - YouTube. Пример обратного подхода: URL видео —
/watch?v=dQw4w9WgXcQ— 11-символьный псевдослучайный код. Это не slug (не читается), а короткий идентификатор. Причина: заголовков видео миллиарды, коллизий было бы слишком много, а SEO YouTube двигает не через URL, а через собственный поиск. Полезное сравнение: когда у тебя контента слишком много и его пишут все подряд, slug перестаёт масштабироваться, и приходится возвращаться к коротким кодам. - Ghost, Medium, Substack. Все три платформы используют slug для статей, но с разной политикой конфликтов и разной длины.
- Django-приложения. Любые сайты, написанные на Django, — от Instagram (в ранние годы был на Django) до Disqus, от Mozilla Add-ons до National Geographic — используют встроенный
SlugField.
Альтернативы и конкуренты
- Числовой ID. URL вида
/post/12345. Плюсы: тривиально уникален, короток, не требует никакого slugify. Минусы: ничего не говорит человеку, плохо для SEO, некрасиво выглядит в чате. - UUID. URL вида
/post/550e8400-e29b-41d4-a716-446655440000. Плюсы: гарантирована глобальная уникальность даже в распределённой системе; можно генерировать на клиенте без запроса к серверу. Минусы: очень длинно, страшно, не запоминается — категорически не подходит для публичного контента, но хорош для приватных приглашений и «магических ссылок». - Короткий код / hash. URL вида
/p/aB3xQ(как у YouTube или битлинков). Плюсы: короткий, гарантированно уникальный, легко копируется. Минусы: нечитаемый; плюсы SEO нулевые. - Дата-путь. URL вида
/2026/07/05/без явного slug — весь путь строится из даты. Плюсы: отлично работает для дневников и хронологических блогов. Минусы: не масштабируется на две статьи в день, теряется темы; чаще используется в паре с slug, а не вместо. - Иерархический путь. URL вида
/category/subcategory/post-name(типичный WordPress). Гибрид: slug для листа плюс путь категорий. Плюс — красивая структура. Минус — при перекладывании поста в другую категорию URL рвётся.
Когда НЕ стоит использовать
- Приватные ресурсы, где угадывать URL нельзя. Если это ссылка на приватный документ, сброс пароля, «magic link» для авторизации — slug противопоказан. Нужен как раз непредсказуемый токен: UUID или длинный случайный код. Slug вида
/reset/vasya-ivanovлюбой сможет подобрать перебором; UUID/reset/550e8400-...— нет. - Часто меняющиеся заголовки. Если контент по своей природе меняется каждые несколько минут (лента новостей, real-time аналитика, оперативный ticker), тратить время на slug и редиректы бесполезно: цепочка редиректов начнёт расти, поисковик запутается. Проще числовой ID.
- Многоязычные сайты без стратегии. Если у одного и того же материала есть версии на пяти языках, надо заранее решить: один slug на все языки (обычно английский или транслит с русского) или разные slug на разных языковых версиях (
/ru/pro-slug,/en/about-slug). Обе стратегии работают, но случайно смешанные — источник багов. Пока не определился с политикой — лучше не выкатывать многоязычие с slug вообще.
Связанные понятия
- permalink (постоянная ссылка) — обещание, что данный URL никогда не изменится и всегда будет вести на этот ресурс; slug — типичная составляющая permalink.
- canonical URL — атрибут
<link rel="canonical">в HTML, которым сайт говорит поисковику «вот основной адрес этой страницы, даже если она доступна ещё по другим»; помогает при нескольких URL с одинаковым содержимым. - percent-encoding (процентное кодирование) — способ закодировать символы, которые нельзя класть в URL напрямую (пробелы, кириллицу, спецсимволы), через последовательности вида
%XX; slug латиницей его избегает. - Punycode — стандарт (RFC 3492, 2003) для кодирования Unicode-доменов в ASCII (например,
рфв домене превращается вxn--p1ai); для пути URL используется percent-encoding, а для самого домена — punycode. - транслитерация — перевод букв одного алфавита в другой по правилам (ГОСТ, ISO 9, «народная»); шаг slugify для кириллицы.
- Unicode-нормализация — приведение визуально одинаковых, но по-разному закодированных символов к каноническому виду (формы NFC/NFKC); нужна перед сравнением slug, чтобы не получить два «одинаковых» slug, которые технически разные.
- 301-редирект — HTTP-ответ «страница переехала навсегда»; используется, когда slug пришлось поменять, чтобы старые ссылки не сломались.
Литература и источники
- Wikipedia, «Slug (publishing)» — про типографские и газетные корни термина:
https://en.wikipedia.org/wiki/Slug_(publishing). - Wikipedia, «Clean URL» — про идеологию человекочитаемых URL:
https://en.wikipedia.org/wiki/Clean_URL. - RFC 3986, «Uniform Resource Identifier (URI): Generic Syntax» (2005) — базовая спецификация URL:
https://www.rfc-editor.org/rfc/rfc3986. - «Cool URIs don't change» (Tim Berners-Lee, 1998) — эссе о неизменяемости адресов:
https://www.w3.org/Provider/Style/URI. - Google Search Central, раздел «URL structure» — официальная рекомендация про дефисы, читаемость и структуру:
https://developers.google.com/search/docs/crawling-indexing/url-structure. - MDN Web Docs, «What is a URL?» — практический разбор частей URL:
https://developer.mozilla.org/ru/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL. - RFC 3492, «Punycode» (2003) — про кодирование Unicode-доменов:
https://www.rfc-editor.org/rfc/rfc3492.
Где встретилось у меня
За последние сутки slug постоянно всплывал в работе над личной системой ежедневного дайджеста: он там задаёт имя markdown-файла статьи, путь на сервере и одновременно служит ключом идемпотентности — при повторном запуске за тот же день оркестратор ищет файл по slug и не даёт продублировать статью. По сути одна короткая строка — и имя файла, и URL, и предохранитель от двойного запуска: удобная демонстрация того, зачем slug вообще придуман.
Краткое резюме
- Slug — короткая, человекочитаемая строка в URL, идентифицирующая ресурс: понятная человеку, обрабатываемая машиной, стабильная во времени.
- Термин пришёл из типографии XIX века через газетный жаргон и закрепился в вебе с CMS начала 2000-х — WordPress (2003) и Django (2005).
- Технически slug — это результат процедуры slugify: нижний регистр, транслитерация или Unicode-нормализация, чистка спецсимволов, пробелы через дефисы, обрезка длины; на базу вешается уникальный индекс, коллизии решаются суффиксами.
- Меняется slug только с 301-редиректом — по принципу «Cool URIs don't change» Тима Бернерса-Ли; иначе рвутся чужие ссылки и падает SEO.
- Slug незаменим для публичного контента (блоги, СМИ, товары), но противопоказан для приватных ресурсов, где на смену ему приходят UUID и случайные короткие коды.