Все записи выдают 404 после смены структуры ссылок: как чинить, не потеряв трафик

Все записи выдают 404 после смены структуры ссылок: как чинить, не потеряв трафик
Анатолий Кузнецов
Анатолий Кузнецов
SEO-оптимизатор с 20-летним стажем. Автор блога seo-prodvizhenie-biznesa.ru о продвижении и доработке сайтов.

Все записи выдают 404 после смены структуры ссылок, а главная и обычные страницы открываются как ни в чём не бывало — картина настолько типовая, что диагноз ставится ещё до похода в логи. Хостинг тут почти всегда ни при чём, база данных цела, записи никуда не делись: они лежат в wp_posts со статусом publish и ждут, пока сервер снова научится превращать красивый адрес в запрос к index.php. Плохо другое — пока сайт отдаёт 404, робот честно записывает каждый такой адрес в исключённые, и вернуть позиции потом дороже, чем починить правила за десять минут.

Почему главная жива, а записи умерли, и как отличить два типа 404

Запрос к корню сайта не требует никаких преобразований. Сервер получает /, смотрит на директиву DirectoryIndex (или index в nginx), находит физический файл index.php и передаёт его PHP. WordPress запускается, видит пустой путь и отдаёт главную. Ровно та же логика работает для /wp-admin/ и /wp-login.php — это существующие на диске каталоги и файлы. Поэтому админка обычно продолжает работать даже на полностью сломанных правилах, и это первый признак, что беда именно в перезаписи URL.

Адрес записи вроде /kak-nastroit-formu/ физически не существует. На диске нет ни такого файла, ни такого каталога. Чтобы страница открылась, сервер обязан подменить путь: «файла нет, каталога нет — отдай запрос в index.php, а параметры передай через строку запроса». Эту подмену на Apache делает блок mod_rewrite в .htaccess, на nginx — директива try_files. Внутри WordPress подмену разбирает класс WP_Rewrite: он сверяет путь с массивом правил, который лежит в опции rewrite_rules таблицы wp_options, и вычисляет, какую запись показать. Сломайте любое из двух звеньев — серверное или внутреннее — и все записи разом превратятся в 404, тогда как главная останется на месте.

Отсюда следует важный вывод: 404 после смены пермалинков бывают двух совершенно разных сортов, и лечатся они по-разному. Прежде чем что-то править, потратьте минуту и определите, какой именно вы поймали.

Откройте любой адрес записи в браузере и посмотрите, что вы видите. Если это ваша тема со своей шапкой, меню и надписью «Страница не найдена» — работает и сервер, и PHP: WordPress запустился, разобрал адрес и не нашёл подходящей записи. Значит, серверные правила в порядке, а сломан внутренний массив правил или сам адрес больше не соответствует новой структуре. Если же вы видите голую страницу сервера — «Not Found. The requested URL was not found on this server.» с подписью Apache или лаконичное «404 Not Found» с подписью nginx — PHP до дела вообще не дошёл, и виноваты серверные правила.

Проверить точнее помогает консоль. Команда curl -I https://site.ru/адрес-записи/ покажет заголовки ответа. Обратите внимание на X-Powered-By, Link и куки WordPress: если их нет ни одного, запрос до движка не доехал. Дополнительно посмотрите в лог ошибок сервера — при сломанном .htaccess Apache пишет туда явные строки вида «Invalid command ‘RewriteEngine’», когда mod_rewrite не подключён.

Что видно на экране Где сломалось Что проверять первым
Страница 404 в дизайне вашей темы Внутри WordPress Опция rewrite_rules, слаги записей, конфликт с плагинами и типами записей
Белая страница «Not Found» с подписью Apache Сервер, mod_rewrite Наличие .htaccess, директива AllowOverride All, подключён ли модуль
Тёмная страница «404 Not Found» nginx Сервер, конфиг сайта Блок location / и директива try_files
500 Internal Server Error вместо 404 Синтаксис .htaccess Лог ошибок, лишние или дублирующиеся директивы в файле
404 только у части записей, остальные живы Данные, а не правила Пустые или дублирующиеся post_name, кириллица в слагах, кэш
Записи открываются, но 404 у пагинации и категорий Внутренние правила Пересохранение пермалинков, конфликт слага категории со слагом страницы

