Skip to content
pageinspection

Missing canonical tags: what it means and how to fix it

A page with no rel="canonical" is not broken, and that is the problem: it works perfectly while quietly letting a search engine decide which of your URLs is the real one. Usually it decides correctly. When it does not, the version it picks is the version that ranks.

The short answer

A canonical tag tells search engines which URL is the real one when several serve the same content. Without it, the engine picks for you, and it often picks a tracking-parameter URL or a paginated variant over the page you meant. Every indexable page should declare a self-referencing canonical with an absolute URL.

CriticalAudit check · Canonical tags

What this check looks for

One <link rel="canonical"> in the <head> of every indexable page, holding an absolute URL that resolves with a 200. That is the whole pass condition. The check fires when the element is absent, when there are two of them with different values, or when the value is empty.

It does not fire merely because a canonical points at a different URL. A page declaring another page as canonical is the entire purpose of the tag, and a printer-friendly view or a syndicated copy is supposed to do exactly that. What matters is whether the declaration is deliberate.

Why a missing canonical costs you rankings

Almost every site serves the same page at more than one URL without meaning to. A tracking parameter from a newsletter, a trailing slash your router tolerates, an uppercase path someone linked to, a session id, an ?page=1 that renders the same thing as no parameter at all. Each of those is a separate URL to a crawler, and a separate candidate for indexing.

When nothing declares which one is preferred, the engine clusters them itself and picks a representative. Inbound links, internal links and engagement that should have accumulated on one URL are spread across the cluster instead, and the URL that surfaces may be the one with the tracking parameter still attached.

Two panels. Without a canonical tag, the three URLs /widget, /widget/ and /widget?utm_source=ig each become their own index candidate, and the page's ranking signals are split three ways. With a self-referencing canonical, all three resolve to one canonical URL and the signals stay consolidated.Without a canonicalthree URLs, three index candidates/widgetits own index candidate/widget/its own index candidate/widget?utm_source=igits own index candidatesplit three waysWith a self-referencing canonicalthree URLs, one index candidate/widget/widget//widget?utm_source=igone canonical URLconsolidated
The same page reached three ways. The tag does not create the duplicates, it tells the crawler which of them to keep.

How PageInspection detects it

The crawler fetches each page in a real headless browser and reads the <head> after render, so a canonical injected by JavaScript is seen the same way a browser sees it. That matters more than it sounds: a canonical added client-side by a tag manager exists for a browser and frequently does not exist for the crawler that never runs the script.

The value is then resolved against the page's own URL, hash removed, trailing slash normalised, so a relative canonical and an absolute one that mean the same thing are compared as equal. What gets reported is the raw value we found, not the normalised one, because the raw value is what you have to go and edit.

Check a page for its canonical

Paste a URL and this runs a single-page audit, then reports one thing: what that page declares as its canonical, and whether it matches the URL that declared it.

Check one page for its canonical tag

No signup required. Each free search audits one page, paste any URL to see it in action.

Why one missing tag is rated Critical

Severity here is about how much of the site a single defect reaches, not how alarming it sounds. Canonicals are emitted by a layout or a head partial, so when they are missing they are missing everywhere at once, and the damage compounds: every inbound link to a parameterised variant lands on a URL that will never consolidate.

It is also silent. Nothing in your analytics, your CMS or your build output reports it, and the page looks correct to everyone who visits. Compare that with a missing meta description, which is rated Important because it costs you control of one snippet on one page and is obvious the moment you look. The full scale is defined on the audit page.

How to fix it

Fix it in the template that renders your head, never page by page. The correct value is the page's own absolute URL, stripped of tracking parameters, with whatever trailing slash convention your router actually serves.

before.html
<head>
  <title>Widget</title>
  <meta name="description" content="Our widget.">
  <!-- no canonical: /widget, /widget/ and
       /widget?utm_source=ig are three candidates -->
</head>
after.html
<head>
  <title>Widget</title>
  <meta name="description" content="Our widget.">
  <link rel="canonical" href="https://example.com/widget">
  <meta property="og:url" content="https://example.com/widget">
</head>

