Canonical Checker

See which canonical URL a live page actually serves, and whether the rest of its head agrees.

Secure server processingWeb & SEOWorkingNo account needed

What this tool does

Canonical Checker asks the OmniKitly processing service to request a page and reads the rel="canonical" link out of the HTML that comes back. A canonical is how a site nominates one address as the keeper when the same content sits at several — with and without a trailing slash, with a tracking parameter, under a second category path — so the value that decides a duplicate content question is not the one the template was written to emit, but the one the server served at the address you asked for.

Every canonical link in the head is counted, not only the first, and each one is printed twice: the value as written and the value it resolves to, next to the address the fetch landed on, the og:url and the robots directive from that same response. Findings sit underneath — two canonicals disagreeing, an empty href, a canonical on http, one carrying utm_ or gclid parameters, a #fragment, a noindex sitting beside a canonical, an og:url naming somewhere else — because a consolidation problem is usually a disagreement between those signals rather than one absent tag. Hreflang alternates are counted too, with a note when x-default is missing.

What the reading cannot reach matters as much. Only the source down to the closing </head> comes back from the fetch, so a canonical injected by JavaScript or a tag manager has not run yet, and one written after </head> by a plugin falls outside the slice; a canonical carried in an HTTP Link header is not covered, because response headers are not part of this fetch; and the canonical target is never requested, so whether it answers 200, redirects onward or declares a different canonical of its own is left untested. The head is read with a regular-expression parser rather than a browser DOM, which means attribute order is irrelevant — a link written href first is read like any other — but also that a tag sitting inside a script string or a template is counted as though it were live.

The fetch happens on the service and not in this tab, because a browser cannot read another domain's HTML across origins. It goes out as OmniKitly/1.0 with no cookies and no sign-in, so a site that varies its head by user agent, or refuses agents it does not recognise, can answer this check differently from the browser you are reading it in, and a page behind a login returns whatever an anonymous visitor gets. The address you enter travels there over an encrypted connection and is stored with the job record, which is deleted along with the report when the job expires — six hours after it ran, unless an administrator has changed the retention setting.

How to use it

  1. Enter the page address. A full https:// URL for the exact page in question, path and query included. Only http and https are accepted, and the service issues the request itself, so the page has to be reachable from the public internet.
  2. Run the check. Each redirect is followed one hop at a time and re-checked against the blocked ranges, up to five hops, and the first 512 KB of the response is read. Any single request that has gone fifteen seconds without an answer is abandoned.
  3. Read the canonical beside the address that was fetched. Both appear in the table, declared and resolved, and the check states whether they match. A difference of only a trailing slash or a capital letter is called out by name, since that is the classic way a page ends up canonicalised to a URL that redirects back to it.
  4. Use “URL of this page” to change what it is compared with. Left empty, the canonical is measured against the final URL the fetch landed on. Type an address into that setting and the comparison — and the resolving of any relative canonical — is done against yours instead, which is how you test whether a variant folds into the page you expect.
  5. Keep the evidence. The report renders in the output pane, and the raw fetch downloads as meta.json with the head source, HTTP status, page title, description and Twitter values that the on-screen table leaves out. Diffing two of those after a template change is straightforward.

Processing & privacy

Secure server processing. This operation requires temporary server processing.

Common use cases

A URL variant that keeps getting indexed

Parameter, paginated and tagged copies are indexed separately when the canonical is missing or when each variant points at itself. Reading the live address settles which of the two is happening.

After a migration or a change of slug

Templates often go on emitting the previous address. Fetching the new URL shows whether the canonical moved with the page or is still folding it into a URL that now redirects.

One page type a CMS plugin skipped

Canonical tags written by a theme or an SEO plugin can be complete on posts and absent on archives. This reads the specific address rather than the rule meant to have produced it.

Settling a duplicate content argument

Two people looking at the same page in different tools disagree less when the canonical, the final URL, the robots meta and og:url are printed together from a single request.

Questions

Where does the URL I enter go?
To the processing service, and nowhere else — the address is sent, not a file. The check has to run on the OmniKitly service because a browser cannot fetch another domain's HTML from this page, so the URL travels there over an encrypted connection, sits in the job record while the job exists, and goes with the report when the job expires — six hours later by default.
It reports no canonical, but I can see the tag in my source
Attribute order is not the reason: <link href="…" rel="canonical"> is read exactly like the usual spelling. What does hide a tag is JavaScript, which never runs here; a position after </head>, which is outside the source the fetch returns; or a page that answered 400 or worse, in which case the raw JSON is shown instead of the report.
What happens when a page declares two canonicals?
Both are listed, and the count is reported as an error rather than quietly resolved, because search engines faced with canonicals that disagree discard the pair and treat the page as its own. The first value is still the one used for the comparisons under it.
Does it confirm the canonical URL actually works?
No. The target is never requested, so a canonical aimed at a 404, at a redirect, or at a page declaring a canonical of its own is reported exactly as written. Redirect Checker follows a chain if that is the part you need.
What about a canonical sent in an HTTP header?
It is not read here. This report covers the HTML only and does not include response headers, so a Link header carrying rel="canonical" goes unseen — HTTP Header Inspector is where the response headers are listed.
Should the canonical be absolute or relative?
Absolute, with scheme and host, is the safer form, and a relative one is flagged as a warning here. It is still resolved for you — against the URL of this page, or against a <base> element when the head declares one — and the declared and resolved values are printed side by side so you can see what it points at in practice.
Can I paste the page's HTML instead of a URL?
Not today, though the input box and its sample button still invite it. Everything typed there is handed to the service as an address to request, so markup comes back rejected as an invalid URL. Meta Tag Preview reads a pasted head in the browser when that is all you have.
Can I check a staging site?
Only where it is publicly reachable over http or https. Loopback, private and link-local ranges, and .local, .internal, .lan or .home hostnames, are refused before any connection is made — including when a public name resolves to one, and again at every redirect hop.

Related tools