Первая помощь: пересохранить правила и проверить конфиг сервера

В девяти случаях из десяти лечение начинается и заканчивается здесь. Зайдите в «Настройки — Постоянные ссылки» и нажмите «Сохранить изменения», ничего не меняя в форме. Кнопка запускает функцию flush_rewrite_rules(), которая пересобирает массив правил заново, кладёт его в опцию rewrite_rules и — если файл доступен на запись — переписывает блок между маркерами # BEGIN WordPress и # END WordPress в .htaccess.

Почему массив вообще протухает: он кэшируется в базе и обновляется только по явному вызову. Плагин, зарегистрировавший свой тип записи или таксономию, обязан вызвать сброс при активации, но делают это далеко не все. После обновления такого плагина, смены темы или ручной правки структуры в базе массив остаётся старым, и WordPress продолжает искать записи по правилам, которых уже нет.

Если у вас есть доступ к консоли, то же самое делается быстрее и надёжнее через WP-CLI: wp rewrite flush --hard. Ключ --hard заставляет переписать и .htaccess, а не только опцию в базе. Посмотреть, какие правила сейчас действуют, можно командой wp rewrite list --format=table, а сменить структуру без захода в админку — wp rewrite structure '/%postname%/' --hard.

Отдельно проверьте, что админка вообще видит файл. Если внизу страницы настроек WordPress показывает готовый блок кода с просьбой вставить его вручную — значит, .htaccess недоступен на запись, и всё, что вы нажимаете, меняет только базу. В этом случае правила придётся положить в файл руками через FTP или файловый менеджер хостинга.

Канонический блок для Apache выглядит так и должен лежать в корне сайта, в файле .htaccess:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Три вещи ломают его чаще всего. Первое — сайт лежит не в корне, а в подкаталоге: тогда RewriteBase и путь в последнем правиле должны содержать этот подкаталог, например /blog/ и /blog/index.php. Второе — на хостинге выключена директива AllowOverride All для каталога сайта, и Apache просто игнорирует файл целиком; проверяется это только у поддержки хостинга, никакими правками файла не лечится. Третье — не подключён модуль mod_rewrite; из-за обёртки <IfModule> ошибки в логе не будет, правила молча не сработают.

На nginx .htaccess не читается вообще, сколько его ни правь. Нужный кусок конфига сайта выглядит так: location / { try_files $uri $uri/ /index.php?$args; }. Директива по очереди проверяет, есть ли файл, есть ли каталог, и только потом отдаёт запрос в PHP вместе со строкой запроса. Ошибка, из-за которой записи падают в 404, почти всегда одна: в конфиге стоит try_files $uri $uri/ =404; — вариант из типового шаблона для статики. Если сайт живёт в связке nginx впереди и Apache позади, правила из .htaccess продолжают работать, но только для тех запросов, которые nginx реально проксирует, — статику он часто отдаёт сам, мимо Apache, и это отдельный источник странностей.

Особый случай — панели управления. ISPmanager, FastPanel и подобные периодически перезаписывают конфиги nginx из шаблона, стирая ручные правки. Если через неделю после починки записи снова легли в 404, ищите не заговор, а плановую перегенерацию конфига. Вносить изменения нужно через интерфейс панели или в специально отведённый файл, который панель не трогает.

Когда нужны 301 со старых адресов

Пересохранение правил чинит сайт для посетителя, но не решает вторую половину задачи. Если структура действительно изменилась — например, вы ушли с /2019/07/kak-nastroit-formu/ на /kak-nastroit-formu/, — все старые адреса в индексе, во внешних ссылках, в закладках и в мессенджерах ведут в пустоту. Часть из них WordPress вытянет сам, часть — нет, и разница здесь принципиальная.

