Start a project

Article · Technical SEO · Canonicals · Duplicate URLs · 12 min read

Canonical tags, trailing slashes and duplicate URLs

A duplicate URL, to a crawler, is two addresses that return substantially the same page. On a small site they usually come from a mix of http and https, www and the bare host, a trailing slash, capital letters, or query parameters. The fix is not a plugin and a hope: pick one URL shape, redirect the others to it, and put an honest, self-referencing canonical on the URL you kept. If the redirect and the canonical disagree, you have not made a choice, you have made a conflict.

On this page 10 sections
  1. What ‘duplicate’ actually means to a crawler
  2. The usual sources: scheme, host, slash, case and parameters
  3. Pick one URL shape and stick to it
  4. Redirects, then the canonical tag, in that order
  5. Self-referencing canonicals, and when not to point away
  6. Pagination, filters and parameters
  7. How to find conflicts on a real site
  8. A short policy you can write down
  9. Key takeaways
  10. Frequently asked questions

I have had to be strict about this on leej.uk, which is a small, static-ish site served from a Cloudflare Worker: one host, HTTPS, a consistent path shape, and a canonical on every public page. The method below is a URL policy you can write down, not a tour of a single tool. The canonical conflict finder and the URL normalisation tester are there to check the policy once it exists.

What ‘duplicate’ actually means to a crawler

Search engines try to group addresses that show the same content, and to pick one as the canonical. You can help or you can get in the way. Duplicates are not only copy-pasted blog posts; they are, much more often on a small site:

Google has said that they use several signals — redirects, the rel=canonical link, sitemaps, internal links — and that they may ignore a canonical you set if it is inconsistent or implausible. I treat that as a reason to be boring and consistent, not as a reason to try to “force” a URL with five conflicting signals.

Duplicates waste crawl budget (less of a problem on a fifty-page site than on a faceted shop, but still messy), they split signals, and they make it easy to share the wrong URL. They also confuse any assistant that is trying to cite “the” address of a page, which is why the same shape should appear in your sitemap, your llms.txt, and your internal links.

A page that is similar but genuinely aimed at a different user (a UK and a US version, a print view with different content) is not a duplicate you should canonicalise away without thought. A page that is the same article with a trailing slash is.

The usual sources: scheme, host, slash, case and parameters

Five families cause almost all of the trouble:

Scheme. The same path on HTTP and on HTTPS, for example example.com/about with each scheme. The redirect should be a single hop to HTTPS. HSTS is a complement, not a substitute for the redirect, because the first visit and non-browser clients still need a clear 301.

Host. www.example.com and example.com. Pick one. Either is fine; mixing them is not. The certificate, the DNS, the sitemap and the canonical all have to use the same host. A site that “works” on both, with no redirect, is two sites.

Trailing slash. /tools and /tools/ are different URLs. Servers and frameworks disagree about which is natural. Pick one policy for directory-like paths, and another, if you must, for files that look like sitemap.xml. Then redirect the other shape. Do not serve 200 on both with a canonical as the only hint if you can avoid it; the redirect is the stronger, clearer signal.

Case. /About and /about. Many servers are case-sensitive; some are not. Humans will type either. A lower-case policy, with a redirect from mixed case, is the usual choice for a public site that does not have a reason to be case-sensitive. When you mint a new path, use a deliberate slug, not a heading pasted with spaces and capitals.

Parameters. ?utm_source=, ?ref=, session IDs, sort order, ?page=1 on a URL that is already the first page, print views. Some parameters change the content; most marketing ones should not. The canonical of a purely tracked URL is the clean URL. The clean URL should not redirect in a loop when the parameter is present; it should 200, with a canonical (and, ideally, a parameter you do not need to index).

A sixth, quieter one: default documents, such as /about and /about/index.html, or a preview host that also serves the production content. If a second host must exist (a preview, a staging site), it should be noindex, preferably blocked from production search via robots or authentication, and it should not appear in the production sitemap.

Pick one URL shape and stick to it

Write the policy in one short block you can hand to a future you, or to a host configuration:

Every public URL you publish — in links, emails, sitemaps, llms.txt, App Store text, QR codes — should be in that shape. Internal links should never point at a URL you intend to redirect; they should point at the destination. That saves a hop and keeps crawlers from discovering the weak form first.

If you are building routes, generate them from one helper, not from a mix of hard-coded strings. The URL normalisation tester is a useful way to see how a candidate URL collapses under your rules before you ship it.

Changing the policy later is a migration. Treat it like one, with a map and 301s, as in the website migration SEO checklist. Do not flip the trailing-slash rule on a Tuesday because a new framework defaulted the other way.

Redirects, then the canonical tag, in that order

A redirect says “this address is not the resource; go there”. A canonical says “this address is the resource, and that other address is the preferred one if you somehow see both”. Use them in that order.

<link rel="canonical" href="https://example.com/tools/slug-generator">

