Shopify Canonical URLs and Duplicate Content: The Collection Path Problem
Shopify gives every product four URLs on purpose. I fetched real stores to record what each canonical says, when the default is right and the one way it breaks.

Shopify serves every product at several URLs by design, and one line in the theme decides what Google does with them. I fetched ColourPop, Allbirds, Kith, Fashion Nova and the Dawn demo store to record what that line actually emits:
- Collection path: /collections/x/products/y canonicalises to /products/y on every store I checked. Leave it alone.
- Variant parameter: ?variant=123 canonicalises to the bare product URL. Right for sizes and colours, wrong only when variants are really different products.
- Tag pages: /collections/all/lip canonicalises to itself, so every tag is an indexable page. That is a decision the platform made for you.
- Pagination: ?page=2 canonicalises to itself, which is exactly what Google's pagination guidance asks for. Apps that point page 2 at page 1 break it.
- Product schema: Dawn emits one Product or ProductGroup block through the structured_data filter. A second block from a reviews app is the common fault.
The default is right far more often than the audit tools suggest. The job is to prove it on your store, not to rewrite it.
Every page ranking for this query tells you Shopify creates duplicate URLs and that canonical tags fix them. None shows you the actual tag on a real store, or the one line of Liquid that writes it. This one does, then shows how to prove it on yours. Try CrawlRaven free: 1 site, no credit card →
The short answer: the default canonical is right, and four URL families depend on it
Point any crawler at a Shopify store and the duplicate-content tab fills up before the crawl finishes. Hundreds of product URLs under /collections/, a ?variant= copy for every size, a page for every tag. The owner reads the count and starts writing redirects. Almost all of those rows are the platform working as designed.
Shopify serves every product at several addresses on purpose, then relies on one canonical tag, written by one line in the theme, to tell Google which address counts. I fetched ColourPop, Allbirds, Kith, Fashion Nova and the Dawn demo store in September 2026 to record what that line emits for each family.
The result is more reassuring than the audit tools make it look, and more specific than the ranking guides. The default is right for the collection path, the variant parameter and pagination. Tag pages are a decision Shopify made for you. And each family has exactly one way of going wrong.
Key Takeaways
- →One line writes every canonical: Dawn's layout/theme.liquid prints link rel=canonical with the canonical_url object. Products, collections, tags and pages all flow through it.
- →Collection path and variants consolidate: /collections/x/products/y and ?variant=id both canonicalise to /products/y on ColourPop, Allbirds and Kith. That is Shopify's documented default.
- →Pagination already matches Google: ?page=2 canonicalises to itself, which is what Google's pagination guide asks for. Do not let an app point it at page 1.
- →Tag pages self-canonicalise: Every single-tag URL is indexable by default. Whether it should be is your call, and the robots.txt guide covers the mechanics.
- →Product schema comes from one filter: The structured_data filter emits a Product or a ProductGroup with an Offer per variant. Apps that add a second Product block are the usual fault.
The four duplicate URL families Shopify creates by design
Shopify's help centre lists "auto-generated canonical tags" among the SEO features it handles for you, and it means these four. Here is what each family looks like and what the live canonical said, store by store, when I fetched them with a desktop browser user agent.
Every URL Shopify creates around one product, and where its canonical points
| Family | Example URL | Canonical it carried | Checked on | Result |
|---|---|---|---|---|
| Collection path | /collections/best-sellers/products/eeveelution-shadow-palette | /products/eeveelution-shadow-palette | ColourPop, Allbirds, Kith | Consolidated |
| Variant parameter | /products/eeveelution-shadow-palette?variant=42459323203666 | /products/eeveelution-shadow-palette | ColourPop, Allbirds | Consolidated |
| Tag page | /collections/all/lip | /collections/all/lip (itself) | ColourPop | Indexable on its own |
| Paginated collection | /collections/best-sellers?page=2 | /collections/best-sellers?page=2 (itself) | ColourPop, Allbirds, Dawn demo | Matches Google's guidance |
| Sort and filter parameters | /collections/all?sort_by=price-ascending | /collections/all | ColourPop, Dawn demo | Parameter stripped |
| Market subfolder | /es/products/gift-cards | /es/products/gift-cards (itself) plus hreflang | Fashion Nova | Separate page by design |
| myshopify.com domain | colourpop-prd.myshopify.com/products/... | 301 redirect to colourpop.com | ColourPop, Allbirds | Redirected, not canonicalised |
The exact tags, so you can compare them with your own store:
| Store | URL fetched | Canonical it carried |
|---|---|---|
| ColourPop | /collections/best-sellers/products/eeveelution-shadow-palette | https://colourpop.com/products/eeveelution-shadow-palette |
| ColourPop | /products/eeveelution-shadow-palette?variant=42459323203666 | https://colourpop.com/products/eeveelution-shadow-palette |
| Allbirds | /collections/mens/products/mens-tree-runner-nz-medium-grey | https://www.allbirds.com/products/mens-tree-runner-nz-medium-grey |
| Allbirds | /products/mens-tree-runner-nz-medium-grey?variant=41206419128400 | https://www.allbirds.com/products/mens-tree-runner-nz-medium-grey |
| Kith | /collections/footwear/products/nwbu189045a | https://kith.com/products/nwbu189045a |
| ColourPop | /collections/all/lip | https://colourpop.com/collections/all/lip |
| ColourPop | /collections/best-sellers?page=2 | https://colourpop.com/collections/best-sellers?page=2 |
| Allbirds | /collections/mens?page=2 | https://www.allbirds.com/collections/mens?page=2 |
| Dawn demo | /collections/all?sort_by=price-ascending | https://theme-dawn-demo.myshopify.com/collections/all |
| Fashion Nova | /es/products/gift-cards | https://www.fashionnova.com/es/products/gift-cards |
1. Collection-path product URLs: /collections/x/products/y
A product that sits in six collections has seven URLs: the plain /products/handle and one /collections/name/products/handle for each collection. The same template renders on every one. Shopify's own documentation for the within filter warns that this produces "the same content on separate URLs" and asks you to consider the SEO implications.
- ColourPop: /collections/best-sellers/products/eeveelution-shadow-palette carried a canonical to https://colourpop.com/products/eeveelution-shadow-palette.
- Allbirds: /collections/mens/products/mens-tree-runner-nz-medium-grey pointed at the plain /products/ URL.
- Kith: /collections/footwear/products/nwbu189045a pointed at https://kith.com/products/nwbu189045a, and Kith is the one store of the three whose collection grid links products through the collection path.
Three stores, three themes, one answer. Shopify's partner documentation states it plainly: for products and variants, canonical_url returns "the default product page with no collection or variant selected". This family is the one the ranking guides spend most of their words on, and it is the one that needs the least attention.
2. Variant URLs: ?variant=<id>
Pick a colour and the URL gains ?variant=42459323203666. Shopify also links these itself: the product object's url property adds the variant parameter of the most relevant variant when a product appears in search results or a filtered collection. Both stores I checked stripped it:
- ColourPop: ?variant=42459323203666 canonicalised to /products/eeveelution-shadow-palette.
- Allbirds: ?variant=41206419128400 canonicalised to /products/mens-tree-runner-nz-medium-grey.
Right for sizes and colours, because the variant is a state of one page. It goes wrong only when variants are really different products, a 250ml bottle and a 5-litre drum, that a buyer searches for separately. Then one URL, one title and one snippet have to serve both, and only the first variant's price gets shown.
If that is your catalog, split those variants into separate products with their own handles, so each gets a URL, a title and its own Offer. For everything that is genuinely one product in several sizes, leave the canonical exactly as it is.
3. Tag pages: /collections/x/<tag> and /collections/all/<tag>
Every product tag becomes a filter URL on every collection that contains a tagged product. ColourPop's /collections/all/lip carried a canonical to itself, so did /collections/best-sellers/lip, and so did the multi-tag /collections/all/lip+matte. Nothing consolidates these to the parent collection.
That makes tag pages the one family where the default is a decision rather than a fix:
- A real category is a landing page. A tag buyers search for, with its own copy, deserves to be indexed.
- Two hundred bare tags are thin near-duplicates. The collection's description with a different product order, repeated per tag.
- Multi-tag URLs are already blocked. Shopify's default robots.txt disallows URLs containing a plus sign. Single-tag pages are yours to keep or noindex, and the Shopify robots.txt guide covers the order to do it in.
4. Paginated collections: ?page=n
This is the family where the audit tools are most confidently wrong. ColourPop's /collections/best-sellers?page=2, Allbirds' /collections/mens?page=2 and the Dawn demo store's /collections/all?page=2 each carried a canonical pointing at itself, page number included.
Google's pagination documentation asks for that: "Don't use the first page of a paginated sequence as the canonical page. Instead, give each page its own canonical URL." It adds that paginated pages may share a title and description, and that Google no longer uses rel=next and rel=prev. A "duplicate title" row on page 2 is not a fault.
- rel=next and rel=prev are still printed. ColourPop and Allbirds both emit them on paginated pages. Google ignores them, other engines may not, and they do no harm either way.
- Sort and filter parameters are stripped, correctly. The Dawn demo's ?sort_by=price-ascending and ?filter.v.availability=1 URLs both canonicalised back to /collections/all, and ColourPop's sorted collection did the same. Google's guidance is to avoid indexing filtered and re-sorted copies of one list, and the stripped canonical does that.
The two extra copies: market subfolders and the myshopify.com domain
Two more copies of the catalog exist outside the four families:
- Market subfolders. Fashion Nova's /es/products/gift-cards carried a self-referencing canonical plus hreflang links for en, es and x-default. Shopify's international domains documentation says it creates hreflang tags automatically for each market. A subfolder is a separate page by design, which is right when the language or currency differs and wrong when nothing but the folder does.
- The myshopify.com domain. colourpop-prd.myshopify.com and weareallbirds.myshopify.com both answered product requests with a 301 to the primary domain. Google ranks a redirect above a canonical tag as a consolidation signal, so this copy needs no canonical at all once a primary domain is set.
The subfolder case is where store owners get hurt. In an August 2023 Shopify Community thread, a Canadian store had created a /us-en subfolder for the same catalog and called it "a huge issue with our duplicate content". A May 2024 r/SEO thread describes the same shape: /products/name and /en-us/products/name where "the only change is the currency".
Where the canonical comes from: one line in Dawn's theme.liquid
Every canonical above is written by one line. Here it is from Dawn, Shopify's reference theme, at v16.0.0 (released August 2026):
{%- comment -%} layout/theme.liquid, Dawn v16.0.0 {%- endcomment -%}
<link rel="canonical" href="{{ canonical_url }}">The canonical_url object does the work. Shopify's partner documentation describes it as the page's default URL with URL parameters removed, and the fetches above show the nuance:
- Product pages: the collection prefix is dropped and ?variant= is stripped.
- Collection pages: ?sort_by= and ?filter. parameters are stripped, but ?page= is kept.
- Tag pages: the tag stays in the path, so the page canonicalises to itself.
- Everything else: the page's own URL on the primary domain.
There is no per-page setting, no admin field and no app required for any of this.
That is also why the failure mode is so narrow. Shopify's help centre counts the canonical among the SEO features it handles automatically, and every theme Shopify distributes ships the line. When it is missing, someone removed it, and when it is wrong, someone replaced it.
When the default is right, and the one way each family goes wrong
Google's canonicalization guide says it in one sentence: "indicating a canonical preference is a hint, not a rule." Google can pick a different URL, and Search Console tells you when it has. Here is the matrix for each family, and the Pages report row that shows which state you are in.
When to leave Shopify's canonical alone, and the one failure per family
- A custom theme dropped the line. In an October 2022 Shopify Community thread, a store owner on a purchased theme reported: "I think it doesn't contain code that deals with the canonical tag. Couldn't find the term." Every product then self-canonicalises at every path, and Search Console fills with "Duplicate without user-selected canonical".
- An app overrides it. SEO apps that inject their own head snippet can print a second canonical, or build one from the request path so the collection copy points at itself. Two canonical tags on one page is a guess, and Google's guidance is not to declare different canonicals for the same page by different methods.
- Pagination canonicalised to page 1. Some apps and a lot of old advice point every ?page=n at the first page. Google's pagination guide says not to, and the practical cost is that products on page 4 lose the only URL Google reaches them through.
- Canonicals to a redirect, a 404 or another product. A retired product still linked from a collection canonicalises to a /products/ URL that now redirects or 404s. A canonical to a redirect sends Google through a hop before it reaches the page, and a canonical to a 404 points at nothing.
The healthy state has a name in Search Console too. Collection-path and variant copies should sit under "Alternate page with proper canonical tag", and Google's Pages report documentation says of that row: "there is nothing you need to do". Our Search Console for Shopify guide walks the rest of that report.
Internal links through the collection path: why link equity still flows
Here is the part the ranking guides skip. On some stores the collection grid links every product through the collection path, so the plain /products/ URL gets no internal links of its own. Kith does this. Dawn does not: its card-product snippet links card_product.url, which resolved to /products/handle on the demo store, as ColourPop and Allbirds do.
The canonical does the consolidation either way. Google's guide says a canonical exists "to consolidate signals for similar or duplicate pages", so link equity pointed at a collection copy is credited to the canonical URL. It also says consistent links to the canonical "help Google understand your preference": linking the plain URL is stronger, not required.
Google's own advice on links is short and worth following where the theme lets you:
- Link to the canonical URL rather than a duplicate wherever the theme lets you choose.
- Use absolute URLs in the canonical tag itself. Dawn does both out of the box.
The theme also links parameterised URLs on purpose. Shopify's product object documentation says product.url carries a ?variant= parameter in search results and filtered collections, and pr_ tracking parameters in product recommendations. Those links are by design, and the canonical strips every one of them.
Shopify product schema: what the structured_data filter emits
"shopify product schema" gets 30 US searches a month and "shopify structured data" another 20 (DataForSEO, US, September 2026), most of them from owners wondering whether they need an app. In Dawn, the structured data for a product page is one filter call in sections/main-product.liquid:
{%- comment -%} sections/main-product.liquid, Dawn v16.0.0 {%- endcomment -%}
<script type="application/ld+json">
{{ product | structured_data }}
</script>Shopify's filter reference says what comes out:
- A schema.org Product when the product has no variants.
- A ProductGroup with one Product per variant when it has any.
Here is the Dawn demo store's output for a bag with several colours, trimmed to one variant:
{
"@context": "http://schema.org/",
"@id": "/products/art-deco-cyclamen#product",
"@type": "ProductGroup",
"brand": { "@type": "Brand", "name": "Mlouye" },
"name": "Art Deco",
"url": "https://theme-dawn-demo.myshopify.com/products/art-deco-cyclamen",
"hasVariant": [
{
"@id": "/products/art-deco-cyclamen?variant=39577010569305#variant",
"@type": "Product",
"name": "Art Deco - Cyclamen",
"gtin": "8682035401650",
"sku": "3001-03-CY-1",
"image": "https://theme-dawn-demo.myshopify.com/cdn/shop/products/....jpg",
"offers": {
"@type": "Offer",
"availability": "http://schema.org/OutOfStock",
"price": "165.00",
"priceCurrency": "CAD",
"url": "https://theme-dawn-demo.myshopify.com/products/art-deco-cyclamen?variant=39577010569305"
}
}
]
}That block covers what Google's merchant listing guide requires on a Product: a name, an image and an Offer. Each Offer carries price, priceCurrency, availability as a schema.org URL and the ?variant= URL, which is how the variant copies earn a purpose without ranking. Google's variants documentation describes the same ProductGroup and hasVariant structure.
So you do not need an app for Product markup on Dawn or any theme that calls the filter. You need an app, or a hand-written block, in two cases:
- The theme has no call at all. Custom or older themes sometimes dropped it.
- You want a rating in the markup. The filter's sample output carries no aggregateRating.
What a theme or app can break in the Product markup
The filter is fine. What surrounds it is where the faults live, and all three of them showed up on the stores I fetched:
- A second Product block from an app. Allbirds' product page ships the theme's ProductGroup and a separate Product entity carrying only an aggregateRating, from a reviews app. Google's merchant listing guide supports pages that "focus on a single product", so two entities force Google to pick one, and the rating block has no Offer to win with.
- A hand-written block that replaces the filter. ColourPop's Product markup is theme-authored, not the filter's: it carries mpn, a seller and an aggregateRating, with availability written as the bare word InStock rather than the schema.org URL the filter uses. Custom markup is fine when complete; the risk is that nobody updates it when the theme changes.
- Missing offers or availability. Themes that print their own JSON-LD and forget the Offer, or set availability from a variable that is blank when sold out, lose the price and stock data merchant listings exist to show. Google's structured data policy forbids marking up content the page does not show, so the markup price must match the page.
The quick check is to view source and count the application/ld+json scripts. The Dawn demo store's product page has two: an Organization block from the header and the ProductGroup from the filter. A third block on a product page is almost always an app.
If your theme has no Product block at all, the free product schema generator writes one in the same shape as the filter output, and the schema validator checks what a URL actually renders.
How to validate your store's canonicals and product schema
Five fetches, in the order that catches store-wide faults first. The first three need a browser and View Source; the last two need the rendered page and Search Console.
Five fetches that prove a Shopify store's canonicals and product schema
Step 1: Read the canonical line in theme.liquid
- Open the file. Online Store > Themes > Edit code > layout/theme.liquid.
- Search for "canonical". You want exactly one hit, inside the head, printing
{{ canonical_url }}. - Fail conditions. No hit at all; a hard-coded domain; or a canonical assembled from
request.path, which reproduces the collection path instead of collapsing it.
Step 2: Fetch one product four ways
Pick a product that sits in at least one collection and has variants. Run each URL through the free canonical checker, or view source and search for rel="canonical":
- /products/handle: the canonical must be this same URL, absolute, on the primary domain.
- /collections/any/products/handle: the canonical must be the plain /products/ URL.
- /products/handle?variant=id: same target, parameter gone.
- yourstore.myshopify.com/products/handle: should answer with a 301, not a 200 with a canonical.
The free Shopify duplicate URL checker does the first three across a sample: give it your store, it picks 20 products, fetches the collection-path copy, the plain page and the ?variant= form of each, and reports where every canonical points.
Step 3: Fetch one collection three ways
- ?page=2: canonical to itself, page number included. A canonical to page 1 is a fault.
- ?sort_by=price-ascending: canonical to the bare collection URL.
- /collections/handle/tag: canonical to itself. Decide whether that page should exist, then noindex or keep.
Step 4: Validate the rendered Product markup
- Test the live URL, not the Liquid. Paste the /products/ URL into Google's Rich Results Test. Apps inject markup at render time, so the theme file never shows the full picture.
- Count the Product entities. One Product or one ProductGroup. Two means an app added its own; merge the rating into the theme's block or remove the app's.
- Check the Offer. Price, priceCurrency and availability present, and equal to what the page shows.
- Cross-check on schema.org. The Schema Markup Validator reports vocabulary errors the Rich Results Test ignores because they do not affect eligibility.
Step 5: Confirm what Google chose in Search Console
- Inspect the /products/ URL. User-declared canonical and Google-selected canonical should be identical.
- Read the Pages report. Collection-path and variant copies belong under "Alternate page with proper canonical tag". Anything under "Duplicate, Google chose different canonical than user" is Google overruling your tag, and its documentation walks through comparing the two URLs.
- Watch the tag pages. A run of "Crawled – currently not indexed" on /collections/all/tag URLs is Google telling you the tag pages are thin.
Doing this for one product proves the theme. Doing it for the whole catalog is what the crawl is for:
- Whole store: CrawlRaven joins Search Console, GA4 and a 200-point crawl into one ranked plan. Its ecommerce mode crawls the store, groups every duplicate family, and flags only the canonicals that point at a 404, a redirect or a different product.
- Cost: the free plan covers 1 site with no credit card. Lifetime licences launched at $49 for 3 sites. Lifetime pricing steps up as licenses sell, so check the pricing page for the current batch. See pricing.
For the wider store review, the Shopify SEO audit walks the whole crawl, the Shopify SEO checklist is the tick-list version, and the Shopify sitemap guide shows why none of these duplicate families appear in sitemap.xml. If you are still weighing the platform, is Shopify good for SEO gives the short verdict.
Shopify canonical and duplicate content FAQs
What Shopify does by default
Does Shopify add canonical tags automatically? Yes, through the theme. Shopify's help centre lists auto-generated canonical tags among its built-in SEO features, and Dawn's theme.liquid prints one line with the canonical_url object. A custom theme that dropped the line is the most common way the default breaks.
What is the canonical URL for a Shopify product? The plain /products/handle URL with no collection prefix and no variant parameter. Shopify's partner documentation says canonical_url returns the default product page with no collection or variant selected, and the three stores I fetched agreed.
Should paginated collections canonicalise to page 1? No. Google's pagination documentation says to give each page its own canonical URL, and Shopify already does. An app or hand edit that points page 2 at page 1 removes the only crawl path to deeper products.
Product schema
What does the structured_data filter output? A schema.org Product for a product with no variants, and a ProductGroup with one Product per variant when it has any, each with an Offer carrying price, currency, availability and the ?variant= URL.
Why does the Rich Results Test show two Product entities? A reviews or SEO app added its own block next to the theme's. Allbirds ships a ProductGroup plus a second Product carrying only an aggregateRating. Keep one entity and merge the rating into it.
Troubleshooting
How do I check whether Google accepted my canonical? URL Inspection on the /products/ URL: User-declared canonical and Google-selected canonical should match. Rows under "Duplicate, Google chose different canonical than user" in the Pages report mean Google overruled the tag.
Does the myshopify.com domain create duplicate content? Not once a primary domain is set. ColourPop's and Allbirds' myshopify.com product URLs both answered with a 301 in September 2026, and Google ranks a redirect as the strongest consolidation signal. If yours returns 200, the primary domain is not set.
The comparison guide SaaS SEO vs ecommerce SEO explains why duplicate families are an ecommerce problem first, and the duplicate content glossary entry covers the general case beyond Shopify.
Sources
- Shopify/dawn, layout/theme.liquid (canonical line, v16.0.0) and sections/main-product.liquid (structured_data call).
- Shopify Liquid reference: canonical_url, structured_data filter, within filter and product object.
- Shopify Partners: canonical URLs and the help centre SEO overview.
- Shopify: managing international domains (automatic hreflang).
- Google: what is URL canonicalization and how to specify a canonical.
- Google: pagination and incremental page loading.
- Google: merchant listing structured data, product variant structured data and structured data policies.
- Search Console Help: Page indexing report.
- Live canonicals recorded on colourpop.com, allbirds.com, kith.com, fashionnova.com and theme-dawn-demo.myshopify.com, September 2026.
- Keyword volumes: DataForSEO, US, September 2026.
Frequently asked questions
Does Shopify add canonical tags automatically?
Yes, through the theme. Shopify's help centre lists auto-generated canonical tags among its built-in SEO features, and Dawn's layout/theme.liquid prints one line, a link rel=canonical whose href is the canonical_url Liquid object. Every Shopify theme is supposed to carry that line. A custom theme that dropped it is the most common way the default breaks.
What is the canonical URL for a Shopify product?
The plain /products/<handle> URL with no collection prefix and no variant parameter. Shopify's partner documentation says canonical_url returns the default product page with no collection or variant selected. On ColourPop, Allbirds and Kith in September 2026, the collection-path and ?variant= copies all carried a canonical pointing at that plain URL.
Are /collections/x/products/y URLs duplicate content on Shopify?
They are duplicates by construction, and the canonical tag is what resolves them. Each collection-path copy renders the same page and points its canonical at /products/y, so Google consolidates signals to one URL. Search Console lists the copies under Alternate page with proper canonical tag, which its documentation says needs no action.
Should Shopify variant URLs have their own canonical?
Not by default. The ?variant= URL is one product in a chosen state, and Shopify canonicalises it to the bare product URL, which is right for sizes and colours. Give variants their own URL and page only when they are genuinely different products, with different names and prices a buyer would search for separately.
Do Shopify tag pages get a canonical tag?
Yes, a self-referencing one. On ColourPop, /collections/all/lip and /collections/best-sellers/lip each carried a canonical pointing at itself in September 2026, so every single-tag page is indexable. Shopify's default robots.txt blocks multi-tag URLs containing a plus sign. Whether the single-tag pages deserve to be indexed is your decision, not the platform's.
Should paginated Shopify collections canonicalise to page 1?
No. Google's pagination documentation says not to use the first page of a sequence as the canonical and to give each page its own canonical URL. Shopify does that: ?page=2 canonicalises to itself on every store I fetched. An app or hand edit that points page 2 at page 1 removes the only crawl path to deeper products.
What does Shopify's structured_data filter output?
A schema.org Product for a product with no variants, and a ProductGroup with a Product per variant when it has any. Each variant carries name, sku or gtin, image and an Offer with price, priceCurrency, availability and the ?variant= URL. Dawn's main-product.liquid prints it inside a JSON-LD script tag on every product page.
Why does the Rich Results Test show two Product entities on my Shopify page?
A reviews or SEO app added its own Product block alongside the theme's. Allbirds' product page ships a ProductGroup from the theme plus a second Product carrying only an aggregateRating. Google's merchant listing guide supports pages that focus on a single product, so keep one entity and merge the rating into it, or remove the app's block.
How do I check whether Google accepted my Shopify canonical?
Open URL Inspection in Search Console on the /products/ URL and compare User-declared canonical with Google-selected canonical. They should match. Then filter the Pages report for Duplicate, Google chose different canonical than user. Rows there mean Google overruled your tag, which its documentation says can happen because a canonical is a hint, not a rule.
Does the myshopify.com domain create duplicate content?
Not once a primary domain is set. In September 2026, colourpop-prd.myshopify.com and weareallbirds.myshopify.com both answered product requests with a 301 redirect to the primary domain, and Google's canonicalization guide ranks a redirect as the strongest canonical signal there is. If your myshopify.com URLs return 200, the primary domain is not set.
15+ years of growing SaaS websites through SEO | Author, 200-Point Audit Checklist
Aditi has spent 15+ years helping SaaS companies scale organic traffic through technical SEO and content strategy. She is the author of the CrawlRaven 200-Point Audit checklist used by agencies and in-house teams to systematically improve search performance.