Перейти к контенту
Neaptidestudio
блог

Canonical в Next.js указывает на другой домен: проверенные причины

Neaptide · 4 октября 2026 г. · 9 мин чтения · Обновлено: 13 октября 2026 г.

Проверили восемь конфигураций метаданных Next.js по HTML и DOM браузера. Показываем причины неверного canonical, исправления и данные эксперимента.

В этой статье
Canonical в Next.js указывает на другой домен: проверенные причины

Если страница Next.js выдаёт canonical на старом домене, изменение metadataBase может ничего не исправить. В нашем сценарии с абсолютным URL старый адрес сохранился при правильной базе. Помогло изменение alternates.canonical страницы. Сначала посмотрите, какой адрес приложение действительно выдаёт, затем найдите настройку, из которой он берётся.

Что мы проверили

4 октября 2026 года мы собрали отдельный стенд App Router на Next.js 15.5.22, React 19.2.6 и Node.js v25.2.1. До замеров задали восемь конфигураций: одну исправную контрольную и семь с намеренно внесёнными ошибками. В одной production-сборке у каждой есть варианты до и после изменения. В каждой паре меняли одну настройку метаданных; контроль оставили прежним.

Каждый адрес запросили дважды: 32 HTTP-ответа для 16 URL. Затем проверили все 16 документов в браузере. Во всех ответах был статус 200 и ровно один canonical в head; повторные запросы и DOM совпали. После соответствующих изменений семь намеренных расхождений исчезли. Это проверка заданных конфигураций, а не исследование распространённости ошибок на сайтах.

Пути /cXX/before и /cXX/after разделяют сценарии стенда. Заданные canonical используют зарезервированные домены example.com и демонстрационные пути товаров, а не повторяют локальные URL. Сам стенд имеет noindex, nofollow.

Восемь конфигураций и фактические адреса

Наблюдения на Next.js 15.5.22. В колонке «После» контрольный сценарий оставлен без изменений.
Сценарий / конфигурацияДо: выданный canonicalПосле: выданный canonical
C01 · Правильная база и относительный путь — контрольhttps://www.example.com/products/widgethttps://www.example.com/products/widget
C02 · Неверный домен базыhttps://preview.example.com/products/widgethttps://www.example.com/products/widget
C03 · Старый абсолютный canonicalhttps://old.example.com/products/widgethttps://www.example.com/products/widget
C04 · Canonical главной унаследован от layouthttps://www.example.comhttps://www.example.com/products/widget
C05 · Вложенный layout заменяет корневую базуhttps://legacy.example.com/products/widgethttps://www.example.com/products/widget
C06 · Лишний путь в metadataBasehttps://www.example.com/catalog/products/widgethttps://www.example.com/products/widget
C07 · Пропущен языковой префикс /frhttps://www.example.com/products/widgethttps://www.example.com/fr/products/widget
C08 · Preview-домен из окружения сборкиhttps://preview.example.com/products/widgethttps://www.example.com/products/widget

Статус HTTP 200 не отличал правильные метаданные от ошибочных: его вернули все страницы стенда. Проверяйте полный адрес, включая путь и язык. В C04 Next.js выдал адрес главной без завершающего слеша; для заданной карточки товара он всё равно оставался неверной целью.

Найдите настройку, которая задаёт неверную часть URL

До исправления C03 абсолютный canonical указывает на old.example.com/products/widget, и HTML содержит тот же адрес. После замены поля на www.example.com/products/widget HTTP и DOM совпадают с ожидаемым URL.
Изменено одно поле. HTTP и DOM браузера совпадают.

Другой домен при относительном canonical — C02, C05 и C08. Проверьте metadataBase в корневом и вложенных layout. В C05 удаление вложенного переопределения вернуло правильную корневую базу. В C08 контролируемая переменная сборки задавала preview-домен; замена этого источника на нужный production-домен исправила результат.

Другой домен при абсолютном canonical — C03. Страница уже содержала полный старый URL, поэтому правильная metadataBase его не заменила. Исправьте это значение или источник, который его формирует, и снова проверьте выданный тег.

Карточка товара указывает на главную — C04. Дочерняя страница унаследовала canonical из layout. Собственное alternates.canonical страницы вернуло нужный путь товара. Проверьте затронутые шаблоны: настройка главной сама не становится адресом каждой страницы.

