~ / insights / guides

Guide · September 2026

The Shopify SEO Issues That Ship by Default.

Every Shopify store opens with the same set of SEO issues on day one. Some you fix, some you configure around, and three you accept because the platform will not move.

Amit TiwariGuide5 min read

The client conversation that produced this guide started, as they usually do, with a list of “critical errors” from an audit tool. Half were Shopify defaults the tool does not understand, a quarter were real and fixable, and the rest were platform properties no amount of budget changes. Sorting a Shopify audit into those three boxes is most of its value.

Step 1. Check the duplicate product URLs and their canonicals

Sorting a Shopify audit into three boxes Handled by platform Needs configuration Cannot change Duplicate product URLs under collections Tag-filtered collection pages products.json catalogue endpoint ?page=N pagination App script pile URL prefixes and sitemap Half of what an audit tool flags as critical sits in the first or third column, where no budget applies.
Figure 1. The three boxes. Price work only against the middle column.

Interactive: paste a Shopify URL to classify it. Needs JavaScript.

Shopify serves every product at /products/handle and again at /collections/collection-handle/products/handle for each collection that contains it. The duplication is real; the damage mostly is not, because the collection-path version carries a canonical tag pointing at /products/handle.

One product, three URLs, one canonical rel=canonical rel=canonical /collections/caps/products/blue-cap /collections/sale/products/blue-cap /products/blue-cap The duplication is real; the damage mostly is not. What remains is internal links pointing at the left-hand URLs.
Figure 2. Shopify’s own canonical handling on the collection-path duplicates.
curl -s https://store.example/collections/caps/products/blue-cap | grep -o '<link rel="canonical"[^>]*>'

What remains worth fixing is internal linking. Older themes link products through the collection path, spreading internal links across URLs that all defer to another URL. Check the theme’s product card snippet for within: in the URL construction, and prefer linking straight to /products/handle [VERIFY: whether your current theme still does this; recent standard themes have moved to the direct URL].

Step 2. Decide what tag pages are allowed to do

40 collections 30 tags 1,200 crawlable tag pages, thin and near-duplicate 1 robots.txt.liquid rule to stop it
Figure 3. How a store mints a thousand pages nobody decided to create.

Every collection filters by tag at /collections/handle/tagname, and each tag combination is a crawlable page with thin, near-duplicate content. A store with 40 collections and 30 tags mints over a thousand of these without anyone deciding to.

Check the scale of the problem in Search Console with a site: style filter on /collections/ pages indexed, and in the crawl stats. The control point since 2021 is robots.txt.liquid, which you create under Online Store, Edit code, Templates. A common pattern blocks tag-filtered paths while leaving the collections themselves open. Blocking via robots keeps crawl budget but leaves already-indexed pages in the index; for those, the theme can emit noindex on tag-filtered views by testing current_tags in Liquid. Choose one target state, then apply both mechanisms toward it rather than one of them halfway.

Step 3. Know that the catalogue is public JSON

Append .json to a products URL, or fetch /products.json, and the store returns its catalogue as structured data, with titles, prices, inventory hints and publication dates.

curl -s "https://store.example/products.json?limit=5" | head -c 400

Competitors and scrapers use it, price-monitoring services are built on it, and it cannot be switched off from the admin [VERIFY: current status; Shopify has adjusted endpoint behaviour over the years]. Treat it as a fact of the platform. The practical consequences are two. Nothing you consider commercially sensitive belongs in product fields, and if you see your prices mirrored elsewhere within hours of a change, this is how.

Step 4. Check pagination behaviour

Collections paginate with ?page=N. The pages self-canonicalise, which is correct, and the thing to verify is that page 2 and beyond are reachable and that the theme has not added a noindex or pointed every page’s canonical at page 1, which orphans every product that lives past the first 24. One curl per doubt:

curl -s "https://store.example/collections/caps?page=2" | grep -oE '<link rel="canonical"[^>]*>|noindex'

Step 5. Audit the script pile

Every installed app injects script, and most stores accumulate apps the way drawers accumulate cables. The result lands on Core Web Vitals, and removal is the only optimisation that works; apps “disabled” in the theme often keep their script tags. List what loads, match each script to an app, and uninstall what nobody defends. Check also for leftover ScriptTag entries from uninstalled apps under the theme’s rendered source, since uninstalling does not always clean up [VERIFY: current behaviour; Shopify has been deprecating ScriptTag in favour of app embeds, which clean up better].

Step 6. Accept the fixed properties, in writing

Three things do not change on any plan, and the audit should say so instead of pricing work against them. URL prefixes are locked, so products live under /products/, collections under /collections/, pages under /pages/, articles under /blogs/handle/; no flat URLs, no category paths in product URLs. The sitemap at /sitemap.xml is generated and not editable; it is also usually correct, so this costs little. And server-level anything, log files, redirects beyond the URL redirect tool, header manipulation past what the platform exposes, is not available, because there is no server to reach.

Markets and locale subfolders (/en-in/ style) follow the platform’s own hreflang and canonical wiring when configured through Markets; configure through the product rather than hand-editing theme hreflang, which conflicts with what the platform emits.

Check it worked

Five checks after the changes. The collection-path product URL still canonicalises to /products/. A tag-filtered URL returns the blocking or noindex behaviour you chose. ?page=2 is indexable with a self-canonical. The rendered page loads only scripts you can name an app for. And Search Console’s page indexing report, four to six weeks later, shows the tag-page count falling rather than rising, which is the lagging proof.

Where I could be wrong

Shopify moves. The robots.txt.liquid capability arrived in 2021, endpoint behaviour has been adjusted since, and theme defaults improve, so any line above marked [VERIFY] should be checked against a current store rather than trusted from the date on this guide.

The tag-page advice also assumes tags are navigation, not landing pages. A store that has deliberately built tag pages into content, with copy and curation, should index the good ones, and the blanket block would throw them away.

Sources

How to cite this guide

Amit Tiwari (2026). The Shopify SEO Issues That Ship by Default. Guide, September 2026. amittiwari.net. https://amittiwari.net/guides/the-shopify-seo-issues-that-ship-by-default

Discuss in the community ↗