В ядре есть функция redirect_guess_404_permalink() из файла wp-includes/canonical.php. Когда движок не смог разобрать адрес, он берёт последний сегмент пути и пробует найти опубликованную запись с таким post_name. Нашёл ровно одну — отдаёт 301 на её новый адрес. Именно поэтому после смены структуры часть старых ссылок волшебным образом сама начинает редиректить. Но угадывание отваливается, когда слаг в конце адреса не уникален, когда последний сегмент — это page/2 или номер записи, когда старая структура была вида /archives/512/, когда на 404 стоит полностраничный кэш и до PHP запрос не доходит, или когда плагин отключил хук template_redirect.

Полагаться на угадывание нельзя ещё по одной причине: оно работает только пока запись жива и слаг не изменился, и оно ничего не делает с адресами категорий, меток и архивов. Правильный порядок такой: сначала поднять сайт пересохранением правил, затем выгрузить реальный список старых адресов и закрыть его серверными 301, а угадывание оставить страховкой для хвоста.

Как собрать пачку 301 за один вечер

Список старых адресов берётся из четырёх источников, и лучше свести все четыре. Первый — Яндекс.Вебмастер, раздел «Индексирование — Страницы в поиске», выгрузка в архив: там лежат ровно те адреса, которые поисковик считает вашими. Второй — старый файл sitemap.xml, если сохранилась копия или он остался в кэше сервисов. Третий — логи доступа сервера за последний месяц: grep ' 404 ' access.log | awk '{print $7}' | sort | uniq -c | sort -rn покажет, какие несуществующие адреса реально запрашивают и роботы, и живые люди. Четвёртый — Google Search Console, отчёт «Индексирование страниц», раздел с ошибками 404.

Дальше начинается главное упрощение, которое экономит вечер. Когда структура менялась целиком, отдельное правило на каждый адрес не нужно — хватает одного регулярного выражения на весь класс адресов. Переход с даты в URL на чистый слаг закрывается одной строкой в .htaccess, размещённой выше блока # BEGIN WordPress:

RewriteEngine On
RewriteRule ^(19|20)\d{2}/\d{2}/([^/]+)/?$ /$2/ [R=301,L]

Расположение критично: всё, что окажется между маркерами BEGIN и END, WordPress сотрёт при следующем сохранении настроек пермалинков. На nginx та же логика записывается как rewrite "^/(19|20)\d{2}/\d{2}/([^/]+)/?$" /$2/ permanent; внутри блока server, до location /.

Индивидуальные правила остаются только там, где старый адрес не содержит нового слага: структура /archives/%post_id%/, ручные переименования, склеенные записи. Такую карту удобно собирать из базы. Команда wp post list --post_type=post --post_status=publish --fields=ID,post_name,url --format=csv > posts.csv даёт готовую таблицу, из которой скриптом на десять строк генерируется список пар «старый адрес — новый адрес». Загонять эти пары лучше в серверный конфиг, а не в плагин: плагин обрабатывает редирект уже после запуска PHP и полной загрузки WordPress, то есть тратит ресурсы на каждый запрос робота, а серверное правило отрабатывает мгновенно.

Готовые правила обязательно проверяются пачкой, а не выборочно. Скрипт из одной строки — while read u; do curl -s -o /dev/null -w "%{http_code} %{redirect_url} $u\n" "$u"; done < old_urls.txt — покажет и код ответа, и цель редиректа для каждого адреса. Смотрите на две вещи: код должен быть 301, а не 302, и цепочка должна быть в один шаг. Схема «старый адрес → 301 → адрес без слеша → 301 → финальный адрес» технически работает, но заставляет робота делать лишние запросы и медленнее передаёт вес. Про разницу между временным и постоянным редиректом и про то, чем оборачивается путаница, я подробно писал в материале Отличие 301 от 302 редиректа, а типовые ошибки с битыми ссылками разобраны в статье 404, 301, 302: как битые ссылки и неправильные редиректы крадут вес страниц.

