В коде ссылки записан адрес href="contacts/": он работает с главной, но из /catalog/item/ открывает /catalog/item/contacts/. Браузер достроил относительную ссылку от текущего каталога. Сравните запись href с полным URL, который получился на главной и в карточке.
Почему путь зависит от открытой страницы
MDN описывает разные способы разрешения относительных адресов, включая текущий каталог и корень сайта. Официальная документация.
На /catalog/item/ строка contacts/ обычно добавляется к текущему каталогу базы, а не к корню сайта. Именно поэтому ссылка, работавшая на главной, начинает открывать вложенный отсутствующий путь. Сначала посмотрите адрес открытой страницы после редиректов и проверьте <base> в head. От них зависит получившийся URL. Не исправляйте несуществующий /catalog/item/contacts/ созданием новой копии контактов: это маскирует ошибку общего меню. Ссылка общего меню должна вести на предусмотренную страницу контактов текущего языка с главной, категории и карточки.
Относительный путь, корень и полный URL
| Вид href | Как браузер строит URL | Что поменять | Какой адрес проверить |
|---|---|---|---|
| contacts/ с главной | Относительный путь | Проверить вычисление | Ожидаемые контакты |
| contacts/ из карточки | Глубокая база | Найти ошибочный путь | Не вложенные contacts |
| /contacts/ | Путь от корня | Проверить язык и base | Нужный хост |
| Абсолютный URL | Хост задан явно | Проверить окружение | Не staging |
Сравните записанный и вычисленный href
Найдите элемент ссылки и сравните getAttribute("href") с его свойством href. Затем откройте вычисленный адрес в новой вкладке. Если он отвечает 404, отдельно проверьте правильную страницу контактов, чтобы подтвердить, что ресурс существует. Посмотрите, не меняется ли ссылка после клиентской навигации: компонент может вычислять её из текущего router-path. Проверьте также base в head. Ошибка бывает на уровне данных ссылки, механизма разрешения или позднего изменения DOM. Если ошибочен href в CMS, замените его там. Если правильный адрес меняет скрипт, исправьте компонент меню.
Рассчитайте адрес на примере
Для учебной базы https://example.com/catalog/item/ сравните new URL("contacts/", base).href и new URL("/contacts/", base).href. Первый адрес останется вложенным, второй начнёт путь от корня этого хоста. Затем используйте базу https://example.com/ru/catalog/ и посмотрите, какой вариант сохраняет язык. Такой расчёт можно выполнить отдельно от живого интерфейса. Для русской страницы контактам может требоваться /ru/contacts/, а /contacts/ сбросит язык. Выберите нужный путь и используйте одну функцию его построения во всех внутренних меню.
Этот расчёт двух адресов можно выполнить в консоли браузера:
const base = "https://example.com/catalog/item/";
[new URL("contacts/", base).href, new URL("/contacts/", base).href];Результаты: /catalog/item/contacts/ и /contacts/ на example.com. На странице проверьте document.baseURI: тег base может задавать другой домен. Команда только вычисляет адреса.
Исправьте ссылку в общем меню
Исправьте источник href в общем компоненте или настройке CMS. Если меню получает маршрут из справочника, проверьте именно значение, а не создавайте обработчик клика поверх ошибочной ссылки. Сохраните стандартный переход, возможность новой вкладки и доступность с клавиатуры. Для framework используйте предусмотренный компонент ссылок, убедившись, что его выходной HTML содержит правильный href. После правки откройте один и тот же компонент на разных страницах. Локальная замена только в карточке не исправит футер и меню, если они продолжают формировать относительные ошибочные назначения.
Учтите язык и тег base
Если base указывает на другой хост, начальный слеш всё ещё разрешается на нём. Поэтому совет «добавить /» требует проверки полной базы. В мультиязычном приложении функция построения URL должна учитывать выбранный язык. В приложении, опубликованном в подпапке, корень домена может отличаться от корня продукта. Перечислите эти случаи до изменения. Абсолютный production-URL тоже нельзя копировать в staging без понимания назначения. Проверьте русский и английский разделы, тестовый и рабочий домены. Одна функция построения ссылок должна выдавать правильный путь в каждом случае.
Откройте контакты с трёх страниц
Ссылка с главной, категории и карточки ведёт на нужные контакты. После клиентского перехода и перезагрузки результат тот же; язык и домен сохранены. Исправление общего компонента не требует создавать копии контактов по ошибочным путям.
Читайте также: Архитектура сайта: силосная структура URL и глубина кликов и HTML валидация: зачем проверять код и как исправить ошибки. Проверки сайта доступны на странице технического аудита reChecker.