Перейти к основному содержимому

Руководства / Починка: руководства по ошибкам, которые встречаются на практике

Fix a canonical URL pointing to staging

A canonical pointing at staging is almost always a base-URL config value that traveled with a release or a database copy; fix the value for the production environment, or build the canonical from the request host instead of a stored constant. The live pages keep returning 200 the whole time, which is why this is usually found in a traffic graph rather than in an alert.

What the symptom looks like

Every page on the live site serves a canonical naming a different host:

curl -s https://example.com/pricing | grep -i 'rel="canonical"'
<link rel="canonical" href="https://staging.example.com/pricing">

Search Console shows it as "Duplicate, Google chose different canonical than user", or as pages dropping out with a user-declared canonical on a host you never verified. Because the staging host is normally unreachable, password-protected or noindexed, there is no destination for the consolidation to land on, so the live pages simply stop ranking one recrawl at a time. Nothing 500s and no uptime check notices, which is what makes it expensive.

Where the wrong base URL comes from

  • A database restored from staging. In WordPress the siteurl and home option rows carry the staging hostname into production, and every generated URL follows them.
  • An environment variable in the deployed build. A site URL baked in at build time, so the compiled output carries staging's value no matter what the runtime environment says.
  • A framework default host configured per environment, where the production config was never updated after the staging one was.
  • A hardcoded absolute URL in a shared layout or SEO plugin setting, written during a migration and never revisited.
  • A cached page built on the wrong host. A CDN or full-page cache populated by a staging build serves stale HTML with the staging canonical long after the config was corrected.

Fix the value, then remove the class of bug

  1. Correct the stored base URL for production, in whichever of the places above applies. In WordPress that is the two option rows plus any absolute URLs written into post content by the staging copy.
  2. Rebuild and redeploy if the value is compiled in. Changing an environment variable without a rebuild leaves the old value in the shipped bundle.
  3. Purge every cache in the path, application, CDN and edge alike. A corrected origin behind a cache full of staging HTML looks unfixed for as long as the cache lives.
  4. Prefer deriving the canonical from the request host over reading a stored constant. A canonical built from the host that served the request cannot be wrong in the environment it was served from, which removes the whole class of failure rather than this instance of it.
  5. Keep staging out of the index by other means. HTTP authentication or an IP allowlist on the staging host is what should be protecting it, not a canonical, and not a noindex that can travel with a config file.

Verify the fix on production

Read the response, not the template, because plugins, edge workers and caches all inject canonicals that do not appear in your repository:

curl -s https://example.com/pricing | grep -i 'rel="canonical"'
curl -sI https://example.com/pricing | grep -i '^link:'

Then check more than one page. The canonical is generated by a template, so getting the homepage right proves nothing about product pages, paginated listings or anything rendered by a different layout. In Search Console, URL Inspection shows the user-declared canonical next to the one Google selected, and the two agreeing after a recrawl is the confirmation that matters. That recrawl takes days, so a corrected canonical does not restore traffic the same afternoon.

Prevent it from shipping again

Two safeguards cost almost nothing. The first is a deploy-time assertion: after a release, fetch a handful of production URLs and fail the deploy if any canonical names a host other than the production one. The second is to keep watching afterwards, because the failure is just as likely to arrive with a database restore or a plugin setting as with a code deploy. HostTracker's HTTP checks can assert against the response body and headers, so a scheduled check can be made to fail when the canonical tag on a page is not what you expect, and that failure alerts like any other.

Check every template, not one page

The fastest way to see whether a canonical problem is one page or one layout is to look at all of them at once. The free site crawl tool walks the site and reports a canonical status per URL, marking the pages where it is missing and the pages where it points at a different address than the page itself, alongside the noindex flags and duplicate bodies that usually accompany a bad deploy. Keeping that under continuous watch, next to uptime, certificates and domain expiry, is what a website monitoring service is for.

Проверить сейчас

Запустите бесплатную проверку своего сайта - аккаунт не нужен.

Crawl site

Следить за этим постоянно

Получайте оповещение в момент сбоя: HostTracker проверяет более чем из 300 локаций и уведомляет по email, SMS, в Slack, Telegram и не только.

Возможности HostTracker

Ещё в этом разделе: Починка: руководства по ошибкам, которые встречаются на практике