Отдельно предупрежу про соблазн отправить все старые адреса на главную. Это худший вариант из возможных: поисковик распознаёт массовый редирект нерелевантных адресов на один документ и переводит их в разряд soft 404, то есть вес не передаётся вообще, а главная получает шлейф нерелевантных сигналов. Механика описана в разборе Редирект на главную вместо 404 плодит soft 404 по всему сайту. Если нового адреса у записи нет — отдавайте честный 410 или оставляйте 404, это чище.

Обновление карты сайта, внутренних ссылок и канониклов

После смены структуры карта сайта пересобирается из базы автоматически: и штатный /wp-sitemap.xml, который появился в ядре начиная с версии 5.5, и файлы SEO-плагинов берут адреса через get_permalink(). Проблема возникает, когда карта закэширована — плагином статического кэша, серверным кэшем или CDN. Откройте карту в браузере и сверьте пару случайных адресов с реальными; если видите старые — сбросьте кэш и перегенерируйте файл в настройках плагина. После этого зайдите в Вебмастер, в раздел «Индексирование — Файлы Sitemap», и убедитесь, что дата последней загрузки обновилась. Что должно быть внутри правильной карты и как её проверять, я разбирал в статье Карта сайта Sitemap.

Внутренние ссылки — самая недооценённая часть работы. Всё, что вы за годы проставили в текстах статей абсолютными адресами, продолжает вести на старые URL. Формально это не ошибка: сработает ваш же 301. Фактически вы отправляете робота гулять по редиректам вместо прямых переходов, теряя часть краулингового бюджета и небольшую долю веса на каждом переходе. Массово чинится это через WP-CLI: wp search-replace 'https://site.ru/2019/07/' 'https://site.ru/' wp_posts --dry-run --report-changed-only. Обязательно сначала с ключом --dry-run и обязательно после бэкапа базы — и учтите, что для дат нужен свой проход на каждый год и месяц, поэтому проще написать короткий скрипт с регулярным выражением.

Не забудьте три места, о которых вспоминают в последнюю очередь. Меню: пункты типа «Произвольная ссылка» хранят адрес в постмете и сами не обновляются. Виджеты и блоки в подвале, где адреса часто вбиты руками в HTML. Настроенные цели в Метрике и Google Analytics — если цель была «просмотр URL, содержащего /2019/», после переезда она перестанет срабатывать, и вы будете думать, что упали заявки.

Канонический адрес проверяется вручную на трёх типах страниц: запись, категория, пагинация. Откройте исходный код и найдите <link rel="canonical". Он должен указывать на новый адрес и совпадать с тем, что отдаёт сайт после всех редиректов. Расхождение между каноническим адресом и реальным — классический источник дублей, о котором подробно в материале Полный гайд по канониклам, редиректам и дублям.

Отправка на переобход и что происходит дальше

Когда сайт починен, а редиректы проверены, задача сводится к тому, чтобы поисковик узнал о новых адресах быстрее, чем успеет выкинуть старые из индекса. Порядок действий такой.

Сначала — карта сайта. В Яндекс.Вебмастере, раздел «Индексирование — Файлы Sitemap», добавьте или переотправьте файл. Робот обходит карту приоритетно, и это самый дешёвый способ показать сразу весь новый список. Затем — инструмент «Переобход страниц» в том же разделе. Лимит на переобход зависит от размера и качества сайта, обычно это несколько десятков адресов в сутки. Отправляйте в первую очередь новые адреса самых трафиковых записей, а не подряд по списку: приоритет решает, что вернётся в индекс в первую неделю, а что через месяц.

Параллельно подключите IndexNow, если он ещё не работает. Протокол пингует поисковик сразу при изменении и снимает большую часть ожидания; настройка занимает пятнадцать минут и описана в инструкции Как установить IndexNow на WordPress. Для Google остаётся инспекция URL в Search Console с ручным запросом индексирования и переотправка карты — квоты там жёстче, поэтому тоже начинайте с приоритетных страниц.

Важное предупреждение: инструмент «Переезд сайта» в Вебмастере для смены структуры ссылок не подходит. Он предназначен для смены домена, протокола или главного зеркала, и попытка применить его к перестановке URL внутри одного домена ничего не даст. Точно так же не стоит гнать старые адреса в инструмент удаления страниц из поиска: он скрывает адрес из выдачи, но не передаёт по нему вес, то есть вы своими руками обнуляете смысл редиректа.

