Смена структуры URL в WordPress почти всегда оставляет хвост из старых адресов: записи открываются по прежним ссылкам, в поиске висят дубли, а часть трафика уходит в 404. Если просто поменять /%postname%/ на другой шаблон и ничего не сделать дальше, поисковики какое-то время будут видеть одновременно старые и новые URL. Это не критично только на очень маленьких сайтах без истории. В остальных случаях нужен понятный план: какие адреса редиректить, какие оставить каноническими, а какие закрыть от индексации.
Когда проблема уже есть
Обычно сигналов несколько. В Google Search Console растёт число страниц с пометкой Страница с перенаправлением или Не найдено (404). В логах сервера видны запросы к старым адресам из выдачи, из соцсетей и из внутренних ссылок. На сайте появляются дубли: одна и та же запись доступна по новому адресу, а старый URL ещё отдаёт контент или редиректит не туда.
Проверка простая: откройте старый адрес в браузере и посмотрите код ответа. Если он отдаёт 200 OK, а не редирект, это уже проблема. Если редирект есть, но ведёт на главную или на нерелевантную страницу, поисковик тоже может считать поведение ошибочным.
Что именно нужно определить до правки
Перед настройкой редиректов ответьте на три вопроса:
- Старый URL соответствует той же записи или это уже удалённый контент?
- Новая структура даёт однозначный адрес для каждой записи?
- Есть ли внешние ссылки и закладки на старые адреса, которые нельзя потерять?
Если запись жива и просто переехала, нужен 301 редирект. Если контент удалён навсегда и замены нет, иногда правильнее отдавать 410 Gone, но это уже отдельное решение и его стоит применять осознанно, а не массово.
Диагностика: где ломается переход на новые URL
Сначала проверьте, как WordPress формирует ссылки внутри сайта. Зайдите в админку в Настройки → Постоянные ссылки и убедитесь, что новая структура сохранена. После этого откройте несколько записей и сравните:
- URL в адресной строке;
- ссылку в HTML-коде карточек и меню;
- адрес в XML-карте сайта;
- канонический URL в исходном коде страницы.
Если карта сайта и каноникал уже указывают на новый адрес, а старые URL всё ещё доступны, значит проблема не в генерации ссылок, а в отсутствии перенаправления или в правилах сервера.
Для быстрой проверки кода ответа удобно использовать curl:
curl -I https://example.com/old-post-url/
Ищите в ответе 301 или 308 и заголовок Location. Если видите 200, старый адрес не закрыт. Если 302, редирект временный, и для миграции структуры URL это обычно не лучший вариант.
Пошаговое решение: редирект, каноникал и чистка внутренних ссылок
Самый надёжный сценарий — не пытаться лечить всё одним инструментом. Сначала настраивается постоянный редирект со старого шаблона URL на новый, затем проверяются канонические ссылки, после чего обновляются внутренние ссылки в контенте и меню.
1. Настройте 301-редирект для старых адресов
Если структура менялась предсказуемо, редирект можно сделать на уровне сервера. Для Apache это обычно .htaccess, для Nginx — конфигурация сайта. Но если шаблон старых URL сложный или менялся несколько раз, проще и безопаснее сделать редирект через WordPress-код, чтобы не ломать серверную конфигурацию.
Пример для functions.php или небольшого mu-plugin: если старый формат был /YYYY/MM/slug/, а новый — просто /slug/, можно попытаться найти запись по старому пути и отправить на её текущий permalink.
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax() || wp_is_json_request()) {
return;
}
$request_uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
if (!preg_match('#^\d{4}/\d{2}/[^/]+/?$#', $request_uri)) {
return;
}
$slug = basename($request_uri);
$post = get_page_by_path($slug, OBJECT, 'post');
if ($post instanceof WP_Post) {
wp_redirect(get_permalink($post), 301);
exit;
}
});
Это не универсальный редирект для любой миграции, но для типового случая с переносом из датированного URL в короткий slug он рабочий. Если у вас другая старая структура, логику нужно адаптировать под конкретный шаблон.
2. Проверьте канонический URL
WordPress сам выводит canonical через rel_canonical() на одиночных записях и страницах. Если тема или SEO-плагин подменяет его, можно получить конфликт: редирект ведёт на новый адрес, а canonical остаётся старым. В таком случае поисковик видит два сигнала и может дольше переобходить страницы.
Откройте исходный код страницы и найдите строку вида <link rel="canonical" href="..." />. Она должна совпадать с конечным URL после редиректа. Если нет — проверьте настройки SEO-плагина и шаблоны темы.
3. Обновите внутренние ссылки
Редирект спасает внешний трафик, но внутри сайта старые ссылки лучше заменить. Иначе каждая внутренняя ссылка будет сначала вести на старый адрес, а потом перенаправляться, что создаёт лишний запрос и замедляет навигацию.
Если на сайте много старых ссылок, можно сделать поиск и замену по базе через WP-CLI. Это безопаснее, чем вручную править десятки записей, но перед запуском нужен бэкап.
wp search-replace 'https://example.com/2023/05/' 'https://example.com/' --skip-columns=guid
Команда выше подходит только если вы точно понимаете, что меняете. Не трогайте guid: в WordPress его не используют как обычный URL для вывода на фронтенде, и массовая замена там может создать лишние проблемы.
Какой способ выбрать: плагин, код или сервер
Если задача разовая и структура URL менялась один раз, серверный редирект или код в mu-plugin обычно надёжнее. Если миграций было несколько и нужно быстро закрыть много старых адресов, удобнее использовать плагин для редиректов. Но у каждого подхода есть компромиссы.
| Подход | Плюсы | Минусы |
|---|---|---|
| Серверный редирект | Быстро, без нагрузки на PHP | Сложнее поддерживать при нестандартных шаблонах |
| Код в WordPress | Гибко, можно учитывать логику записей | Добавляет нагрузку на фронтенд, нужен аккуратный код |
| Плагин редиректов | Удобно управлять из админки | Дополнительный слой, возможны конфликты с кэшем |
Если на сайте уже используется набор для технической чистки и SEO-оптимизации, вроде Clearfy Pro, имеет смысл проверить, не дублирует ли он часть функций вашего SEO-плагина. Два инструмента, которые одновременно управляют canonical, noindex и редиректами, часто мешают друг другу.
Проверка результата после внедрения
После настройки не ограничивайтесь открытием одной страницы в браузере. Нужна проверка по трём точкам: код ответа, конечный адрес и индексация.
- Старый URL должен отдавать
301и вести на нужную запись. - Новый URL должен отдавать
200без цепочки лишних редиректов. - Canonical на новой странице должен совпадать с конечным адресом.
- XML-карта сайта должна содержать только актуальные URL.
- Внутренние ссылки в меню, блоках и контенте должны указывать сразу на новый адрес.
Для быстрой ручной проверки удобно смотреть заголовки ответа:
curl -I https://example.com/old-post-url/
curl -I https://example.com/new-post-url/
Если редиректов несколько подряд, это видно по повторным переходам или через инструменты разработчика. Цепочки лучше убрать: старый URL должен вести сразу на финальный, без промежуточных шагов.
Частые ошибки и как их исправить
Редирект ведёт на главную
Так бывает, когда старый URL не удаётся сопоставить с конкретной записью. Поисковик воспринимает это как мягкую потерю страницы, а не как корректную замену. Решение простое: редирект должен вести на наиболее близкий аналог, а если аналога нет — лучше удалить URL из карты сайта и дать ему 404 или 410, а не отправлять всех на главную.
Старый адрес всё ещё отдаёт 200
Причина обычно в том, что правило редиректа не срабатывает из-за кеша, неправильного шаблона или конфликта с плагином. Проверьте, не отдаёт ли CDN или page cache старую версию страницы. Иногда достаточно очистить кеш на уровне плагина, сервера и CDN одновременно.
Появились циклы редиректов
Это происходит, когда WordPress, плагин и сервер одновременно пытаются «помочь» и отправляют URL в разные стороны. Особенно часто цикл возникает после ручной правки .htaccess и одновременного использования плагина редиректов. Оставьте один источник истины: либо сервер, либо WordPress-логика, либо плагин.
Внутренние ссылки остались старыми
Редирект не исправляет контент. Если в статьях, виджетах и меню остались старые ссылки, сайт будет постоянно делать лишние запросы. После миграции обязательно прогоните поиск по базе и проверьте шаблоны темы.
Безопасность и производительность
Редиректы — это не только SEO, но и нагрузка. Чем больше логики вы вешаете на template_redirect, тем важнее не делать там тяжёлых запросов. Не запускайте сложный перебор записей на каждом хите. Если структура URL известна заранее, лучше использовать серверные правила или заранее подготовленную таблицу соответствий.
Перед массовой заменой ссылок сделайте резервную копию базы. Если используете WP-CLI, сначала прогоните команду в тестовом режиме с --dry-run, чтобы увидеть объём изменений:
wp search-replace 'https://example.com/2023/05/' 'https://example.com/' --skip-columns=guid --dry-run
Если на сайте есть тяжёлые блоки, видео или динамические вставки, после миграции проверьте, не увеличилось ли время ответа из-за дополнительных редиректов. В таких случаях полезно отдельно смотреть TTFB и количество запросов к старым адресам в логах.
Что считать успешным результатом
Решение можно считать рабочим, если старые URL больше не индексируются как отдельные страницы, новые адреса стабильно открываются без цепочек переходов, а внутренние ссылки сразу ведут на финальные страницы. На практике это видно по уменьшению 404 в логах, по чистой карте сайта и по тому, что в Search Console старые адреса постепенно уходят в статус перенаправленных или исключённых из индекса.
Если после всех правок часть старых URL всё ещё всплывает в выдаче, не спешите менять логику ещё раз. Сначала проверьте кеш, каноникал и карту сайта — именно там чаще всего остаются следы старой структуры.