The og:url line is not decoration. Social scrapers and several AI crawlers read it in preference to the canonical, and when the two disagree you have published two different answers to the same question.

In Next.js App Router, this is metadata, not markup:

app/widget/page.tsx
import type { Metadata } from 'next'

// metadataBase makes the relative path below absolute in the
// rendered tag, so the canonical is declared in one place per
// route and resolved in one place per app.
export const metadata: Metadata = {
  alternates: { canonical: '/widget' },
  openGraph: { url: '/widget' },
}

A dynamic route does the same thing from generateMetadata, building the path from the resolved slug rather than from the incoming URL. Reading the request URL is the mistake to avoid: it carries the parameters you are trying to canonicalise away.

Where it usually goes wrong, by platform

WordPress
Yoast and Rank Math both emit a self-referencing canonical by default, so a missing tag here almost always means a theme printing its own <head> without calling wp_head(), or a second SEO plugin fighting the first. Two plugins active at once is the classic cause of two conflicting canonicals on one page.
Shopify
The stock themes emit a canonical, but collection filtering and sort parameters generate a large number of URL variants, and products reachable through more than one collection path historically produced duplicate paths. Check a filtered collection URL rather than the homepage, which is where this looks fine on almost every store.
Webflow
Canonicals are set per page in page settings and are easy to leave blank on pages cloned from a template, since the clone copies the layout and not always the setting. Collection pages inherit from the template, so one blank field there covers every item.
Plain HTML and static sites
Nothing emits a canonical unless you write it, and a hand-written one is the most likely to be copy-pasted between files with the previous page's path left in it. A wrong canonical is worse than none, because it actively points the crawler away.

When this check fires and the page is fine

Three situations look like failures and are not, and it is worth knowing them before you open a ticket.

  • Paginated archives. Page two of a listing should canonicalise to itself, not to page one. Pointing every page of a series at the first one tells the engine the later pages do not exist, and the products or posts only reachable from page four go with them.
  • Deliberate cross-domain canonicals. A syndicated article pointing at the original publisher is the tag working as designed. Our report shows the target so you can confirm the direction is the one you intended.
  • Pages you never wanted indexed in the first place. A cart, a search results page or a filtered view does not need a canonical argument at all. Those want a robots directive, and mixing the two on one page is the overcorrection below.

The wrong fix, which is common

Do not canonicalise everything to the homepage, and do not pair a canonical with a noindex on the same URL.

Both are attempts to use the tag as a blunt instrument for keeping pages out of the index, and both misfire. A canonical is a hint about which of several near-identical URLs to prefer; pointed at a page with different content it is simply ignored, and you have spent the signal for nothing. Combined with a noindex it is actively contradictory: one element says consolidate the signals into this URL, the other says drop this URL, and which instruction wins is not something you control.

Confirming the fix landed

View source on the fixed page rather than trusting the CMS preview, and confirm there is exactly one canonical element. Then request the URL with a tracking parameter appended and confirm the canonical still reads as the clean path. That second step is the one people skip, and it is the one that catches a canonical built from the request URL.

Then re-crawl. The check flips to passing and the affected-pages count for it drops to zero, which is the difference between having fixed it and believing you have. Re-crawling also catches the regression case, where a later deploy reintroduces a head partial that does not include the tag.

Questions this check raises

Should a page canonicalise to itself?
Yes. A self-referencing canonical is the normal case and it costs nothing: it states which URL you consider primary before any parameter, protocol or trailing-slash variant of the page exists. Without one, the first campaign link with a UTM parameter creates a second URL with no stated preference between them.
Is a canonical tag the same as a redirect?
No. A redirect removes the duplicate and sends everyone to one URL; a canonical leaves both reachable and expresses a preference the engine may or may not follow. Use a redirect when the other URL should not exist, and a canonical when it should stay reachable for people while consolidating signals onto one address.
Can a canonical tag point to a different page?
It can, and that is the correct move for a genuine duplicate such as a syndicated copy or a print view. It is a mistake when the two pages differ: canonicalising every product variant to a category page tells the engine the variant does not need indexing, and it will comply.