/ โ† Site Audit Fixes / Add a Canonical Tag
In this guide
  1. What a canonical tag is and what it does
  2. Canonical tag code and examples
  3. How to add a canonical tag in HTML
  4. How to add or fix the canonical URL in WordPress
  5. How to fix the canonical URL in Shopify
  6. How to check which canonical a page really outputs
  7. The fix, step by step
  8. Edge cases worth knowing
  9. Keeping canonicals correct
  10. Questions and answers

What a canonical tag is and what it does

A canonical tag is a <link> element with rel="canonical" placed in the <head> of a page. It names the preferred address for the content on that page. When Google finds several URLs showing the same or nearly the same content, it groups them together, picks one to index and show in results, and folds the signals from the others into it. Your canonical tag is your vote in that choice.

It is a strong hint, not an order. Google also weighs redirects, internal links, the sitemap, hreflang and whether the pages are truly duplicates. If your tag disagrees with everything else, Google may pick a different URL, and Search Console will say so. That is why adding the tag is only half the job; the other half is making the rest of the site agree with it.

There are two kinds of canonical you will use:

A canonical tag is not a way to merge two different pages, and it does not hide a page from visitors. If an old page should never be visited again, a 301 redirect is the honest answer. The canonical fixes guide covers how canonicals fit alongside redirects and noindex.

Canonical tag code and examples

The tag itself is short. This is a self-referencing canonical for a service page:

<link rel="canonical" href="https://www.example.com/services/wedding-cakes/">

And this is a cross-page canonical on a filtered listing that should consolidate into the main category:

<!-- On https://www.example.com/cakes/?sort=price&flavour=lemon -->
<link rel="canonical" href="https://www.example.com/cakes/">

Five rules make the difference between a tag Google trusts and one it ignores:

RuleRightWrong
Use the full absolute addresshttps://www.example.com/cakes//cakes/ or cakes/
Match your live protocol and hosthttps and the host you actually servehttp, or www when the site redirects to non-www
Point to a page that returns 200A live, indexable pageA redirect, a 404 or a page with noindex
One canonical per pageA single tag in the headTheme and plugin both printing one
Put it in the headInside <head> in the served HTMLIn the body, or only added later by a script

Relative addresses are allowed by the HTML specification, but they break easily when a page is copied, proxied or served on a staging host, so absolute addresses are the safer habit. Keep the trailing slash consistent with how your server actually answers, because /cakes and /cakes/ are different URLs.

Canonicals for files that are not HTML

A PDF cannot carry a head element, so you send the canonical as an HTTP response header instead. Google supports this for web search:

Link: <https://www.example.com/guides/cake-care.html>; rel="canonical"

How to add a canonical tag in HTML

On a hand-built or static site, open the template or each page file and add the tag inside the head, near the title and meta description:

<head>
  <meta charset="UTF-8">
  <title>Wedding Cakes in Leeds | Example Bakery</title>
  <meta name="description" content="Tiered wedding cakes baked to order.">
  <link rel="canonical" href="https://www.example.com/services/wedding-cakes/">
</head>

If you use a static site generator or a shared header include, add it once in the layout and build the address from the page's own path, so every page gets its own value. A common mistake is pasting the home page address into a shared header, which tells Google that every page is a copy of the home page. Pages then drop out of the index one by one.

For a server-side template, the pattern is the same: print the site's base address plus the clean path, without query strings. In PHP that might look like this:

<?php
$path = strtok($_SERVER['REQUEST_URI'], '?');
$canonical = 'https://www.example.com' . $path;
?>
<link rel="canonical" href="<?= htmlspecialchars($canonical) ?>">

That strips every parameter, which is right for tracking codes but wrong if a parameter genuinely changes the content, such as ?page=2 on a listing. Keep those parameters in the canonical, so page 2 points to page 2. The pagination guide explains why paginated pages should not all point to page 1.

โš ๏ธ Adding a canonical with JavaScript after the page loads is risky. Google may render it, but other search engines and AI crawlers often read only the raw HTML. Put the tag in the HTML the server sends.

How to add or fix the canonical URL in WordPress

WordPress core already prints a self-referencing canonical on single posts and pages through its rel_canonical() function. SEO plugins replace that output with their own and extend it to archives, categories and the home page. So on most WordPress sites you are not adding a canonical; you are checking and correcting the one the plugin prints.

Yoast SEO

Edit the post or page, open the Yoast SEO panel, choose the Advanced section and fill in Canonical URL. Leave it empty for a normal self-referencing canonical; only enter an address when this page is a duplicate of another. For template-wide changes, developers can use the wpseo_canonical filter:

