returntag - hreflang checker · one finding
Alternate target canonicalizes elsewhere
Recommended action: Align the alternate’s canonical with its own hreflang URL, or remove that alternate if it is intentionally canonicalized to another page.
Fix principle: Align every canonical signal for a page — the HTML <link rel=canonical>, an HTTP Link header, the post-render DOM, and each page's self-reference inside an hreflang cluster — on one confirmed intended URL; a conflict anywhere in that chain is resolved at its owning layer, never papered over by adding another canonical downstream.
Implementation for your setup
Confirm first: The page emits zero, more than one, or mutually disagreeing canonical signals across its HTML head, HTTP response header, or post-render DOM. A present canonical signal is relative, points to a URL that does not return a live 200 response, sits outside <head> where crawlers may not honor it, or only appears after client-side JavaScript runs.
Do not apply when: Exactly one absolute canonical URL is declared consistently across the HTML head, any HTTP header, and the rendered DOM, and that target itself returns 200. The apparent second reference is a distinct, valid annotation — an hreflang alternate, a pagination rel=next/prev, or another non-canonical link — not a competing canonical claim for the same page.
Likely control points: cms-app · server · edge-cdn
Choose the layer that owns the final response.
Generic HTTP / HTML
Steps
- Enumerate every canonical signal for the URL — the HTML <link rel="canonical">, any HTTP Link: rel="canonical" response header, and the post-render DOM — and identify which layer emits each one.
- Choose exactly one intended absolute canonical URL per page and make every signal reproduce it verbatim; never declare a relative canonical, and never let a sitemap entry, redirect target, or hreflang alternate imply a different URL than the declared canonical.
- Correct or remove the emitting layer for any conflicting or duplicate signal at its source. Do not add a second, "corrective" canonical on top of an existing one.
- Confirm the canonical target itself returns a live 200 response on the protocol and host the site actually serves, not a redirect or error.
Verify on this platform
- Fetch the raw response and inspect <head> for exactly one absolute canonical link, then check response headers for at most one agreeing Link: rel="canonical".
- Confirm the canonical target itself returns 200 without redirecting, then use Search Console URL Inspection to compare the user-declared canonical against the Google-selected canonical.
Rollback
- Restore the previous canonical annotation or header if the correction points crawlers away from a URL that needs to stay indexed, then re-diagnose the true conflicting layer before trying again.
Caveats
- A declared canonical is a hint, not a directive: Google may select a different URL as canonical for various reasons even when every signal you control agrees.
- Don't specify different canonical URLs for the same page using different mechanisms (for example, one URL in a sitemap and a different one via rel=canonical) — the conflict itself is the defect, not the presence of any one mechanism.
- If the page belongs to an hreflang cluster, each localized URL must canonicalize to itself (or its own best-language substitute), not to the primary-language version.
Official sources
WordPress
Steps
- Confirm WordPress core's native rel_canonical() output — hooked on wp_head — is the only source of the canonical tag, or that exactly one SEO plugin or theme has deliberately taken over that responsibility. Never leave two layers emitting a tag for the same page.
- If a plugin, theme, or manual template edit adds a second <link rel="canonical"> or a conflicting header, correct or remove it at that specific owning layer; do not add a third tag to compensate.
- Confirm the intended canonical target is the live, indexable URL the site actually wants, not a query-parameter, paginated, or otherwise non-canonical variant.
Verify on this platform
- While logged out, view the public HTML source once and confirm a single <link rel="canonical"> matching the intended URL, then confirm no HTTP Link header contradicts it.
Rollback
- Restore the previous theme or plugin canonical configuration if removing a tag causes an unintended page to lose its canonical reference, then correct the true conflicting layer before trying again.
Caveats
- Do not invent a specific SEO plugin's settings path: WordPress core exposes wp_get_canonical_url() and rel_canonical() on wp_head, but which plugin or theme, if any, has overridden that output is not verified here.
- A page builder or headless WordPress frontend is owner-managed; use that system's own verified workflow instead of assuming core theme output controls the response.
Official sources
Next.js / Vercel
Steps
- Set metadata.alternates.canonical (or the equivalent value returned from generateMetadata) to one absolute intended URL per App Router route; in the Pages Router, emit exactly one canonical <link> via next/head.
- Set metadataBase once at the root layout so relative canonical values resolve against the correct production host, instead of leaving canonical relative or inconsistent between preview and production domains.
- Do not also emit a second canonical tag from a component, a custom document, or an edge Proxy/Middleware response header once the metadata API owns the output.
- If the route belongs to an hreflang cluster, pair alternates.canonical with alternates.languages so each localized route canonicalizes to itself.
Verify on this platform
- Fetch the deployed production route without executing JavaScript, confirm exactly one <link rel="canonical"> with the intended absolute URL, then rerun Canonicalization Checker or Render Gap on the same URL.
Rollback
- Revert the metadata export or route segment if the deployment changes the canonical for a route that needs to keep its prior target, then correct the actual conflicting layer before redeploying.
Caveats
- metadataBase only fills in relative values; an already-absolute canonical value is used as-is and ignores metadataBase.
- Confirm the production deployment domain matches the intended canonical host — a Preview Deployment URL is never the intended canonical target.
Official sources
Shopify
Steps
- Duplicate the active theme and confirm theme.liquid emits exactly one <link rel="canonical" href="{{ canonical_url }}" /> in the head; Shopify's canonical_url object already resolves to the platform's intended canonical for standard product, collection, and content pages.
- If a second canonical tag is present — added by an app embed, a theme customization, or a duplicated snippet — remove it at that specific source rather than editing canonical_url itself.
- Preview representative product, collection, and content routes before publishing the corrected duplicate theme.
Verify on this platform
- Inspect the published storefront response without browser execution and confirm a single canonical tag reflecting canonical_url on each route type.
Rollback
- Republish the previous theme if the corrected theme regresses canonical output or storefront functionality.
Caveats
- These steps apply only to Shopify Online Store Liquid/JSON themes using the canonical_url object.
- An app-owned storefront, a Hydrogen implementation, or an app that injects its own canonical tag is owner-managed; verify that system's own workflow rather than assuming theme.liquid is the only emitter.
Official sources
- Shopify: add SEO metadata to your theme (canonical_url) verified
- Shopify Help: duplicate a theme verified
- Shopify Help: publish a theme verified
Platform-managed / ask the vendor
Implementation is controlled by the platform or vendor.
Verify on this platform
- Ask the vendor to confirm which single layer emits the canonical tag and header for the URL, then compare the user-declared and Google-selected canonical in Search Console URL Inspection.
Caveats
- Escalate when the vendor cannot identify or expose the layer that emits a conflicting or duplicate canonical signal.
- Do not accept a claim that the canonical is correct without one production-URL response showing a single agreeing signal.
Official sources
How to verify
- Fetch the raw response and confirm exactly one canonical signal (the HTML tag and, if present, the HTTP header) names the same absolute, live URL.
- Confirm the canonical target itself returns 200 without redirecting.
- Compare the user-declared canonical against Google's selected canonical in Search Console URL Inspection.
- Rerun the finding's originating tool (Canonicalization Checker, On-Page SEO Checker, SEO Site Audit Crawler, Render Gap, Google Index Checker, or HTTP Header Checker) on the same production URL.
Escalate when
Escalate when ownership of the emitting layer is unclear, more than one system claims to own the canonical output, or Google's selected canonical keeps diverging from the declared canonical after every signal you control has been made consistent.