How to fix missing canonical on Remix

Add a self-referencing canonical tag to every page so Google knows which URL is the definitive version of that content.

Steps for Remix

  1. In each route file (e.g. app/routes/products.$handle.tsx, app/routes/collections.$handle.tsx, app/routes/_index.tsx), export a `meta` function if one doesn't already exist. Inside it, construct the canonical URL by combining your store's base URL with the current route path — for example: `const canonical = new URL(params.handle ? `/products/${params.handle}` : '/', 'https://www.yourstore.com').href;`
  2. Return a `<link>` descriptor from the `meta` function array for the canonical tag: `return [ { tagName: 'link', rel: 'canonical', href: canonical } ];` — Remix's `meta` export supports arbitrary tag descriptors including `<link>` elements via the `tagName` field.
  3. To avoid repeating this in every route, create a shared utility in app/utils/seo.ts that accepts a `request: Request` object and returns the canonical link descriptor: `export function canonicalLink(request: Request) { const url = new URL(request.url); url.search = ''; return { tagName: 'link', rel: 'canonical', href: url.toString() }; }` — stripping query params ensures tracking/filter params don't pollute the canonical.
  4. In each route's `loader`, pass the `request` object through to the returned data (e.g. `return json({ ..., canonicalUrl: canonicalLink(request).href })`), then reference it in the `meta` function via the `data` argument: `export const meta: MetaFunction<typeof loader> = ({ data }) => [ { tagName: 'link', rel: 'canonical', href: data.canonicalUrl } ];`
  5. For the root layout (app/root.tsx), ensure no conflicting or duplicate `<link rel='canonical'>` tags are rendered inside the `<Links />` component or hardcoded in the `<head>`. Remix's `<Links />` component automatically renders all link descriptors returned by route `meta`/`links` exports — confirm only one canonical appears per page by inspecting View Source.
  6. Deploy and validate by loading a product or collection page, viewing page source, and confirming exactly one `<link rel='canonical' href='https://www.yourstore.com/...'>` tag appears in the `<head>` with the correct, query-string-free self-referencing URL.
Official Remix documentation ↗

What is missing canonical?

A canonical tag is a small snippet of HTML code placed in the `<head>` of a web page that tells search engines "this is the official, preferred URL for this content." It looks like `<link rel="canonical" href="https://www.yourstore.com/your-page/" />`. When the same (or very similar) content is accessible at multiple URLs — for example, with and without "www", with tracking parameters like `?utm_source=email`, or through category filter combinations — the canonical tag acts as a signpost that points all the credit back to one master URL. Without it, search engines must guess, and they often guess wrong.

Without a canonical tag, Google may discover multiple URLs showing identical or near-identical content and split the ranking signals (links, authority) across all of them instead of concentrating them on the one URL you actually want to rank. This directly dilutes your organic search rankings and can cause the wrong URL to appear in search results — hurting click-through rates and conversions. For ecommerce stores, product pages are especially vulnerable because filtered URLs (`/shoes?color=red&size=10`), session IDs, and affiliate parameters create dozens of duplicate variants every day. Consistently missing canonical tags is one of the most common technical SEO issues that silently erodes organic traffic over time.

See the complete Missing canonical guide for every platform and the full background.

Not sure if your Remix store has this?

Run a free SEOLZ scan — we’ll find missing canonical and every other issue across your whole site.

Scan my site free

Fix missing canonical on another platform