Смена структуры URL в WordPress почти всегда оставляет хвост из старых адресов: часть ссылок уже лежит в поиске, часть — в закладках, часть — в логах сервера и внешних ссылках. Если просто поменять /2024/05/slug/ на /slug/ или убрать базу у рубрик, старые URL начинают отдавать 404. Это не всегда критично, но если таких адресов много, вы получаете лишний шум в логах, потерю веса внешних ссылок и путаницу для поисковых систем.
Ниже — рабочая схема: как диагностировать проблему, где настроить редиректы, как проверить результат и какие ошибки чаще всего ломают миграцию.
Когда проблема действительно есть
Не каждый 404 после редизайна — катастрофа. Но если вы видите одно и то же поведение на десятках или сотнях старых адресов, это уже техническая задача, а не единичный случай.
Типичные сценарии
- изменили структуру постоянных ссылок в
Настройки → Постоянные ссылки; - убрали дату из URL записей;
- перенесли сайт с одного домена на другой;
- изменили базу рубрик или произвели массовую чистку URL;
- включили плагин, который переписывает адреса, но старые ссылки не обработал.
Если у вас уже есть статья про дубли тегов, архивов и авторов, это соседняя задача: здесь речь не о каноникализации и индексации, а именно о сохранении доступности старых адресов и корректной переадресации.
Диагностика: какие URL ломаются и откуда они приходят
Перед тем как настраивать редиректы, нужно понять, какие старые адреса реально используются. Иначе вы начнёте редиректить всё подряд, а потом получите цепочки, петли или лишнюю нагрузку на сервер.
Что проверить в первую очередь
- логи веб-сервера: какие старые URL чаще всего запрашиваются;
- Google Search Console: раздел с ошибками сканирования и страницами с 404;
- внутренние ссылки в контенте и меню;
- внешние ссылки из старых публикаций, соцсетей, рассылок;
- карты сайта и кэшированные версии страниц.
Если у вас есть доступ к серверным логам, это самый полезный источник. Например, в Nginx можно быстро посмотреть частые запросы к старым адресам:
grep ' 404 ' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -30
Команда не идеальна для всех форматов логов, но для первичной оценки подходит. Смысл простой: вы увидите, какие старые URL запрашиваются чаще других.
Какой способ редиректа выбрать
Для WordPress есть три рабочих подхода: плагин, правила на уровне сервера и код в теме или мини-плагине. Универсального варианта нет — зависит от масштаба и того, кто будет сопровождать сайт дальше.
| Способ | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Плагин редиректов | Нужно быстро закрыть список старых URL без правки сервера | Удобно, видно историю переходов, проще для редактора | Дополнительная нагрузка, риск лишних правил |
| .htaccess / Nginx | Много URL, нужен быстрый ответ до загрузки WordPress | Производительнее, меньше зависимость от CMS | Нужен доступ к серверу и аккуратность в синтаксисе |
| PHP-код | Небольшой набор правил, нужен контроль через репозиторий | Гибко, можно хранить рядом с кодом проекта | Нельзя перегружать логику, важно не делать редирект на каждом хите |
Пошаговое решение через плагин редиректов
Если сайт уже в продакшене и вам нужно быстро закрыть старые адреса, плагин — самый безопасный старт. Для ручного управления часто используют Redirection. Он не выдуманный, давно существует и подходит для точечных 301-редиректов.
Что делать
- Соберите список старых URL из логов и Search Console.
- Добавьте правило на каждый важный адрес или на шаблон, если структура предсказуемая.
- Выбирайте
301 Moved Permanently, если адрес действительно заменён навсегда. - Не редиректите всё на главную без разбора — это плохой сигнал и для пользователей, и для поиска.
Пример логики для типичного случая: старые записи были с датой, новые — без даты. Тогда можно редиректить по шаблону, если slug сохранился.
^/\d{4}/\d{2}/([^/]+)/?$ /$1/ 301
Это не готовое правило для любого сервера, а именно шаблон логики. В плагине редиректов вы обычно задаёте исходный и целевой URL через интерфейс, а не пишете регулярку в таком виде. Но сам принцип тот же: старый формат уходит на новый.
Вариант для .htaccess: когда нужен быстрый ответ сервера
Если сайт работает на Apache и у вас есть доступ к .htaccess, редиректы лучше отдавать на уровне сервера. Так WordPress не тратит ресурсы на обработку заведомо старого адреса.
Ниже пример для переноса записей без даты, когда старый URL содержал год и месяц:
RewriteEngine On
RewriteRule ^([0-9]{4})/([0-9]{2})/([^/]+)/?$ /$3/ [R=301,L]
Если вы переносите сайт с одного домена на другой, правило будет другим — там лучше делать отдельный блок редиректа домена, а не смешивать его с переписыванием структуры. Иначе потом трудно понять, где именно сломалась цепочка.
Код в WordPress: если нужен контроль внутри проекта
Когда редиректов немного и вы хотите хранить их в репозитории, можно добавить их через template_redirect. Но делать это нужно аккуратно: проверять только нужные запросы и не запускать лишнюю логику на каждом хите.
<?php
add_action( 'template_redirect', function () {
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
if ( preg_match( '#^/\d{4}/\d{2}/([^/]+)/?$#', $request_uri, $matches ) ) {
$new_url = home_url( '/' . $matches[1] . '/' );
wp_redirect( $new_url, 301 );
exit;
}
} );
Такой код лучше размещать не в активной теме, а в небольшом must-use плагине или в собственном функциональном плагине. Тогда редиректы не исчезнут при смене темы.
Когда код лучше не использовать
- если редиректов очень много;
- если правила часто меняются редактором без доступа к коду;
- если сервер уже перегружен и лучше отдать задачу на уровень Apache/Nginx;
- если есть риск создать петлю из-за сложной логики условий.
Проверка результата после внедрения
Редирект считается рабочим не тогда, когда «вроде открывается», а когда он отдаёт правильный код ответа и ведёт на нужный канонический адрес без промежуточных прыжков.
Что проверить вручную
- старый URL отдаёт
301, а не302; - новый URL открывается с
200 OK; - нет цепочки
301 → 301 → 200; - не возникает редирект-петля;
- внутренние ссылки уже ведут на новый адрес.
Проверить заголовки можно через curl:
curl -I https://example.com/2024/05/old-post/
В ответе вы должны увидеть строку вроде HTTP/2 301 и заголовок Location с новым адресом. Затем отдельно проверьте целевой URL:
curl -I https://example.com/old-post/
Если там уже 200, значит цепочка закрыта правильно.
Частые ошибки и как их исправить
На практике проблемы обычно повторяются. Ниже — не теория, а то, что реально ломает редиректы после смены структуры URL.
Редирект на главную вместо релевантной страницы
Так делают, когда «не хочется разбираться». Для пользователя это плохой опыт, а для поисковика — слабый сигнал. Если старой страницы больше нет, ищите ближайший аналог по теме, а не отправляйте всё на главную.
Цепочка из нескольких 301
Например, старый адрес сначала уходит на промежуточный URL, а потом ещё раз перенаправляется на финальный. Это лишняя задержка и лишняя нагрузка. Решение простое: редирект должен вести сразу в конечную точку.
Смешали 301 и 302
Если страница переехала навсегда, нужен 301. 302 оставляет двусмысленность: поисковик может дольше держать старый URL в индексе.
Редирект по слишком широкому шаблону
Одна неаккуратная регулярка может зацепить и старые записи, и новые страницы, и служебные URL. Перед выкладкой проверяйте правило на нескольких реальных адресах.
Правило добавили в тему
При смене темы редиректы пропадают. Для технической логики это плохое место. Используйте плагин, mu-plugin или серверную конфигурацию.
Безопасность и производительность
Редиректы сами по себе не опасны, но плохая реализация может создать лишнюю нагрузку. Особенно если вы проверяете каждую страницу через сложные регулярки или обращаетесь к базе данных без необходимости.
- не делайте редирект через PHP на каждом запросе, если можно решить на уровне сервера;
- не храните десятки однотипных правил в активной теме;
- проверяйте, что редирект не срабатывает на
/wp-admin/,/wp-json/и служебных путях; - после массовых изменений очистите кэш страниц и объектный кэш, если он используется.
Если на сайте стоит плагин для технической чистки и SEO-настроек, например Clearfy Pro, часть задач по дублирующимся URL и служебным настройкам можно держать в одном месте. Но редиректы всё равно лучше выносить отдельно и не смешивать с общей оптимизацией.
Чек-лист перед публикацией изменений
- Список старых URL собран из логов и Search Console.
- Для каждого важного адреса есть понятное новое назначение.
- Редиректы отдают
301, а не302. - Нет цепочек и петель.
- Внутренние ссылки обновлены.
- Кэш очищен.
- Проверены несколько URL вручную через
curl -Iили браузерные инструменты.
Если после внедрения в Search Console старые 404 продолжают расти, это обычно означает одно из трёх: правило не покрывает все варианты URL, где-то осталась внутренняя ссылка на старый адрес или редирект ведёт не туда, куда вы ожидали. В таком случае проще вернуться к логам и добить список точечно, чем расширять правило вслепую.