Дальше нужно просто наблюдать. Реальный порядок событий выглядит так: в первые дни в Вебмастере растёт число исключённых страниц со статусом 404 или «редирект» — это нормально, робот встречает старые адреса и отрабатывает их. Через одну-три недели новые адреса начинают появляться в разделе «Страницы в поиске». Позиции в этот период обычно колеблются, и просадка на две-четыре недели после массовой смены URL — ожидаемая часть процесса, а не признак катастрофы. Полностью картина устаканивается за месяц-два в зависимости от того, как часто робот ходит на сайт. Как отслеживать процесс без гаданий, я описывал в заметке Как проверить индексацию сайта в Яндексе.

И последнее: 301-правила нельзя снимать. Минимальный срок — год, а по-хорошему они живут столько же, сколько сайт. Внешние ссылки на старые адреса не исчезают никогда, и удаление правил через месяц просто возвращает вас в исходную точку, только уже без трафика.

Когда структуру постоянных ссылок менять вообще не стоит

Смена URL — это операция с гарантированной ценой и негарантированной пользой. Цена — временная просадка, работа с редиректами и риск потерять хвост низкочастотного трафика. Польза измерима далеко не всегда. Ниже — рабочая таблица для решения.

Текущая структура Проблема Менять?
/%postname%/ Нет проблемы, это оптимальный вариант для блога Нет, никогда
/%year%/%monthnum%/%postname%/ Дата в адресе старит статью в глазах пользователя и мешает переиздавать материал Да, но только если статьи регулярно обновляются
/?p=123 (простые ссылки) Нет ключа в адресе, нечитаемо, плохо шарится Да, это тот случай, когда выгода очевидна
/archives/%post_id%/ Нет слага, любой редирект придётся строить по карте вручную Да, но заложите время на ручную карту
/%category%/%postname%/ Смена рубрики ломает адрес, при нескольких рубриках возможны дубли По ситуации: если рубрики стабильны, оставьте
Любая, но сайт моложе трёх месяцев Индекс ещё маленький, терять нечего Да, сейчас самый дешёвый момент
Любая, но на сайте нет доступа к серверным правилам Нечем закрыть старые адреса Нет, сначала получите доступ

Помимо таблицы есть четыре ситуации, в которых смену стоит отложить независимо от текущей структуры. Сезон: если у вас пик спроса в декабре, декабрь — не время. Совмещение с другими переездами: менять URL одновременно с переходом на HTTPS, сменой домена или редизайном нельзя, потому что при просадке вы не поймёте, что именно её вызвало, — почему это плохо кончается, показано в разборе HTTPS, который убивает SEO: 4 ошибки переезда. Внешние размещения: если старые адреса напечатаны на визитках, зашиты в QR-коды или проставлены в купленных статьях, вы обязаны держать редиректы вечно и учитывать это в решении. И четвёртое — отсутствие бэкапа: перед сменой структуры делается копия базы и файлов, потому что откат правил без копии превращается в реконструкцию по памяти.

Отдельно про мотив «так красивее». Длина и красота URL сами по себе позиции не двигают. Ключ в адресе даёт слабый эффект, вложенность рубрик — почти нулевой. Если единственный аргумент за смену — эстетика, аргумент недостаточный. А вот если структура порождает дубли, ломает адреса при перекладывании записей по рубрикам или мешает обновлять контент, менять надо — просто по описанному выше порядку, а не наскоком.

Чеклист починки: что сделать по порядку

Свожу всё в последовательность, по которой можно идти сверху вниз, не думая. Один пункт — одно действие, каждое проверяемо.

1. Определите тип 404: страница темы или голая страница сервера. От этого зависит вся дальнейшая ветка.

2. Сделайте бэкап базы и файла .htaccess до любых правок. Скопировать файл — пять секунд, восстановить конфиг по памяти — час.

3. Зайдите в «Настройки — Постоянные ссылки» и нажмите «Сохранить изменения» без изменений. Проверьте запись.

