Смена структуры URL в WordPress почти всегда оставляет хвост из старых адресов: записи открываются по прежним ссылкам, в индексе остаются дубли, а в логах растут 404. Если просто поменять постоянные ссылки и ничего не сделать дальше, поисковик какое-то время будет видеть обе версии страниц. Для небольшого сайта это обычно заканчивается потерей части веса ссылок и лишней нагрузкой на обход.
Ниже — рабочая схема, которая закрывает старые URL без лишней магии: сначала находим, какие адреса реально живут, потом ставим редиректы, проверяем canonical и только после этого чистим индекс.
Когда проблема уже есть: как её диагностировать
Типичный сценарий выглядит так: вы поменяли структуру записей, например с /2024/05/%postname%/ на /%postname%/, а в Search Console или в логах сервера видите старые адреса. Иногда старые URL продолжают открываться с кодом 200, если на сайте остались архивы, кастомные правила или кэш отдает не тот ответ.
Что проверить в первую очередь
- открывается ли старый URL с кодом
301или всё ещё отдает200; - ведет ли новый URL на ту же запись без цепочки редиректов;
- не создаются ли дубли через категории, теги, архивы автора и пагинацию;
- какой
canonicalвыводится в HTML; - нет ли в sitemap старых адресов.
Проверять лучше не глазами, а инструментами. Для одного URL достаточно команды:
curl -I https://example.com/staryy-url/В ответе нужен 301 Moved Permanently и заголовок Location с новым адресом. Если вместо этого приходит 200 OK, значит редирект не настроен или его перебивает другой слой: плагин, тема, серверный конфиг, кэш.
Пошаговое решение: редирект старых URL на новые
Самый надежный вариант — сделать редирект на уровне сервера или через WordPress, если у вас нет доступа к конфигам. Для массовой смены структуры лучше не писать редирект на каждую запись вручную, а использовать правило, которое понимает старый шаблон URL.
Вариант 1: редирект через WordPress
Если структура менялась предсказуемо, можно добавить правило в functions.php дочерней темы или в свой мини-плагин. Ниже пример для случая, когда из URL убрали дату:
add_action('template_redirect', function () {
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
// Пример: старый формат /2024/05/post-name/ -> новый /post-name/
if (preg_match('#^/\d{4}/\d{2}/([^/]+)/?$#', $request_uri, $m)) {
$slug = $m[1];
$new_url = home_url('/' . $slug . '/');
wp_redirect($new_url, 301);
exit;
}
});Это не универсальный код для любого сайта, а рабочий шаблон под конкретный сценарий. Если у вас другая старая структура, регулярное выражение нужно адаптировать под неё. Смысл один: старый адрес должен стабильно вести на новый, без промежуточных прыжков.
Вариант 2: редирект на уровне сервера
Если сайт на Apache и доступен .htaccess, редирект лучше делать там. Это быстрее и не зависит от загрузки WordPress. Пример для старой структуры с датой:
RewriteEngine On
RewriteRule ^[0-9]{4}/[0-9]{2}/([^/]+)/?$ /$1/ [R=301,L]На Nginx логика будет другой, но принцип тот же: старый шаблон URL должен отдаваться как 301. Если вы не уверены в правилах, лучше протестировать на одном шаблоне и только потом раскатывать на весь сайт.
Что делать с canonical, sitemap и внутренними ссылками
Редирект сам по себе не решает всё. Если в HTML остаются старые canonical или в sitemap продолжают попадать старые адреса, поисковик будет дольше переобходить мусор. Поэтому после редиректов нужно проверить три вещи.
Canonical должен указывать на новый URL
На каждой записи в исходном коде страницы должен быть один канонический адрес — новый, а не старый. Если у вас стоит SEO-плагин, проверьте, не переопределяет ли он canonical вручную. В кастомной теме иногда встречается собственный вывод canonical, который конфликтует с плагином.
Sitemap должен содержать только актуальные адреса
После смены структуры пересоберите sitemap и убедитесь, что в нем нет старых ссылок. Если sitemap генерируется плагином, очистите кэш плагина и кэш страниц. Если sitemap собирается вручную, проверьте шаблон генерации: он может брать permalink из старого мета-слоя или из закэшированного массива.
Внутренние ссылки стоит обновить отдельно
Редирект спасает внешние и старые закладки, но внутренние ссылки лучше переписать. Иначе каждая кликабельная ссылка внутри сайта будет вести через лишний 301. На больших сайтах это заметно по логам и по времени ответа.
Если нужно быстро найти старые адреса в контенте, удобно сделать выборку по базе. Перед любыми изменениями — бэкап.
SELECT ID, post_title
FROM wp_posts
WHERE post_content LIKE '%/2024/05/%';После этого можно точечно заменить ссылки через поиск и замену в базе или через WP-CLI, если он у вас настроен. Главное — не трогать сериализованные данные без подходящего инструмента.
Сравнение подходов: плагин, код, сервер
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Плагин редиректов | Нужно быстро закрыть несколько старых шаблонов URL | Просто настраивать, не нужен доступ к серверу | Дополнительная нагрузка, риск конфликтов с кэшем |
| Код в WordPress | Нужна логика под конкретную структуру | Гибко, можно учесть условия сайта | Зависит от загрузки WordPress |
| Редирект на сервере | Массовая смена структуры, важна скорость | Быстрее, не зависит от темы и плагинов | Нужен доступ к конфигу и аккуратное тестирование |
Если на сайте уже стоит набор для технической чистки, например Clearfy Pro, его имеет смысл использовать для сопутствующих задач: убрать лишние архивы, закрыть дубли и проверить служебные страницы. Но сам редирект лучше держать в одном месте, а не размазывать по нескольким плагинам.
Проверка результата после внедрения
После настройки не ограничивайтесь открытием одной страницы в браузере. Нужна короткая, но повторяемая проверка.
- Откройте 3–5 старых URL и убедитесь, что все отдают
301. - Проверьте, что новый URL открывается сразу, без цепочки
301 → 301 → 200. - Посмотрите исходный код страницы и найдите актуальный
canonical. - Проверьте sitemap: старых адресов там быть не должно.
- Через несколько дней посмотрите логи 404: их количество должно снизиться по старым шаблонам URL.
Для быстрой проверки цепочки редиректов удобно использовать:
curl -I -L https://example.com/staryy-url/Если -L показывает несколько переходов, значит где-то есть лишний редирект: на уровне плагина, темы или сервера. Это стоит убрать, иначе поисковик будет тратить лишние обходы.
Частые ошибки и как их исправить
Старый URL отдает 200 вместо 301
Обычно это значит, что правило редиректа не сработало или его перекрыл кэш. Проверьте порядок правил, очистите кэш страницы и серверный кэш, если он есть. Если редирект сделан в WordPress, убедитесь, что код подключается до вывода шаблона.
Редирект ведет на главную
Так часто бывает, когда правило не находит соответствующую запись по slug. Не отправляйте все неизвестные старые URL на главную — это плохая замена. Лучше либо сопоставить шаблон корректно, либо вернуть 404, если адрес не соответствует реальной записи.
Появилась цепочка из нескольких 301
Например, старый URL сначала редиректится на версию без даты, а потом еще раз на URL со слешем. Это лишний шаг. Сведите все правила к одному финальному адресу и проверьте, нет ли конфликтующих настроек в SEO-плагине и в .htaccess.
В sitemap остались старые адреса
Значит, генератор sitemap берет данные из кэша или из старого источника. Очистите кэш, пересохраните настройки постоянных ссылок и пересоберите sitemap. Если проблема повторяется, проверьте, не хранится ли старый URL в метаполях или в кастомных таблицах.
Что учесть для безопасности и производительности
Не ставьте несколько плагинов редиректов одновременно: они часто конфликтуют и усложняют диагностику. Для массовых изменений сначала делайте бэкап базы и файлов. Если редирект завязан на PHP-логику, следите, чтобы код не выполнялся на каждом запросе без необходимости — чем проще правило, тем лучше.
Если сайт большой, лучше перенести массовые редиректы на серверный уровень и оставить WordPress только для точечных случаев. Это снижает нагрузку и уменьшает шанс, что редирект сломается после обновления темы или плагина.
И еще один практический момент: после смены структуры не удаляйте старые URL сразу из всех источников. Сначала убедитесь, что редиректы работают, поисковик видит новый canonical, а в логах нет всплеска 404. Только потом можно считать миграцию закрытой.