hreflang и пагинация

Две продвинутые темы: разметка языковых версий через hreflang и SEO-дружелюбная пагинация списков.

hreflang — атрибут, который говорит поисковику: «у этой страницы есть версии на других языках/для других регионов, вот они». Помогает показать пользователю версию на его языке.

hreflang: международное SEO

Если у вас есть версии страницы на русском, английском, для разных стран — без разметки поисковик может показать не ту. Или счесть их дублями. hreflang связывает версии и указывает, кому какую показывать.

<link rel="alternate" hreflang="ru" href="https://site.com/ru/page">
<link rel="alternate" hreflang="en" href="https://site.com/en/page">
<link rel="alternate" hreflang="x-default" href="https://site.com/page">

Правила, которые часто нарушают:

  • Взаимность. Если RU-страница ссылается на EN, то EN обязана ссылаться обратно на RU. Иначе разметка игнорируется.
  • Самоссылка. Каждая версия включает hreflang на саму себя.
  • x-default — запасная версия для всех, кто не подошёл под язык/регион.
  • Коды: язык по ISO 639-1 (ru, en), при необходимости плюс регион (en-GB, pt-BR).

Как работает под капотом: проверка взаимности

Самый частый баг hreflang — отсутствие обратной ссылки. Проверим граф связей на согласованность:

# у каждой страницы — на кого она ссылается через hreflang
links = {
    "/ru/page": ["/ru/page", "/en/page"],
    "/en/page": ["/en/page"],                 # забыли ссылку на /ru/page!
}

def check_reciprocity(links):
    problems = []
    for src, targets in links.items():
        for t in targets:
            if t == src:
                continue
            back = links.get(t, [])
            if src not in back:
                problems.append(f"{src} -> {t}, но {t} не ссылается обратно")
    return problems or ["все ссылки взаимны"]

for p in check_reciprocity(links):
    print(p)

Вывод:

/ru/page -> /en/page, но /en/page не ссылается обратно

Пагинация для SEO

Списки (каталог, блог, лента) разбивают на страницы. Главное правило сегодня: каждая страница пагинации — самостоятельный индексируемый URL с self-canonical. Старый приём rel="next"/"prev" Google больше не использует для индексации, но он не вреден и помогает другим ботам.

/blog?page=1   canonical -> /blog?page=1   (на себя, НЕ на page=1 со всех!)
/blog?page=2   canonical -> /blog?page=2
/blog?page=3   canonical -> /blog?page=3

Типичная ошибка — поставить canonical всех страниц пагинации на первую: тогда товары/посты со 2-й и далее страниц выпадают из индекса.

Бесконечная прокрутка

«Бесконечный скролл» удобен людям, но опасен для SEO: бот не скроллит, контент за пределами первого экрана он не подгрузит. Решение — гибрид: бесконечная прокрутка для UX плюс реальные постраничные URL (?page=N) с настоящими <a href>, по которым бот пройдёт и проиндексирует всё.

Частые ошибки

  • hreflang без взаимных ссылок — разметка игнорируется целиком.
  • Неверные коды (en-UK вместо en-GB) — частая опечатка.
  • Canonical пагинации на первую страницу — теряете весь контент глубже первой.
  • Только бесконечный скролл без href-пагинации — бот видит лишь первый экран.

Итог

  • hreflang связывает языковые/региональные версии; ссылки обязаны быть взаимными и включать self и x-default.
  • Страницы пагинации — самостоятельные индексируемые URL с self-canonical, а не canonical на первую.
  • Бесконечную прокрутку дополняйте реальными постраничными ссылками, иначе бот увидит только первый экран.
Проверьте себя
1. Что произойдёт, если RU-страница ссылается на EN через hreflang, а EN не ссылается обратно на RU?
AНичего, hreflang всё равно сработает
BРазметка hreflang будет проигнорирована — нужна взаимность ссылок
CEN-страница выпадет из индекса
DGoogle автоматически создаст обратную ссылку
2. Каким должен быть canonical на странице пагинации /blog?page=3?
Acanonical на /blog?page=1
Bcanonical на саму себя (/blog?page=3)
Cnoindex вместо canonical
Dcanonical на главную страницу
3. Почему чистая бесконечная прокрутка опасна для SEO?
AОна замедляет сервер
BБот не скроллит — контент за первым экраном не подгрузится и не проиндексируется
CБесконечная прокрутка запрещена стандартом
DОна ломает hreflang