add_filter( 'wpseo_canonical', function ( $url ) {
    if ( is_page( 'cake-menu-print' ) ) {
        return home_url( '/cake-menu/' );
    }
    return $url;
} );

Rank Math

Edit the post, open the Rank Math panel, go to the Advanced tab and use the Canonical URL field. The matching developer filter is rank_math/frontend/canonical.

Common WordPress canonical faults

How to fix the canonical URL in Shopify

Shopify themes print the canonical from the Liquid canonical_url object, normally in layout/theme.liquid. Open Online Store, then Themes, then Edit code, and search the layout for canonical. You should find one line like this:

<link rel="canonical" href="{{ canonical_url }}">

Shopify handles the common duplicates for you. A product reached through a collection, such as /collections/cakes/products/lemon-drizzle, gets a canonical to /products/lemon-drizzle. Leave that behaviour alone; it is correct.

The faults that do happen on Shopify are usually these:

Product and collection duplicates go deeper than the tag; the duplicate products guide covers variants, near-identical products and filtered collections.

How to check which canonical a page really outputs

The settings screen tells you what you asked for. The served HTML tells you what Google receives. Always check the second. From a terminal, fetch the page and pull out the tag:

curl -sL https://www.example.com/services/wedding-cakes/ | grep -io '<link[^>]*canonical[^>]*>'

More than one line in the result means more than one canonical. To check for a canonical sent as an HTTP header, look at the response headers:

curl -sI https://www.example.com/files/cake-care.pdf | grep -i '^link:'

In the browser, open Chrome DevTools, go to the Console and run:

[...document.querySelectorAll('link[rel="canonical"]')].map(l => l.href)

This shows the rendered page, after scripts have run. If curl shows one value and DevTools shows another, a script is rewriting the tag, and you should fix it at the source.

What Google decided

In Google Search Console, paste the address into URL Inspection and open the page indexing details. You will see the User-declared canonical, which is your tag, and the Google-selected canonical. When they match, you are done. When they differ, Google has overruled you, usually because internal links, the sitemap or a redirect point elsewhere, or because the content is a near-duplicate of another page. The canonical conflicts guide walks through that case.

Checking the whole website

To check a website for canonical tags at scale, run a crawl with the site crawler and sort pages by canonical status: missing, self-referencing, pointing elsewhere, pointing to a redirect or a 404, and pages with more than one tag. That list is your work queue.

The fix, step by step

Step 1

Decide the canonical address for each page

List your page types and write down the one address each page should be known by: https, your chosen host, the clean path and your usual trailing slash. Decide which pages are true duplicates, such as print versions, sorted listings or tracking links, and which page each should point to. Confirm each chosen address returns 200 by running curl -sI on it and reading the status line. You are finished when every template has a rule for its canonical address.

Step 2

Remove duplicate sources of the tag

Before adding anything, find every place that can print a canonical: the theme header, an SEO plugin, a Shopify app, a page builder or a CDN worker. Run curl -sL on a sample page and grep for canonical. If more than one tag appears, switch off all but one source. In WordPress keep the SEO plugin and remove any theme copy; in Shopify keep the theme line or the app, never both. Re-run the check until only one tag appears.

Step 3

Add the tag to the template head

Add a single <link rel="canonical"> inside the head of the shared layout, built from the page's own path rather than a fixed address. In plain HTML put it next to the title tag. In Shopify confirm theme.liquid contains {{ canonical_url }}. In WordPress leave the plugin's automatic canonical switched on. Save, purge any page cache, then fetch two different pages with curl and confirm each shows its own address.

Step 4

Set cross-page canonicals on true duplicates

For each real duplicate, point the canonical at the main page. In Yoast or Rank Math use the Canonical URL field in the Advanced section of that post. In custom code, map the duplicate path to the main address in the template. Do not do this for pages with distinct content. Fetch each changed page and confirm the tag now names the main page, and that the main page still names itself.

Step 5

Align redirects, links and sitemap

Make the other signals agree with your tags. Check that http and non-preferred host versions 301 redirect to the canonical address. Update menus and internal links that use parameter or old addresses. Regenerate the XML sitemap so it lists only canonical URLs that return 200. Spot check with curl -sI http://example.com/ and follow the Location header until it lands on the canonical address with a 200 status.

Step 6

Check the output across the site

Crawl the whole site and export each page's canonical. Filter for pages with no canonical, more than one canonical, a canonical that points to a redirect or 404, and a canonical that points to a different page unexpectedly. Fix each group at its template, not page by page. Run the crawl again after fixing. You are done when every indexable page either names itself or names a deliberate main page.

Step 7

Inspect key pages in Search Console

