All lintlab tools

Canonical Tag Checker

What it does

Check the canonical tag on every page of a site in one run, not one URL at a time. Give it a homepage or an XML sitemap. For each page it reads the <link rel="canonical"> tag from the server-delivered HTML, resolves it, fetches the target, and tells you what's wrong and how to fix it. The same run also checks titles, descriptions, headings, robots directives and internal links.

Open the Actor on Apify

What it flags

CheckSeverityWhen
canonical.missingwarningNo canonical tag, or an empty one
canonical.relativewarningWritten as a relative URL instead of an absolute one
canonical.elsewherewarningResolves to a different URL than the page itself
canonical.malformederrorCan't be parsed as a URL
canonical.non_200errorThe target doesn't return HTTP 200, or can't be fetched

A canonical that points elsewhere is sometimes intended, for example on a filtered or paginated URL. The check shows you where it happens so you can confirm it.

Input and output from a real run

We set up five demo pages on this site, each with one canonical fault (or none), and ran the Actor on them on Apify on 2026-09-30 (run atMJfdP6XdeAkvgJz). It found each fault: the correct page came back clean, the other four got the finding shown in the table above.

Input JSON

{
  "startUrls": [
    { "url": "https://lintlab.dev/demo/canonical/ok/" },
    { "url": "https://lintlab.dev/demo/canonical/relative/" },
    { "url": "https://lintlab.dev/demo/canonical/elsewhere/" },
    { "url": "https://lintlab.dev/demo/canonical/gone/" },
    { "url": "https://lintlab.dev/demo/canonical/missing/" }
  ],
  "discoverSitemap": false,
  "maxPages": 5,
  "checkLinks": false
}

For a whole site, give only the homepage and leave discoverSitemap on: the Actor finds the sitemap through robots.txt or /sitemap.xml.

Output excerpt: the page whose canonical target is gone

{
  "url": "https://lintlab.dev/demo/canonical/gone/",
  "status": 200,
  "canonical": "https://lintlab.dev/demo/canonical/old-page/",
  "findings": [
    {
      "checkId": "canonical.elsewhere",
      "severity": "warning",
      "message": "The canonical points to another URL.",
      "fix": "Verify that consolidation to the canonical target is intentional.",
      "value": "https://lintlab.dev/demo/canonical/old-page/"
    },
    {
      "checkId": "canonical.non_200",
      "severity": "error",
      "message": "The canonical target returned HTTP 404.",
      "fix": "Make the canonical target return HTTP 200.",
      "value": 404
    }
  ]
}

Run summary excerpt

{
  "pagesAudited": 5,
  "counts": { "error": 1, "warning": 4, "notice": 0 },
  "topIssues": [
    { "checkId": "canonical.elsewhere", "count": 2 },
    { "checkId": "canonical.missing", "count": 1 },
    { "checkId": "canonical.non_200", "count": 1 },
    { "checkId": "canonical.relative", "count": 1 }
  ]
}

Price and limits

$0.004 per successfully audited page ($4 per 1,000 pages). Canonical target fetches and internal link checks aren't charged. Pages that fail or return an error status are reported but not charged.

  • Up to 5,000 pages per run.
  • Reads the HTML the server sends. It doesn't run JavaScript, so a canonical tag added only by client-side script won't be seen.
  • Doesn't read canonicals sent in the HTTP Link header.
  • For sites you own or are allowed to audit.

When a free tool is better

For a few URLs on a site you've verified, use the URL Inspection tool in Google Search Console. It's free and shows both the canonical you declared and the one Google chose. This Actor is for checking every page of a site at once, any public site, without verification, with JSON you can diff between runs or check in CI. URL Inspection tool documentation · Google's guide to canonical URLs.