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