Open URL Inspection in Google Search Console for your most important pages, one per template. Run the live test to confirm Google can see the new tag in the rendered HTML. Then read the indexed result for the User-declared canonical and the Google-selected canonical. Where they now match, request indexing if the page is new or changed. Where they still differ, look for duplicate content or conflicting internal links.

Step 8

Monitor the indexing report

Over the next few weeks, watch the Page indexing report in Search Console. Duplicate and alternate page counts should settle to the URLs you expect, such as parameter and filtered addresses, while your main pages move into the indexed group. Google recrawls at its own pace, so allow days to weeks. If an important page stays under a duplicate reason, inspect it again and compare its content with the page Google chose.

Edge cases worth knowing

Keeping canonicals correct

Canonicals break quietly. A theme update, a new plugin, a domain move or a caching layer can change every tag on the site at once, and nothing looks wrong to visitors. Build three habits:

  1. Check after every template change. After a theme update, a plugin install or a new page builder, run the curl check on one page of each template: home, category, product or post, and a static page.
  2. Crawl monthly. A scheduled crawl catches missing, duplicated and wrong canonicals before Google acts on them. Compare the count of self-referencing pages against last month.
  3. Keep signals aligned. Your sitemap should list only canonical addresses, menus should link to canonical addresses, and redirects should end on canonical addresses. When all four agree, Google almost always follows your tag.
๐Ÿ’ก Watch the Search Console page indexing report for the reasons about duplicates and alternate pages. A sudden rise in either usually means a template started printing the wrong canonical.
Questions and answers

1. How do I add a canonical tag to a page?

Add a single link element with rel set to canonical and the page's full address as href inside the head section of the HTML. On most sites you do this once in the shared template so every page outputs its own address, rather than editing pages one by one. WordPress SEO plugins and Shopify themes already print one, so on those platforms you normally check and correct the existing tag. After adding it, fetch the page with curl or view the source to confirm exactly one canonical appears with the right address.

2. What is an example of a canonical tag?

A typical self-referencing canonical looks like a link element with rel equal to canonical and an href of https://www.example.com/services/wedding-cakes/, placed in the head of that same page. A cross-page example is a filtered listing such as /cakes/?sort=price pointing its canonical at https://www.example.com/cakes/. Both use the full absolute address, the live https protocol and the same host the site redirects to. The code examples on this page show both forms ready to copy and adapt to your own addresses.

3. How do I add a canonical tag in WordPress?

WordPress already outputs a self-referencing canonical on posts and pages, and SEO plugins such as Yoast and Rank Math take over and extend it. To set a different canonical on one page, edit it, open the plugin panel, go to the Advanced section and enter the address in the Canonical URL field. Leave the field empty for the normal self-referencing tag. Then check the live page source, because a theme or second plugin can print a duplicate tag that confuses search engines.

4. How do I fix the canonical URL in Shopify?

Open the theme code editor, find layout/theme.liquid and make sure the head contains one canonical line that uses the canonical_url Liquid object rather than a fixed address. Shopify then sets sensible canonicals for products reached through collections. If an SEO app also adds a canonical, turn off one of them so only a single tag remains. Also confirm the primary domain in the store settings is the one you want indexed, because canonicals follow it.

5. How can I check a website for canonical tags?

For one page, view the page source and search for canonical, or run curl on the address and grep the output, which shows exactly what the server sends. In Search Console, URL Inspection shows both your declared canonical and the one Google selected. For a whole website, run a crawl that records the canonical of every page, then filter for pages with none, more than one, or a canonical pointing at a redirect, a 404 or an unexpected page.

6. Should every page have a self-referencing canonical?

Yes, every page you want indexed should normally carry a canonical pointing to its own clean address. It costs nothing and protects the page when people link to it with tracking parameters, mixed case or other variations, because those copies then consolidate into the main address. Google does not require it, and pages can be indexed without one, but a self-referencing tag removes guesswork. Pages you do not want indexed at all are better handled with noindex than with a canonical.

7. Why is Google ignoring my canonical tag?

Google treats the canonical as a strong hint, so it can overrule it when other signals disagree. The usual reasons are internal links or the sitemap pointing to a different version, redirects that land somewhere else, two canonical tags on the page, a canonical to a page that redirects or returns an error, or content that is not really a duplicate. Fix the conflicting signals, confirm a single correct tag in the served HTML, then request indexing and give Google time to recrawl.

Check every canonical tag on your site

The site audit crawls your pages and flags missing, duplicated and conflicting canonical tags, including canonicals that point to redirects or errors, so you can fix them template by template.

Open Site Audit Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Site Audit Fixes  ·  Fixing canonical tags  ·  Canonical conflicts  ·  Alternate page with proper canonical tag  ·  Duplicate content  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.