4. Если не помогло — откройте .htaccess и сверьте блок WordPress посимвольно, включая RewriteBase для подкаталога. На nginx проверьте try_files.

5. Отключите плагины по одному, начиная с кэша, SEO-плагина и всего, что регистрирует свои типы записей. После каждого отключения — сброс правил и проверка.

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

7. Соберите список старых адресов из Вебмастера, логов и старой карты сайта. Уберите дубли.

8. Напишите правила: одно регулярное выражение на весь класс адресов плюс индивидуальные строки на остаток. Разместите их выше блока # BEGIN WordPress.

9. Прогоните весь список через curl. Проверьте код 301 и длину цепочки.

10. Перегенерируйте карту сайта, обновите внутренние ссылки в текстах, меню и виджетах, проверьте канонические адреса.

11. Переотправьте карту в Вебмастере, отправьте приоритетные адреса на переобход, включите IndexNow.

12. Через неделю и через месяц вернитесь в Вебмастер и посмотрите динамику исключённых и проиндексированных страниц. Правила не снимайте.

Если сайт живёт на WordPress и вы хотите заранее исключить типовые грабли с индексацией, разбор частых причин собран в материале Почему Яндекс не индексирует новые статьи на WordPress. А если задача шире, чем разовая починка, и нужно системное восстановление позиций сайта в поиске после технической аварии — работать придётся не только с адресами, но и с индексом, перелинковкой и скоростью.

Частые вопросы

Главная работает, записи 404 — это точно пермалинки, а не взлом? Проверяется за минуту. Зайдите в админку: если она открывается и записи на месте в списке «Все записи», база цела. Откройте запись по адресу вида site.ru/?p=123 — если по нему страница показывается, а по красивому адресу нет, это стопроцентно правила перезаписи. При взломе картина другая: подменённый контент, лишние администраторы, изменённые файлы ядра.

Пересохранил настройки, не помогло. Что дальше? Проверьте, доступен ли .htaccess на запись — WordPress мог обновить только базу. Затем временно переименуйте папку plugins в plugins-off через FTP: это отключит все плагины разом. Если записи ожили, включайте по одному. Если нет — вопрос к серверу: AllowOverride, mod_rewrite или try_files.

Плагин редиректов или серверные правила? Для десятка адресов разницы нет. Для сотен и тысяч выбирайте сервер: правило отрабатывает до запуска PHP, не грузит базу и не зависит от того, жив ли плагин. Плагин удобен там, где нет доступа к конфигу, и там, где редиректы нужно вести редактору без консоли.

Сколько держать 301 со старых адресов? Постоянно. Год — абсолютный минимум, после которого поисковик обычно уже переклеил все сигналы, но внешние ссылки и закладки живут дольше. Правила почти ничего не стоят серверу, снимать их незачем.

Часть старых адресов сама редиректит, часть 404 — почему? Работает встроенное угадывание из redirect_guess_404_permalink(): движок ищет запись по последнему сегменту адреса. Оно срабатывает, когда слаг уникален и не изменился, и молчит на пагинации, на адресах с ID вместо слага и на страницах, закэшированных на уровне сервера.

Можно ли использовать инструмент «Переезд сайта» в Вебмастере? Нет. Он для смены домена, протокола и главного зеркала. Смена структуры внутри домена решается редиректами, картой сайта и переобходом.

Нужно ли удалять старые адреса из индекса вручную? Нет, и лучше этого не делать. Инструмент удаления скрывает адрес из выдачи, но не передаёт вес на новую страницу. Правильный путь — отдавать 301 и дать роботу переклеить сигналы самому.

Что делать, если старая структура была /?p=123? Это единственный случай, где почти ничего делать не надо: WordPress сам отдаёт 301 с адреса с параметром p на текущий постоянный адрес записи. Достаточно убедиться, что редирект отдаётся кодом 301 и что параметр не режется кэшем.

