# Canonical URLs

A canonical URL is the one address you want indexed for a piece of content, declared with a `link rel="canonical"` element in the page head. Where several URLs return the same or near-identical content, the canonical says which of them to keep. It is a strong hint rather than a command, and it is ignored when the rest of the page's signals disagree with it.

- **Status:** Reference
- **Audience:** both, developer
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/technology/canonical-url/

## The duplicates nobody meant to create

Almost no site sets out to publish the same page twice. Duplicates arrive as a by-product of how URLs are generated, and the list is boringly consistent across every site that has ever had this problem.

| Shape | Example pair | Usual fix |
|---|---|---|
| Tracking parameters | `/page/` and `/page/?utm_source=x` | Canonical to the clean URL; the parameter is for analytics, not identity |
| Trailing slash | `/page` and `/page/` | Pick one, redirect the other, canonical to the survivor |
| Scheme and host | `http://` and `https://`, `www.` and bare | A redirect at the edge, not a canonical alone |
| Index file | `/section/` and `/section/index.html` | Never serve both; canonical the file form to the directory form |
| Case | `/Page/` and `/page/` | Refuse the wrong case at the router rather than papering over it |
| Print, AMP, mirror formats | `/page/` and `/page.md` | The alternate format carries the canonical of the HTML page |

A canonical is the *cheapest* of these fixes and the weakest. Where a redirect is available, use the redirect: it removes the duplicate rather than annotating it, works for every client rather than for crawlers that choose to honour the hint, and cannot be contradicted.

## What overrules a canonical

Search engines treat the element as one input among several, and they will disregard it when the page's other signals point elsewhere. The usual contradictions:

- **Internal links.** If every link on the site points at the URL you declared non-canonical, the declaration is arguing with the site's own structure.
- **The sitemap.** Listing a URL in `sitemap.xml` while its page canonicals somewhere else is a direct conflict; list only canonical URLs.
- **hreflang.** Every URL in an hreflang set must be self-canonical. Pointing a language variant's canonical at another language breaks the set.
- **Redirects.** A canonical to a URL that redirects is a chain the crawler must resolve, and it may resolve it differently from how you intended.
- **Content that is not actually duplicate.** Two pages that answer different questions are not consolidated by asserting that they are.

> **Careful** A canonical pointing at a page that returns 404, or at a page that is `noindex`, is worse than none: you have named a target the crawler cannot keep, and the consolidation has nowhere to land.

## Does Connect use canonical URLs?

**Used, and structurally rather than cosmetically.** In this documentation corpus the canonical URL is not an attribute added to a page — it is the page's identity. Every page record is keyed by its canonical URL, and the build refuses a duplicate key outright, so two pages cannot claim the same address and no page can exist without one.

The URL form is enforced rather than encouraged. A documentation URL must start with `/docs`, `/research`, `/developers` or `/changelog`, must be all lowercase kebab-case, and must end with a trailing slash. That removes the case and trailing-slash duplicate families before they can be created, which is why the corpus needs the canonical element for exactly one job: pointing alternate formats back at the HTML page.

```html
<link rel="canonical" href="https://connectbyjbrh.com/docs/technology/canonical-url/">
```

The application at `/app` is a separate case and is handled with a `noindex` meta tag rather than a canonical, because its screens are not duplicates of anything — they are simply not for a search index. That page is deliberately *not* disallowed in `robots.txt`, since a disallowed URL is never fetched and its `noindex` is therefore never read.

## Getting it wrong quietly

**Every page canonicals to the home page** — A template bug, and the most damaging one. The site collapses to a single indexed URL. Check a handful of deep pages, not the home page, after any template change.
**Relative canonical with a broken base** — `href="/page/"` resolves against the current document's base URL. On a mirror or a preview host it silently names the wrong origin. Use an absolute URL.
**Canonical in the body** — The element is only recognised in the head. A canonical injected by a script that runs late, or placed after the first content, may never be seen.
**Two canonicals on one page** — One from the template and one from a plugin. Where they disagree the whole signal is usually discarded, and no consolidation happens at all.

## Questions

### Should a page canonical to itself?

Yes, for anything you want indexed. A self-referencing canonical costs nothing, states the preferred form of the URL explicitly, and protects against parameter-laden versions of the same page being treated as separate documents. It is also a requirement for pages that belong to an hreflang set.

### Does a canonical stop a page being crawled?

No. The page is still fetched, still read, and still counted against crawl capacity. A canonical influences which URL is *indexed*, not which URLs are *visited*. If your aim is to reduce fetching, that is a robots.txt question; if it is to keep a page out of results, that is a noindex question.

### Can the Markdown mirror of a page carry the canonical of the HTML page?

That is precisely what an alternate format should do. A plain-text or Markdown copy exists to be read by a program, and it should name the HTML page as canonical so that the two are never treated as competing documents.

## Related

- [XML sitemaps](https://connectbyjbrh.com/docs/technology/sitemap/)
- [robots.txt](https://connectbyjbrh.com/docs/technology/robots-txt/)
- [hreflang](https://connectbyjbrh.com/docs/technology/hreflang/)
- [Markdown alternates](https://connectbyjbrh.com/developers/markdown-mirrors/)
- [Writing documentation that both a person and a retrieval system can use](https://connectbyjbrh.com/research/writing-for-people-and-machines/)

## What this page is based on

- RFC 6596 — the canonical link relation, https://www.rfc-editor.org/rfc/rfc6596
- Google Search Central — canonicalization and duplicate URLs, https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls
- Connect documentation build — `docs-source/schema.py` URL rules and the duplicate-canonical refusal in `tools/docs_check.py`
- Connect capability registry (docs-source/facts.py) — public_docs, docs_manifests
