5453 страницы-дубля: как мультиязычность тихо убивает индексацию
Коротко: в чём суть проблемы
Если на сайте включена мультиязычность, но переведена только часть страниц, движок может сгенерировать пустые копии всех остальных разделов на каждом языке. Эти копии отдают код 200 «страница существует», но контента в них нет, а заголовок наследуется от главной. Для поисковой системы это тысячи одинаковых страниц.
На собственном сайте BotClinic мы обнаружили 5453 такие страницы. Панель Яндекс.Вебмастера при этом показывала «2 дублирующихся title» — она видит только то, что уже попало в индекс. Реальный масштаб оказался в 2700 раз больше.
Почему панель вебмастера показывает не всю картину
Диагностика Вебмастера и Search Console строится по проиндексированным страницам. Если мусорные копии ещё не попали в индекс, в отчёте их не будет. Вы видите «2 дубля», считаете проблему мелкой — а робот тем временем постепенно обходит остальные тысячи.
Это принципиальное ограничение: панели показывают следствие с задержкой, а не причину. Чтобы увидеть причину, нужно смотреть на то, что физически лежит в сборке сайта.
Практический вывод: после любой правки, затрагивающей маршрутизацию или локализацию, сверяйте количество сгенерированных страниц. Рост числа файлов без роста контента — почти всегда мусор.
Как выглядела проблема технически
Сайт собран на Next.js со статической генерацией и тремя языковыми версиями. Разделы блога, ниш, услуг и городов не задавали явно, для какого языка их создавать — и фреймворк добросовестно сгенерировал копии под каждый. Переведены при этом были только главные страницы.
В итоге адрес вида /en/blog/статья/ отдавал код 200, пустое тело и заголовок главной. Хуже того, на этих страницах оказались сразу два конфликтующих указания для роботов: одно запрещало индексацию (от механизма «страница не найдена»), другое разрешало (от общего шаблона). Какое учтёт поисковик — вопрос удачи.
В карте сайта этих адресов не было. Но на главной стоял корректный указатель языковых версий (hreflang), который прямо сообщал роботам: у страницы есть английская и казахская версии. Роботы шли по указателю и попадали в пустые копии.
Как обнаружить это у себя: три проверки
1. Сравните число страниц в сборке с числом уникальных заголовков. Если страниц 5000, а уникальных title 3000 — у вас 2000 дублей. Самая быстрая диагностика: занимает пару минут и не требует доступа к панелям.
2. Откройте любую страницу неосновной языковой версии и посмотрите исходный код. Заголовок совпадает с главной, а текста нет — проблема есть. Заодно проверьте, не встречается ли указание для роботов дважды.
3. Загляните в историю обхода в Яндекс.Вебмастере: там видно, какие адреса робот посещал и какой код получал. Именно этот отчёт в нашем случае показал реальную картину — в нём обнаружились и другие проблемы, невидимые в сводке.
Такие проверки входят в наш технический аудит: панельные отчёты дополняются анализом самой сборки, потому что панели по определению отстают от реальности.
Что мы сделали и что получилось
Решение зависит от того, планируете ли вы реальный перевод. Если да — переводите разделы и оставляйте языковые версии. Если нет (наш случай: переведены только главные) — генерацию внутренних разделов нужно ограничить одним языком.
Мы явно указали для каждого раздела, что он существует только на русском. Число страниц упало с 5482 до 5106, групп дублирующихся заголовков стало три вместо семи, причём оставшиеся безобидны: перенаправление с корня, служебные страницы ошибок и раздел контактов, закрытый каноническим адресом.
Адреса вида /en/blog/статья/ теперь честно отдают 404 вместо ложного «страница есть». Для поисковой системы это чистый сигнал: страницы не существует.
Отдельный нюанс: одна страница оказалась клиентским компонентом, и задать для неё язык сборки на уровне фреймворка было нельзя — сборка падала с ошибкой. Там мы обошлись каноническим адресом, который решает ту же задачу иначе.
Чем это грозит, если не чинить
Первое — распыление краулингового бюджета. Робот тратит визиты на пустые копии вместо реальных страниц. Чем больше сайт, тем дороже обходится мусор.
Второе — риск оценки качества. Тысячи пустых страниц с одинаковыми заголовками выглядят как признак низкокачественного сайта. У нас уже был прецедент: Яндекс исключил 3808 страниц со статусом «нет спроса», когда мы сгенерировали избыточные комбинации. Урок тот же: объём без содержания вредит.
Третье — ложные сигналы для нейросетей. Языковой указатель сообщал ИИ-краулерам, что у страницы есть английская версия. Они приходили и получали пустоту вместо контента, который могли бы процитировать. О том, как ИИ выбирает источники, — в нашем исследовании AI-выдачи.
Правило, которое мы вынесли
Мультиязычность включается не флагом, а решением: какие именно страницы вы реально переводите. Всё остальное не должно существовать физически — не «закрыто от индексации», а просто не сгенерировано.
Закрытие от индексации помогает слабее, чем кажется: страница всё равно создаётся, попадает в сборку, тратит время робота и может получить противоречивые указания. Отсутствующая страница таких проблем не создаёт.
И главное: доверяйте сборке больше, чем панели. Панель показывает, что успел увидеть робот. Сборка показывает, что есть на самом деле.
Частые вопросы
Как быстро проверить, есть ли у меня дубли заголовков?+
Сравните общее число страниц в сборке сайта с числом уникальных значений title — разница и есть дубли. Проверка занимает минуты и не требует доступа к панелям вебмастера; в отличие от отчётов Яндекса и Google, она показывает реальное положение дел, а не только проиндексированную часть.
Почему Яндекс показывал 2 дубля вместо 5453?+
Диагностика Вебмастера строится по страницам, уже попавшим в индекс. Мусорные копии туда ещё не дошли, поэтому в отчёте их не было. Панели показывают следствие с задержкой — причину нужно искать в самой сборке сайта.
Может, достаточно закрыть лишние страницы от индексации?+
Это слабее, чем не создавать их вовсе. Закрытая страница всё равно генерируется, попадает в сборку и тратит визиты робота при обходе. К тому же в нашем случае на таких страницах оказалось два конфликтующих указания для роботов сразу — какое учтёт поисковик, предсказать нельзя.
Это специфично для Next.js?+
Механика описана на примере Next.js, но проблема общая для любой системы с мультиязычностью: страницы генерируются под все языки, а переведена только часть. То же встречается в WordPress с языковыми плагинами и других CMS. Симптом везде одинаковый — рост числа страниц без роста контента.