Просядут ли позиции после смены структуры? На две-четыре недели колебания практически неизбежны даже при идеально выполненной работе — роботу нужно обойти старые адреса, увидеть редиректы и переклеить сигналы. Опасный сценарий другой: если 404 провисели неделями без редиректов, часть страниц выпадет из индекса, и возвращать их придётся заново через переобход.

Записи открылись, а категории и вторые страницы пагинации по-прежнему 404. Почти всегда это конфликт слагов: у вас есть страница и рубрика с одинаковым адресом, либо базовый слаг рубрик совпадает с началом структуры записей. Поменяйте базовый префикс рубрик в настройках пермалинков и сбросьте правила заново.

Коротко

  • Главная жива, потому что / — это физический index.php; записи 404, потому что их адреса существуют только благодаря правилам перезаписи.
  • Тип 404 определяется по внешнему виду страницы: дизайн темы — сломан WordPress, голая страница сервера — сломаны mod_rewrite или try_files.
  • Первое действие — «Настройки — Постоянные ссылки — Сохранить изменения» или wp rewrite flush --hard; это чинит большинство случаев.
  • Старые адреса закрываются серверными 301: одно регулярное выражение на весь класс адресов плюс ручная карта на остаток, всё выше блока # BEGIN WordPress.
  • После починки обязательны перегенерация карты сайта, замена внутренних ссылок в текстах и меню, проверка канониклов и переобход через Вебмастер и IndexNow.
  • Редирект всех старых адресов на главную запрещён — это soft 404 и потеря веса; правила 301 не снимаются ни через месяц, ни через год.

Смена структуры постоянных ссылок относится к тем работам, где порядок действий важнее скорости: сначала бэкап и диагностика, потом правила, потом редиректы, и только потом переобход. Если вы уже словили 404 на всём блоге и не понимаете, где именно рвётся цепочка, или наоборот — только планируете переезд и хотите заранее посчитать риски, приходите на SEO-консультацию: разберём вашу структуру, соберём карту редиректов и наметим порядок работ под конкретный сайт. В SEO с 2005 года, продвижение веду лично, вы общаетесь со мной напрямую, а не с менеджером.

Увеличьте позиции и продажи вашего сайта

Профессиональное SEO-продвижение с гарантией результата. Выберите подходящую услугу:

Анатолий Кузнецов — SEO-оптимизатор

Остались вопросы по продвижению?

Меня зовут Анатолий Кузнецов, я SEO-оптимизатор с 20-летним стажем. Разберу ваш сайт, отвечу на вопросы и подскажу, что улучшить для роста позиций в Яндексе и Google.

Связаться со мной →

Комментарии

