# Canonical URL is set

- **Pattern:** `ab-002537` (`site-health-check.seo-discoverability.canonical-url`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002537
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002537)

## Why it matters

Without a canonical URL, Google treats `https://example.com/page`, `https://www.example.com/page`, and `https://example.com/page?utm_source=x` as three separate URLs competing for the same ranking slot. Link equity fragments across variants, duplicate-content filters kick in, and the version Google indexes is nondeterministic. A canonical tag consolidates signals to one preferred URL and eliminates an entire class of ranking self-harm.

## Severity rationale

Medium because duplicate-content dilution degrades rankings over time but rarely triggers a hard penalty on its own.

## Remediation

Emit a `<link rel="canonical">` with the absolute preferred URL on every indexable page. In Next.js App Router, set it via the metadata API so the scheme and host are consistent across the site:

```ts
// app/page.tsx
export const metadata = {
  alternates: { canonical: 'https://yoursite.com/page-path' },
};
```

For static HTML, place `<link rel="canonical" href="https://yoursite.com/page-path">` in the `<head>`.

## Detection

- **ID:** `canonical-url`
- **Severity:** `medium`
- **What to look for:** Count the number of `<link rel="canonical">` tags in the HTML — there must be at least 1 canonical URL. Extract the `href` attribute value. Verify the URL starts with `https://` or `http://` and is not a relative path. Check if the canonical URL matches the page being audited (it should point to the preferred version of this page).
- **Pass criteria:** Exactly 1 `<link rel="canonical" href="...">` tag exists in the HTML with an absolute URL (starting with `https://` or `http://`). The URL must not be empty, must not be a relative path, and must not point to a different domain unless the site is intentionally canonicalizing to another domain.
- **Fail criteria:** No `<link rel="canonical">` tag found, or the `href` value is empty, relative, or contains no valid URL.
- **Skip (N/A) when:** The response `Content-Type` is not HTML (e.g., JSON API endpoint).
- **Error when:** SPA detected.
- **Detail on fail:** `"No canonical URL set — search engines may index duplicate versions of this page"`
- **Remediation:** Canonical URLs tell search engines which version of a page is the "official" one, preventing duplicate content penalties. Add to your `<head>`:

  ```html
  <link rel="canonical" href="https://yoursite.com/page-path">
  ```

  In Next.js App Router: `export const metadata = { alternates: { canonical: 'https://yoursite.com/page-path' } }`. The canonical should always be an absolute URL with the preferred scheme (https) and domain (with or without www, but consistent).

Taxons: findability

HTML version: https://auditbuffet.com/patterns/ab-002537