Absolute HTTPS URLs in the canonical are the least ambiguous. A relative canonical is easier to get wrong when the page is served on more than one host. The href should be the URL you want in Search, not a parameterised version of itself, and not a typo.

Do not canonicalise a live page to a URL that 404s, that redirects again, or that you have noindexed, unless you have a very specific reason and you understand the conflict you are creating. Do not point every page at the homepage as a “hack”. That is not a canonical policy; it is a request to drop the pages.

Self-referencing canonicals, and when not to point away

Self-referencing canonicals look redundant, and they are useful. They tell a crawler that, even if it found this page with a tracking parameter or via a second host you failed to redirect, the preferred address is the one you named. They also make it obvious, in the HTML, which URL you think this is.

Point the canonical away only when the page you are serving is a true duplicate or a variant you do not want chosen: a printer-friendly copy, a syndicated copy you are allowed to publish but not to have indexed as original, a filtered list that is a subset of a canonical list. In those cases the canonical must be a 200 URL you control, or a URL the receiving site has agreed to, and the rest of your signals (sitemap, internal links) should agree.

Cross-domain canonicals exist, but they are a syndication tool, not a way to merge two websites you accidentally launched. If you are moving a site, redirects are the primary signal, as in the migration checklist; a canonical-only move is weaker and slower.

If you cannot decide whether two URLs are duplicates, do not point one at the other “just in case”. You may accidentally drop a useful, slightly different page. Decide, or leave them as two pages with their own self-canonicals and their own titles.

Pagination, filters and parameters

List pages are where small sites grow accidental duplicates.

If you are unsure whether a parameterised URL is being indexed, look in Search Console for the naked and the parameterised forms, and look at the canonical the live HTML declares. The conflict finder is built for that comparison.

How to find conflicts on a real site

A method that scales to a few hundred URLs, which is most of the sites I work on:

  1. List the shapes you think you support. Bare and www, slash and no slash, a sample parameter, HTTP if it still answers.
  2. Request them, and record the status, the final URL after redirects, and the canonical in the final HTML. The redirect chain tracer and the canonical conflict finder will do the mechanical part.
  3. Diff the sitemap against that list. Every sitemap URL should be a 200, in the chosen shape, self-canonical, and not a redirect. Every important 200 should be in the sitemap, or left out on purpose.
  4. Grep the HTML for internal links that still use the weak shape, including an HTTP scheme and the wrong host. Fix the links; do not rely on redirects for your own site.
  5. Check Search Console (the Page indexing and URL inspection reports, and a site: search if you must) for unexpected variants that are indexed or “crawled, not currently indexed”.

On this site I also refuse a deploy that would ship a page without a canonical, or with an ops host in a public link. You may not need that level of automation, but you do need the check to happen before a launch, not after a week of “why is this URL odd in the results”.

A short policy you can write down

Here is a complete, boring policy a small HTTPS site can adopt. Change the host and the slash rule to match your choice, then actually implement it.

If a new tool or framework wants a different default, the policy wins, or the policy is formally changed. The framework does not get to quietly serve both.

Key takeaways

If you want a second pair of eyes on a URL policy or a conflict report, tell me about it.

Frequently asked questions

What is a canonical tag in SEO?

A <link rel="canonical" href="…"> in the page head (or an equivalent X-Robots-Tag) that names the preferred URL for the content you are serving. It is a hint to search engines, strongest when it agrees with your redirects, sitemap and internal links. A self-referencing canonical names the page itself, in the shape you want indexed.

Should my URLs have a trailing slash?

Either policy is fine; serving both without a redirect is not. Pick one, redirect the other in a single hop, and put that chosen URL in the canonical, the sitemap and your links. Changing your mind later needs a 301 map, not a silent flip.

What happens if the canonical and the redirect disagree?

You have given two different instructions. A URL that 301s to A, whose HTML canonicalises to B, or a canonical that points at a URL which then redirects, is a conflict. Crawlers may ignore one of the signals, and not the one you hoped. Make the redirect target and the canonical the same published URL.

Do query parameters need their own canonical URL?

Only if the parameter defines a distinct, useful page you want indexed. Tracking parameters should keep the clean URL as the canonical. ?page=1 and empty filters should usually redirect or canonicalise to the clean list. Do not put tracked URLs in the sitemap.

How do I find duplicate URLs on a small site?

Request the obvious variants (scheme, host, slash, case, a tracking parameter), record the final URL and the canonical, and compare them to the sitemap and to your internal links. Search Console will show variants it has already found. A conflict-finder tool speeds this up; it does not replace a written URL policy.

Written by Lee Johnson. Published 10 November 2026.

All articles · Swift A–Z · Apps

Questions, or an app in mind?

Let's bring your ideas to life. Whether you're envisioning a game-changing Apple Watch app or a transformative iOS experience, I'm here to make it happen.

Start a project