Canonical tags: preventing duplicate content issues
Duplicate content isn't usually deliberate plagiarism — it's most often the same page reachable at more than one URL, created entirely by accident: http and https versions, www and non-www, a trailing slash and its absence, a URL with and without tracking query parameters. Each pair looks identical to a visitor and completely different to a crawler.
Why duplicate URLs are a real problem
When a search engine finds the same content at multiple URLs, it has to guess which one is the "real" one to rank — and it splits whatever ranking signals (links, engagement) accumulate across all of them instead of consolidating behind one. A page that would rank well on its own strength can underperform simply because its authority is split three ways across example.com/post, www.example.com/post, and example.com/post/.
The canonical tag
<link rel="canonical" href="https://www.example.com/tutorials/python-requests-library" />This single tag, present on every version of a page (including the canonical one itself), tells a search engine exactly which URL is the one to index and rank — even if the page is technically reachable at several others. It's a hint, not an absolute directive the way noindex is, but a strong one that major search engines respect in the overwhelming majority of cases.
A real example: canonical host consistency
http://example.com/ → 308 redirect → https://example.com/
https://example.com/ → 308 redirect → https://www.example.com/
http://www.example.com/ → 308 redirect → https://www.example.com/
https://www.example.com/ → 200 OK (the canonical version)This is a real pattern, verified directly on a live production site: every variant of the domain — http, non-www, or both — redirects to one single canonical form. Combined with a matching <link rel="canonical"> on every page pointing at that same https://www. version, this closes the duplicate-content gap at both the redirect layer and the metadata layer simultaneously.
The redirect chain problem
http://example.com/ → 308 → https://example.com/ → 308 → https://www.example.com/Two hops instead of one — technically still correct, still resolves to the right place, but each redirect is a full round trip a crawler (and a real visitor) has to follow before reaching the actual page. This is a genuine, if minor, real-world inefficiency worth fixing: a single redirect rule sending every non-canonical variant straight to the final URL, rather than chaining through an intermediate hop.
Self-referencing canonicals
<!-- On the page https://www.example.com/tutorials/python-requests-library itself -->
<link rel="canonical" href="https://www.example.com/tutorials/python-requests-library" />Every page should include a canonical tag pointing at itself — not just pages with a known duplicate. This is standard, defensive practice: it protects against duplicate content created by something outside the site's own control entirely, like a URL with an appended tracking parameter (?utm_source=newsletter) that a search engine might otherwise treat as a distinct page.
Pointing every page's canonical tag at the homepage, copy-pasted from a template without updating the URL per page. This doesn't prevent duplicate content — it actively tells search engines every single page on the site is a duplicate of the homepage, which can cause real pages to drop out of the index entirely.
Next: structured data — markup that goes beyond telling a search engine what a page says, to telling it explicitly what a page is.