---
title: "Missing canonical tag - Serpwise"
description: "Without an explicit canonical, Google picks one - often the URL with tracking params, a paginated variant, or a duplicate. Add a self-referential canonical."
url: "https://serpwise.ai/learn/missing-canonical-tag/"
source: "https://serpwise.ai/learn/missing-canonical-tag/"
---
[← Back to Learn](/learn/)

Canonicalization Warning

# Missing canonical tag

Without an explicit canonical, Google picks one - often the URL with tracking params, a paginated variant, or a duplicate. Add a self-referential canonical.

`<link rel="canonical">` tells search engines which URL is the authoritative version of a piece of content. Without it, Google picks for you based on signals it can see - internal links, sitemaps, redirects - and the result is often a URL with tracking parameters, a paginated variant, or a near-duplicate.

Canonical is a hint, not a directive. Google may still pick a different URL if other signals are stronger. But a missing canonical is the loudest possible signal of indifference, and the cheapest one to fix.

## When to add a canonical

Every indexable HTML page. Including the homepage. Including pages that you think have no duplicates - query parameters, mixed-case URLs, trailing slashes, and HTTPS/HTTP variants all create duplicates you may not have noticed.

The default canonical is **self-referential**: the page’s canonical points to itself, on the preferred protocol, host, and path. No query string unless the query string actually distinguishes the content.

## How to detect it

```
curl -s https://example.com/some/page \
  | grep -oE '<link[^>]*rel="canonical"[^>]*>'
```

If the output is empty, there’s no canonical. If there are multiple matches, you have conflicting canonicals (also a problem).

In Google Search Console: **URL Inspection** shows “User-declared canonical” (what you said) and “Google-selected canonical” (what Google picked). Divergence means Google overrode you. Missing user-declared means you didn’t declare one.

## The fix

### Universal HTML

```
<link rel="canonical" href="https://example.com/some/page" />
```

Rules:

- Absolute URL, including protocol and host.
- One canonical per page. Multiple `<link rel="canonical">` tags confuse the picker.
- Inside `<head>`, before any `<meta>` that could be parsed instead.
- The canonical URL must return `200` - don’t canonicalize to a redirected or 404’d target.

### HTTP header alternative (for non-HTML resources)

For PDFs and other non-HTML, set the canonical in the response header:

```
Link: <https://example.com/whitepaper.pdf>; rel="canonical"
```

### WordPress (Yoast / Rank Math)

Both plugins emit a self-referential canonical automatically. Verify it’s working - disable any caching plugin temporarily and view source on a few key pages.

To override on a specific post: Yoast → Advanced tab → Canonical URL. Rank Math → Advanced → Canonical URL.

If your theme also emits a canonical (some do, in `header.php`), you’ll get duplicates. Remove the theme’s `<link rel="canonical">` and let the plugin handle it.

### Shopify

Shopify emits a canonical via the theme. Check `theme.liquid`:

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

If it’s missing, add the line. Shopify’s `canonical_url` already strips known tracking params and handles `?variant=` correctly for product pages.

### Static HTML

Add it to your build template. For multi-page sites, generate the canonical from the page’s URL slug at build time.

### Next.js (App Router)

Set canonical via metadata API:

```
// app/blog/[slug]/page.tsx
export async function generateMetadata({
  params,
}: {
  params: { slug: string };
}): Promise<Metadata> {
  return {
    alternates: {
      canonical: `https://example.com/blog/${params.slug}`,
    },
  };
}
```

For sites with `metadataBase` set in the root layout, you can use a relative path. Verify the rendered HTML - `metadataBase` errors silently fall back to localhost during dev.

### Server-side header (Nginx / Apache)

For non-HTML assets:

```
location ~ \.pdf$ {
  add_header Link '<https://example.com$request_uri>; rel="canonical"' always;
}
```

## Pitfalls

**Don’t canonicalize across substantially different content.** A blog post and its category page aren’t duplicates - canonical-ing them together hides the category page from search.

**Don’t canonicalize the wrong direction for paginated archives.** Page 2 of `/blog?page=2` should canonical to itself, not to page 1. Google deprecated `rel=next/prev` in 2019; canonicalizing all pages to page 1 hides paginated content entirely.

**Don’t canonicalize HTTPS pages to HTTP, or with-www to without-www inconsistently.** Pick one canonical form for the whole site, enforce it via `301`, and emit canonical tags matching it.

**Don’t include unused query strings in the canonical.** A page rendered at `/products/widget?utm_source=email` should canonical to `/products/widget` - strip the tracker.

**Don’t canonical to a 404 or to a redirect target.** Google ignores both and falls back to picking on its own.

## Fix at the edge with Serpwise

When the canonical strategy crosses CMS boundaries - marketing on one stack, store on Shopify, help center on a vendor - the safest place to enforce a single canonical strategy is the edge.

Serpwise can inject `<link rel="canonical">` based on URL patterns: strip `utm_*` params, normalize trailing slashes, force HTTPS-only canonicals, override missing canonicals on entire sections of the site - all without touching origin templates.

[See pricing](/pricing) or run a [free AI visibility audit](/audit).

From diagnosis to deployment

## Find the issue. Ship the fix.

Use Learn to understand the problem, then run Serpwise against your own site to see what can be approved and deployed.

[Run free audit](/audit/) [Book a demo](/demo/)