Представьте: сайт работает, страницы открываются, всё выглядит нормально. Но однажды вы запускаете краулер — и он находит 300+ битых ссылок. Все ведут на несуществующие адреса вроде /katalog/blog/, /product/blog/, /works/blog/category/.... Откуда взялся этот мусор, если ссылка на блог — вот она, в меню, работает?

Разбираю реальную ситуацию, которую встречаю на MODX-сайтах регулярно. Одна системная настройка — и навигация ломается на всех вложенных страницах.

Суть проблемы: относительные vs абсолютные ссылки

Браузер интерпретирует ссылки по-разному в зависимости от того, есть ли ведущий слеш:

  • href="/blog/" — абсолютный путь. Всегда ведёт на site.ru/blog/, с какой бы страницы ни кликнули
  • href="blog/" — относительный путь. Браузер дописывает его к текущему URL

Вот что происходит с относительной ссылкой href="blog/" в меню:

Текущая страницаКуда ведёт ссылкаРезультат
/ (главная)/blog/✅ Работает
/katalog//katalog/blog/❌ 404
/product/tovar-1//product/tovar-1/blog/❌ 404
/works//works/blog/❌ 404

На главной всё ок — потому что корень / + blog/ = /blog/. Но стоит зайти на любую вложенную страницу — и ссылка начинает вести в никуда.

Почему это происходит в MODX

В MODX Revolution есть системная настройка link_tag_scheme. Она определяет формат URL, который генерируется функциями makeUrl(), фильтром url в Fenom и сниппетами вроде pdoMenu, pdoCrumbs.

Возможные значения:

ЗначениеФормат URLПример
-1Относительныйblog/
0 или пустоОтносительно корня/blog/
absАбсолютный от корня/blog/
fullПолный URLhttps://site.ru/blog/
httpsHTTPS URLhttps://site.ru/blog/

Значение -1 — это корень проблемы. При нём MODX генерирует URL относительно текущей страницы, без ведущего слеша. И любая ссылка в навигации, крошках, карточках товаров — начинает ломаться на вложенных уровнях.

Как это выглядит в шаблонах

Fenom-шаблон с фильтром url:

<a href="{242|url}">Блог</a>

При link_tag_scheme = -1 это рендерится как:

<a href="blog/">Блог</a>

pdoCrumbs без указания scheme:

{$_modx->runSnippet('pdoCrumbs', [])}

Хлебные крошки тоже получают относительные пути — и ведут в никуда на вложенных страницах.

Как найти проблему

1. Проверьте системную настройку

Зайдите в админку MODX → Настройки системы → найдите link_tag_scheme. Если стоит -1 — это оно.

2. Проверьте HTML вложенной страницы

Откройте любую страницу второго уровня (например, /katalog/) и посмотрите исходный код. Ищите ссылки без ведущего слеша:

curl -s https://site.ru/katalog/ | grep -oP 'href="[^/"h][^"]*"' | head -20

Если видите href="blog/", href="blog/category/..." — это относительные ссылки.

3. Прогоните краулер

Screaming Frog, Netpeak Spider или любой другой — фильтруйте по статусу 404. Если в списке десятки URL вида /katalog/blog/, /product/kontakty/, /works/uslugi/ — это массовая проблема относительных путей.

Как исправить

В админке MODX → Настройки системы:

link_tag_scheme → abs

Это заставит все стандартные функции генерации URL возвращать абсолютные пути с ведущим /.

Шаг 2. Исправьте Fenom-шаблоны

Замените фильтр url на явный вызов makeUrl с параметром abs:

Было:

<a href="{242|url}" class="footer-nav__item">Блог</a>

Стало:

<a href="{$_modx->makeUrl(242, '', '', 'abs')}" class="footer-nav__item">Блог</a>

Параметры makeUrl:

  • 242 — ID ресурса
  • '' — контекст (пустая строка = текущий)
  • '' — параметры URL
  • 'abs' — схема (абсолютный путь)

Шаг 3. Исправьте pdoCrumbs

Добавьте параметр scheme в вызов:

Fenom-синтаксис:

{$_modx->runSnippet('pdoCrumbs', ['scheme' => 'abs'])}

MODX-тег:

[[pdoCrumbs? &scheme=`abs`]]

Шаг 4. Исправьте карточки и списки

Если в шаблонах карточек (товары, статьи) URL подставляется через {$uri}, замените на makeUrl:

Было:

<a href="{$uri}">{$pagetitle}</a>

Стало:

<a href="{$_modx->makeUrl($id, '', '', 'abs')}">{$pagetitle}</a>

Шаг 5. Проверьте хардкод

Иногда ссылки прописаны руками в чанках. Найдите все такие случаи через SSH:

grep -rn 'href="[^/"h#\{]' core/elements/ --include="*.tpl" --include="*.html"

Эта команда найдёт все href=, которые начинаются НЕ с /, НЕ с http, НЕ с # и НЕ с { — то есть потенциально относительные ссылки.

Шаг 6. Очистите кэш

Обязательно после всех правок:

# Через SSH
find core/cache -mindepth 1 -maxdepth 1 ! -name '.gitignore' -exec rm -rf {} +

Или через админку: Управление → Очистить кэш.

Чеклист: проверка после исправления

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

  • link_tag_scheme = abs в системных настройках
  • На вложенной странице (/katalog/) все ссылки в меню ведут правильно
  • Хлебные крошки показывают корректные абсолютные URL
  • Карточки товаров/статей ведут на правильные страницы
  • Повторный краулинг не находит 404 вида /katalog/blog/
  • Кэш MODX очищен

Почему это важно для SEO

Относительные ссылки в навигации — это не просто «не работают кнопки». Это серьёзная SEO-проблема:

Раздутый индекс. Поисковые боты ходят по всем ссылкам. Если на каждой из 50 страниц каталога есть относительная ссылка на блог — краулер найдёт 50 несуществующих URL. Умножьте на количество таких ссылок в навигации, футере, крошках — и получите сотни фантомных страниц.

Потерянный краулинговый бюджет. Поисковик тратит ресурсы на обход 404 вместо индексации реального контента.

Сигнал низкого качества. Массовые 404 — это сигнал поисковым системам, что сайт заброшен или плохо поддерживается.

Битые внутренние ссылки. PageRank не передаётся через 404. Страницы, на которые должны вести ссылки из навигации, теряют вес.

Как не допустить повторения

  1. Не ставьте link_tag_scheme = -1 без веской причины. Значение abs — безопасный дефолт.

  2. Используйте makeUrl вместо хардкода. Ссылка href="/blog/" работает, но привязана к конкретному alias. Если alias изменится — ссылка сломается. makeUrl(ID) всегда вернёт актуальный URL.

  3. Всегда указывайте scheme в pdoTools. По умолчанию pdoCrumbs и pdoMenu наследуют link_tag_scheme. Если системная настройка вдруг изменится — ваши крошки сломаются. Явный &scheme=abs страхует от этого.

  4. Периодически прогоняйте краулер. Даже если всё работает — запускайте проверку раз в месяц. Битые ссылки могут появиться после обновления MODX, смены шаблона или редактирования чанков.

  5. Добавьте правило в чанки комментарием:

{* ВАЖНО: всегда использовать makeUrl(..., 'abs') — НЕ фильтр |url *}

Это спасёт от ситуации, когда кто-то через полгода скопирует старый код с {ID|url} и вернёт проблему.

Итого

Одна настройка link_tag_scheme = -1 + навигация в шаблонах = сотни фантомных 404 на вложенных страницах. Проблема незаметна на главной, но ломает весь сайт для поисковых ботов и пользователей, которые кликают по меню не с корневой страницы.

Фикс занимает 15 минут: сменить системную настройку, пройтись по шаблонам, добавить abs в вызовы pdoTools, очистить кэш. Но если не знать, где искать — можно месяцами гадать, откуда берутся битые ссылки в Search Console.

Автор материала

Антон Ветров Разработка сайтов, поисковая доступность, автоматизация и эксплуатация.