Страница 404 - код ответа, свой шаблон, мягкие ошибки
Делаем страницу 404 так, чтобы посетитель видел понятный текст, а поисковая система - настоящий код ошибки вместо обычной страницы.
Что нужно знать заранее
У ошибки есть две стороны: что видит человек и что видит робот. Человеку нужен понятный текст со ссылками, роботу - код ответа, по которому он поймёт, что страницы больше нет.
Мягкая ошибка - это красивая страница ошибки с кодом успешного ответа. Поисковая система считает её обычной страницей и держит в индексе, а вебмастер потом удивляется тысячам пустых адресов в отчётах.
Страница ошибки живёт отдельным файлом в корне сайта и подключается платформой. Настройка обработки ошибки включается в административном разделе, а сам файл верстают как обычную страницу.
Шаги
- Проверить, какой код ответа отдаёт несуществующий адрес сайта прямо сейчас.
- Включить обработку ошибки в настройках продукта и завести файл страницы ошибки.
- Поставить в этот файл установку кода ответа выше любой строки вывода разметки.
- Отдавать ошибку прямо из кода там, где элемент или раздел не найден.
- Смотреть журнал веб-сервера и чинить битые ссылки на страницах самого сайта.
Решение
Проверяем код ответа несуществующего адреса:
curl -sI https://example.com/net-takoy-stranicy/ | head -1# ожидаем HTTP/1.1 404 Not Found, а не 200 OK и не 302 Foundcurl -sI https://example.com/catalog/net-takogo-tovara/ | head -1# карточку несуществующего товара проверяют отдельно: там своя обработкаПроверка занимает секунду и снимает главный вопрос всего разбора. Красивая страница с кодом успешного ответа - самая частая ошибка: она выглядит правильно в браузере и неверна для поисковой системы.
Ставим код ответа в файле страницы ошибки:
// /404.php в корне сайта, до вывода разметкиdefine('ERROR_404', 'Y');require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php';\CHTTP::SetStatus('404 Not Found'); // настоящий код ответа для робота$APPLICATION->SetTitle('Страница не найдена');Установка кода идёт до вывода разметки страницы. После первой строки вывода заголовки ответа уже отправлены, и поменять их не получится ни в шаблоне, ни в компоненте.
Отдаём ошибку из кода при отсутствии элемента:
$element = CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ID' => $id], false, false, ['ID'])->Fetch();if (!$element) { \Bitrix\Iblock\Component\Tools::process404('', true, true, true, '/404.php');}// пустая карточка с кодом успешного ответа хуже, чем честная ошибкаШтатный вызов делает сразу три вещи: показывает страницу ошибки, ставит код ответа и пишет запись в журнал. Свой код с одной установкой заголовка обычно забывает про журнал и про сам вывод страницы.
Смотрим частые ошибки в журнале веб-сервера:
awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20# верхние строки - это чаще всего битые ссылки на самом сайте, а не ботыВерхние адреса в этом списке почти всегда приходят с самого сайта. Их чинят в меню, в карточках товаров и в письмах, а не закрывают правилом перенаправления на главную страницу.
Ставим редирект там, где адрес действительно сменился:
location = /old-catalog/ { return 301 /catalog/; }# перенаправление уместно для переехавшей страницы, а не вместо ошибкиПеренаправление и ошибка решают разные задачи. Страница переехала - код перенаправления, страница исчезла - код ошибки, и подмена одного другим путает и поисковую систему, и посетителя.
Типичные проблемы
Несуществующий адрес отвечает кодом успешной страницы.
Обработка ошибки включена, но установки кода ответа в файле страницы нет вовсе. Код ответа ставят до вывода разметки, первой же строкой файла ошибки.
Вместо ошибки посетителя уводит на главную страницу.
Настроено перенаправление на главную вместо показа страницы ошибки. Поисковая система при этом считает старые адреса живыми и держит их в индексе.
Карточка несуществующего товара открывается пустой.
Компонент не проверяет наличие элемента и потому не отдаёт ошибку. Отсутствие элемента обрабатывают штатным вызовом страницы ошибки до вывода разметки.
Код ответа не меняется, хотя вызов в коде есть.
Часть страницы уже выведена, и заголовки ответа отправлены браузеру. Проверку наличия элемента делают до вывода, в самом начале страницы.
После включения композита ошибка снова отдаёт успешный код.
Страница ошибки попала в кэш готовых страниц и отдаётся оттуда. Такие страницы из композитного кэша исключают явным образом, отдельной настройкой.
Частые вопросы
Обязательно ли делать свою страницу ошибки?
Да, иначе посетитель видит служебный текст веб-сервера и уходит. Своя страница со ссылками на разделы и поиском возвращает часть посетителей на сайт.
Чем 404 отличается от 410?
Первый код означает «страницы нет», второй - «удалена навсегда». Для товаров, снятых с продажи, иногда берут второй, но большинству проектов хватает обычной ошибки.
Нужно ли закрывать 404 от индексации?
Нет, правильный код ответа уже говорит роботу всё нужное. Дополнительные запреты только усложняют настройку и ничего не дают.
Что делать со старыми адресами после переезда?
Ставить перенаправление на новый адрес, а не отдавать ошибку. Ошибка уместна там, где замены странице нет вовсе.
Как найти битые ссылки внутри сайта?
По журналу веб-сервера с отбором по коду ошибки и по обходу сайта краулером. Первое дешевле и показывает то, по чему реально ходят посетители.
Смежное
- ЧПУ и SEO комплексных компонентов - оглавление подтемы
- Свои ЧПУ-адреса: правила обработки, порядок, конфликты - откуда берутся адреса своих страниц
- ЧПУ комплексного компонента: настройка и разбор 404 - когда 404 даёт детальная страница
- Ссылка на товар ведёт в 404: разбор причин - тот же разбор в каталоге
- Дубли страниц каталога: канонический адрес, пагинация, фильтр - соседняя задача про индексацию
- Редиректы внутри сайта: 301 на раздел, https и старые адреса - когда нужен переезд, а не ошибка
- Карта сайта и robots.txt: генерация, расписание, мультисайт - что ещё видит поисковый робот
- Компоненты и шаблоны - устройство компонентов целиком
- Сайт на технических работах: заглушка и доступ для своих - какой код ответа отдавать во время работ