В теге предпочтительного адреса canonical записано href="article/", а выше появился <base> с адресом другого раздела. Строка не изменилась, но браузер достроил из неё другой полный URL. Сравните записанное значение и получившийся адрес, чтобы понять причину.
Как браузер достраивает относительный адрес
MDN описывает разрешение относительных ссылок относительно базового URL, включая ссылки от корня. Официальная документация.
Строки article/, /article/ и https://example.com/article/ задают разные правила построения адреса. Первая использует текущий каталог базы, вторая — её корень, третья задаёт полный адрес. Если в документе появляется base на другом домене, первые две строки могут начать вести туда. Canonical нередко создаётся отдельным плагином, который не знает о настройке base в теме. Поэтому в исходнике остаётся article/, а полный адрес ведёт в другой раздел или на чужой домен.
Что получится при разных href
| Значение href | Какой base задан | Получившийся адрес | Что это значит |
|---|---|---|---|
| href="article/" | База /docs/ | Получится /docs/article/ | Проверить document.baseURI |
| href="/article/" | База на другом хосте | Корень другого хоста | Слеш не фиксирует домен |
| Абсолютный HTTPS URL | Любая база | Адрес явно задан | Предпочтительный вариант |
| Base меняет скрипт | HTML до и после скрипта различается | Повторить после загрузки | Найти генератор |
Сравните три значения в консоли
Для найденного link сравните getAttribute("href") с его свойством href. Первый возвращает записанное значение, второе показывает вычисленный адрес элемента в браузере. Дополнительно сохраните document.baseURI. Если эти данные противоречат ожиданию, найдите base в служебной части HTML — head — и выясните источник его появления. Проверяйте все canonical-элементы: выбор только первого скрывает дублирующий вывод. Такой тест не доказывает, что поисковик уже выбрал иной URL; он подтверждает конкретную неоднозначность или неправильное разрешение в текущем документе.
({ база: document.baseURI, canonical: [...document.querySelectorAll('link[rel="canonical"]')].map(el => ({ записано: el.getAttribute('href'), вычислено: el.href })) });Если записано содержит article/, а вычислено показывает чужой домен, посмотрите <base href="..."> в head. Исправьте генератор canonical, чтобы он выводил полный HTTPS URL нужной страницы. Команда только читает страницу и не меняет настройки сайта.
Выведите полный URL в canonical
Выводите в canonical полный URL рабочего сайта, например https://example.com/docs/article/. Домен задайте в настройках сайта. Если он берётся из заголовка Host — имени домена в запросе, — разработчик должен ограничить его разрешёнными доменами, чтобы посторонний запрос не подставил чужой хост. Попросите разработчика убедиться, что сборка тестового сайта не встроила свой домен в рабочую версию. Если base нужен другим ресурсам, оставьте его и исправьте только генератор canonical. Если base признан ошибочным, перечислите относительные ресурсы, меню и адреса отправки форм — action, которые требуется проверить после удаления. Удаление base меняет и обычные ссылки, поэтому одной проверки canonical здесь мало.
Проверьте адрес со слешем и без него
При отсутствии явного base базовым становится адрес документа. Для https://example.com/docs и https://example.com/docs/ относительное article/ может разрешаться по-разному, потому что первый адрес выглядит как файл, второй — как каталог. Сначала выясните, перенаправляет ли сервер один вариант на другой, затем вычисляйте адрес относительно фактического конечного URL. Проверьте обе формы прямым входом, особенно если промежуточный сервер перед приложением меняет путь. Если генератор выдаёт абсолютный canonical, это различие больше не влияет на его href, но по-прежнему может влиять на обычные относительные ссылки. При следующей смене маршрутов снова откройте обе формы /docs и /docs/. Это быстро покажет, вернулась ли ошибка с относительными адресами.
После правки откройте вложенную страницу
У canonical записанный href и полный адрес в браузере должны совпадать с нужным полным URL. Если меняли base, дополнительно откройте относительную ссылку меню и изображение; адрес отправки формы (action) проверьте в HTML без отправки сообщения.
Читайте также: HTML валидация: зачем проверять код и как исправить ошибки и Конфликт canonical, sitemap, hreflang и редиректов. Проверки сайта доступны на странице технического аудита reChecker.