Домен правильный, путь неверный — C06 и C07. Префикс /catalog в базе остался в итоговом URL, хотя значение canonical начиналось с /. Удаление лишнего пути базы исправило C06. Добавление пропущенного /fr исправило C07. Нужные вашему размещению префиксы сохраняйте.

Небольшая явная конфигурация для адаптации

Для сайта в корне домена задайте базовый адрес в layout, а путь страницы — в её метаданных. Ниже исправленный вариант C02. Замените демонстрационные домен и путь своими; для сайта в подпапке отдельно определите правила путей.

// app/layout.tsx
export const metadata = {
  metadataBase: new URL("https://www.example.com"),
};

// app/products/widget/page.tsx
export const metadata = {
  alternates: { canonical: "/products/widget" },
};

Если страница содержит старый абсолютный URL из следующего примера, одной правки layout недостаточно. В C03 мы изменили только это значение canonical.

// C03 — before
alternates: {
  canonical: "https://old.example.com/products/widget"
}

// C03 — after
alternates: {
  canonical: "https://www.example.com/products/widget"
}

Проверьте собранную страницу и документ браузера

  1. Соберите production-версию с той конфигурацией публичного домена, которая нужна при размещении. Если хостинг, middleware или CDN меняют ответ, проверьте и опубликованный URL.
  2. Сохраните HTTP-ответ и проверьте canonical в head: полный href, число тегов и заголовок ответа Link, если он задаёт дополнительный canonical.
  3. В инструментах разработчика браузера проверьте итоговый документ. Выражение ниже перечисляет теги и их расположение. Расхождение HTML и DOM требует отдельного разбора.
  4. Повторите проверку после изменения. Возьмите карточки, вложенные пути и переводы, а не только главную. Рядом с каждым результатом сохраните фактический и ожидаемый адрес.
Array.from(document.querySelectorAll('link[rel="canonical"]'))
  .map(link => ({
    href: link.getAttribute("href"),
    inHead: link.closest("head") !== null
  }));

C08 проверяет значение переменной, а не инфраструктуру Vercel. Управление индексацией preview — отдельная задача: Vercel описывает стандартный noindex для preview и исключение для собственных доменов на непроизводственных ветках. Для вывода о хостинге проверьте реальные заголовки размещённой версии.

Чего эксперимент не показывает

Результаты относятся к одной установленной версии, статическим экспортам метаданных и локальному production-серверу. Мы не проверяли streaming metadata, Pages Router и все платформы размещения. Совпадение canonical с заданным адресом не доказывает, что Google выберет его, проиндексирует страницу или повысит позиции. Google описывает канонизацию как процесс с несколькими сигналами; выбранный им URL проверяйте отдельно в Search Console при наличии доступа.

Данные, стенд и повторение эксперимента

Дополнительное повторение 13 октября 2026 года: точную архивную копию стенда зафиксировали Git-коммитом перед новой сборкой. Все 32 HTTP-наблюдения canonical и 16 проверок DOM совпали с исходными результатами. Отдельно датированные доказательства включены в архив; исследование от 4 октября сохранено без изменений.

В комплекте — зафиксированный протокол, хеши исходников, результаты и запускаемый стенд. Скрипт собирает HTTP-ответы; проверка браузера описана отдельным шагом. Прямые зависимости закреплены, но все транзитивные зависимости отдельного пакета полностью не зафиксированы.

Если проблема затрагивает несколько шаблонов

Передайте разработчику конкретную запись: URL страницы, выданный canonical, нужный адрес, ответственную настройку и повторную проверку. Если задействованы layout, переводы и окружения размещения, наш SEO-аудит Next.js поможет составить карту зависимостей и очередь внедрения.

Если метаданные оказались в body, наш эксперимент с девятью условиями Next.js поможет разделить исходный HTML и DOM, а также проверить положение canonical с учётом требований Google.

частые вопросы

Коротко о главном

Заменяет ли metadataBase абсолютный canonical?

В сценарии C03 — нет. Старый абсолютный URL сохранился до изменения alternates.canonical. Проверьте поведение на своей установленной версии и фактическом ответе.

Почему вложенная страница указывает canonical на главную?

В C04 страница унаследовала значение из layout. Собственный canonical страницы изменил результат на нужный URL товара.

Семь исправленных сценариев означают, что ошибка есть у большинства сайтов?

Нет. Мы намеренно создали семь неверных конфигураций и одну контрольную. Эксперимент проверяет их поведение, а не распространённость ошибок или процент SEO-улучшения.