Тимур Азаматов
Убрал даты из адресов, получил 404 на всех 400 статьях. Пересохранил пермалинки — сайт ожил, но в Вебмастере теперь висит гора исключённых. Это само рассосётся или надо что-то делать?
Анатолий Кузнецов автор
Само не рассосётся, пока робот не увидит по старым адресам явный 301. Проверьте curl’ом десяток старых URL: если часть отдаёт 404, значит встроенное угадывание их не вытянуло, и нужно правило в .htaccess по шаблону из раздела про пачку редиректов. Дальше переотправьте карту сайта в разделе «Файлы Sitemap» и закиньте в «Переобход страниц» новые адреса самых трафиковых статей, а не подряд по списку. Рост исключённых в первые дни — нормальная реакция, они переедут в статус «редирект» по мере обхода. Через месяц вернитесь и сравните число страниц в поиске с тем, что было до переезда.
Влас Огородников
У меня nginx без Apache вообще. Правил .htaccess два часа, потом дошло, что его никто не читает. Может, стоит написать это капслоком в начале статьи.
Радмир Ишмуратов
Записи открываются, а вторые страницы пагинации в рубриках 404. Сброс правил не помогает, плагины отключал.
Анатолий Кузнецов автор
Классический конфликт слагов. Посмотрите, нет ли у вас страницы с адресом, совпадающим со слагом рубрики, — WordPress разрешает такое создать, а потом правило страницы перехватывает запрос раньше правила архива. Второй частый вариант: базовый префикс рубрик пустой, а структура записей начинается со слага рубрики, и движок не может отличить /category/page/2/ от записи. Поменяйте базовый префикс рубрик в настройках пермалинков на что-то вроде rubrika, сбросьте правила и проверьте. Заодно посмотрите вывод wp rewrite list — там видно, какое правило срабатывает первым, и это сразу закрывает вопрос.
Феликс Барановский
Про размещение RedirectMatch выше блока BEGIN WordPress — жирный плюс. У меня правила стирались после каждого захода в настройки, и я честно думал, что их удаляет хостинг.
Эмиль Вафин
Вопрос по внутренним ссылкам. Их реально надо переписывать в текстах, если 301 и так работает? Боюсь лезть в базу на живом сайте.
Анатолий Кузнецов автор
Сайт от этого не сломается, но переписать стоит. Каждый переход по внутренней ссылке через редирект — это лишний запрос робота и небольшая потеря в передаче веса, а на блоге в несколько сотен статей таких переходов тысячи. Делайте это через wp search-replace обязательно с ключом —dry-run на первом проходе: команда покажет число совпадений, ничего не меняя. Перед реальным прогоном снимите дамп базы — не «на всякий случай», а потому что откатывать построчно вы не сможете. И не забудьте про меню: пункты «Произвольная ссылка» лежат в постмете и под замену в wp_posts не попадут.
Рустам Хайбуллин
Хостер сказал, что AllowOverride у них выключен и включать не будут. Получается, красивые ссылки на таком тарифе невозможны в принципе?
Анатолий Кузнецов автор
На таком тарифе — да, .htaccess вам ничем не поможет, и никакие правки файла ситуацию не изменят. Вариантов три. Первый: попросить поддержку прописать правила прямо в конфиг виртуального хоста, некоторые хостеры это делают по заявке. Второй: переехать на тариф или хостинг, где .htaccess работает, — это вопрос часа и обычно небольшой доплаты. Третий, самый неприятный: остаться на структуре с параметром p, но тогда вы теряете ключ в адресе и удобство для пользователя. Я бы выбрал второй: экономия на тарифе, который не даёт управлять перезаписью URL, оборачивается ограничениями во всём остальном тоже.
Гордей Ланщиков
Отдельное спасибо за предупреждение про «Переезд сайта». Я его уже собирался применить и час искал, почему форма не принимает адрес.
Севастьян Кривошапко
Проверил цепочки скриптом с curl — почти везде было два шага: старый адрес слал на версию без слеша, а та уже на финальную. Лечится дописыванием слеша прямо в цель правила, то есть /$2/ вместо /$2. После правки везде один хоп.
Лаврентий Дурманов
Структура была /archives/512/. Слага в адресе нет, регулярка не спасает. Пришлось выгружать ID и слаги через wp post list и генерить полторы тысячи строк скриптом — работает, но файл конфига распух.
Аскольд Пирожков
После починки записи открываются в инкогнито, а в обычном браузере всё ещё 404. Мистика какая-то.
Демьян Ципляев
Кэш браузера, скорее всего. 404 отдавался с заголовками, разрешающими кэширование, вот он и залип.
Розалия Тахтарова
Сайту полтора года, структура /%category%/%postname%/. Хочу уйти на чистый слаг, потому что периодически перекладываю статьи по рубрикам и адреса ломаются. Стоит игра свеч или терпеть?
Анатолий Кузнецов автор
Если вы реально перекладываете статьи по рубрикам, то структура уже работает против вас: каждый перенос ломает адрес и плодит либо 404, либо новую пару редиректов. В такой ситуации разовый переезд на /%postname%/ дешевле, чем бесконечная течь. Технически он закрывается одним правилом на класс адресов, потому что слаг остаётся последним сегментом и в старом, и в новом адресе, — это самый простой сценарий из всех. Сделайте бэкап, смените структуру, проверьте пару десятков старых URL через curl, переотправьте карту и отправьте на переобход топ-30 страниц по трафику. Только не совмещайте это с редизайном или другими крупными правками: если что-то пойдёт не так, вы не поймёте, что именно было причиной.
Прокрутить вверх