Skip to content

Shopify SEO With Claude Code: Complete Workflow

What Shopify already does well, what is genuinely left to you, and the thin pages the platform creates without being asked. Every claim measured by fetching the URL rather than taken from documentation.

Claude Code Guides: Shopify SEO With Claude Code. Three product URL variants resolving to a single canonical URL.

What Shopify does, and what is left to you

Shopify handles more of technical SEO than most hosted platforms, and the first useful thing an audit can do is stop you rebuilding what already works.

Shopify handles You handle
Sitemap generation, kept current in real time Checking it lists what you expect
robots.txt, including crawl-trap rules Deciding whether to override it at all
Canonical tags, including parameter stripping Confirming the theme actually emits canonical_url
HTTPS, HTTP/2, global CDN Image sizes and third-party scripts
Duplicate collection-product URLs Thin pages the theme creates
SEO title and description fields Actually filling them in, uniquely

Every claim in this article about how Shopify behaves was measured by requesting the URL on a live storefront and reading the response, not taken from documentation. Some of it will change; the method for re-checking it will not.

One product, five URLs, one canonical

The most common Shopify SEO worry is duplicate product URLs. Measured on a live store, it is mostly a solved problem.

Five URLs for one Shopify product and how each resolves. The plain product URL returns 200 and canonicals to itself. The variant parameter and a UTM parameter both return 200 with the parameter stripped from the canonical. A collection-scoped product URL returns 200 and canonicals to the plain product URL. A collections-slash-all product URL returns a 301 redirect to the plain product URL.
Measured by fetching each URL and reading the canonical tag out of the response. Shopify resolves all five; the job is to confirm it, not to rebuild it.

Two things follow. First, do not write theme code to "fix" collection-scoped product URLs — you would be duplicating platform behaviour and creating a second thing to maintain. Second, link internally to the clean /products/handle form anyway. A canonical resolves the duplicate for search engines; an internal link that points at a redirect still wastes a hop for everyone.

The one thing you do control is whether your theme emits a canonical at all. A custom layout that forgets {{ canonical_url }} throws away everything above. Fetch a page and check.

Titles and descriptions: the metafields that matter

Shopify stores the SEO title and description as metafields on the resource — global.title_tag and global.description_tag — for products, collections, pages, blogs and articles alike. That matters for two reasons.

First, they can be set programmatically, so keeping metadata unique across a growing catalogue is a script rather than an afternoon in the admin:

For every article in the guides blog, set:
  global.title_tag        from the manifest's seoTitle
  global.description_tag  from the manifest's seoDescription

Then fetch each published URL and confirm the rendered title and meta
description match the manifest. Report any that do not.

The second half is the part that matters. Setting a metafield and assuming the theme reads it is a check that cannot fail. Fetch the page.

Second, a theme has to actually use them. Shopify's page_title and page_description resolve to these metafields when set and fall back to the resource title and body when not — so a theme that hard-codes something else silently ignores everything you entered in the admin.

Two Shopify-specific gotchas worth knowing before you write the script: the Admin GraphQL blog.articles connection has no query argument, so finding an article by handle means listing and filtering locally; and ShopPolicyInput keys on type, not id, which is not what the surrounding API conventions lead you to expect.

The homepage title trap

This one is worth its own section because it is invisible and it hits the most valuable page on the store.

Shopify's homepage title comes from Online Store → Preferences, not from the theme and not from any product. When that field is empty, page_title falls back to the store's raw .myshopify.com domain. The homepage then ships with a title like kjhvcj-yi.myshopify.com, which looks completely normal in a browser tab and is a disaster in a search result.

There is no Admin API mutation for that preference field, so a script cannot set it and a script cannot check it in the admin. The workaround used on this site is to have the layout supply the homepage title from a theme setting instead:

{% if template.name == 'index' %}
  {% assign seo_title = settings.home_seo_title | default: shop.name %}
{% else %}
  ... normal page_title handling ...
{% endif %}

Either way, the check is the same and takes five seconds: fetch the homepage and read the <title> out of the response.

Thin pages Shopify creates for you

A Shopify store generates indexable URLs nobody deliberately created. Two categories are worth auditing on every store.

Blog tag archives. Every tag on every article produces /blogs/<blog>/tagged/<tag>. These self-canonicalise, are indexable, and in most themes inherit the blog's own title and meta description — so a store with eight tags ships eight pages carrying the blog index's exact title tag. They also add no text of their own: each one lists a subset of articles the index already lists in full. On this site the fix was a distinct title and description for anyone who lands on one, plus noindex, follow so they stop competing with the index while still passing link equity to the articles.

Default collections. Shopify creates a frontpage collection, and it goes into the generated sitemap whether or not your theme uses it. On this store it was rendering through the purchased theme rather than the custom layout, with an h1 of "Home page" and no title tag at all — a page in a different design, in the sitemap, that nothing on the site linked to. The fix was a collection template on the site's own layout so it is at least in-brand, and noindex because a one-product store's collection listing duplicates the homepage.

Neither of these is exotic. Both were found by crawling the site and sorting the results by title.

Structured data on a Shopify theme

Most purchased themes ship Product markup. Before adding your own, check what is already in the rendered HTML, or you will end up with two Product entities on one page disagreeing about price.

What a clean product page needs: one Product with name, description, brand, url, image, and one Offer carrying price, priceCurrency, availability and url. Build the price from the variant rather than a hard-coded string, so it cannot drift from what checkout charges.

Three rules that matter more than completeness:

  • No review, rating or aggregate markup without real reviews. Review apps sometimes inject it on stores with zero reviews. Check the rendered output rather than trusting the app.
  • Do not add a return policy you do not have. If refunds are handled case by case, none of schema.org's return categories describes that, and inventing a window to satisfy a validator puts your markup in conflict with your published policy. Omit the property and write down why.
  • A warning is not an error. Rich Results Test flags recommended-but-absent properties. Filling one in with a plausible guess is worse than leaving it out.

Breadcrumb markup should mirror the breadcrumb the visitor can see. If the theme shows Home / Guides / Article, the markup says the same three, generated from the same condition so they cannot drift.

The sitemap: validate, never replace

/sitemap.xml on Shopify is an index that points at per-resource sitemaps for products, pages, collections and blogs, and it is regenerated as the catalogue changes. It cannot be edited by hand, and you should not want to: a hand-maintained sitemap goes stale the first time somebody adds a page.

What to do instead is validate it:

Fetch /sitemap.xml, follow every child sitemap, and for each URL:
- fetch it and record the status code
- record the canonical, and whether it points at the URL itself
- record any robots meta

Report: any non-200, any URL whose canonical points elsewhere, any
noindexed URL, and any page in the store that is missing entirely.
Do not modify the sitemap.

The two findings that matter are a URL in the sitemap that should not be indexable, and a page that should be indexable and is missing. Both are real. Neither is fixed by editing XML.

robots.txt, and when to override it

Shopify's generated robots.txt is better than most hand-written ones. It already disallows the cart, checkout, account and order paths, sort and filter parameter combinations, preview parameters, and internal endpoints, and it declares the sitemap.

Shopify does allow an override through robots.txt.liquid. Almost nobody needs it, and the downside is asymmetric: a mistake here can remove your store from search results, and it will not be obvious. Use it only for a rule you can state in one sentence with a reason, and check the live file afterwards.

Images

Shopify's CDN handles format negotiation and resizing, so the work is on your side of the boundary.

  • Request the size you render, through image_url: width: N, and provide a srcset rather than one large file scaled down in the browser.
  • Set width and height on every image. Layout shift is the most common Core Web Vitals failure on a storefront.
  • The product's main image and an article's hero are the LCP element. Load them eagerly. Everything below the fold gets loading="lazy".
  • Descriptive filenames and real alt text. Alt describes the image; it is not a place to repeat the product name with keywords attached.
  • image_url returns a protocol-relative URL. Structured data and Open Graph need an absolute one, so prepend https: — not http:.

Product copy that is worth ranking

The technical layer above is table stakes. The product page still has to answer the question somebody typed.

An assistant is genuinely useful here and genuinely dangerous. Useful: restructuring a description so the specific answer comes first, finding the questions the copy never answers, catching claims the rest of the site contradicts. Dangerous: it will happily invent a specification, a dimension, a compatibility claim, or a customer count, because product copy in its training data is full of them.

The rule that works: the assistant may rewrite what is there, and may tell you what is missing, but may not supply a fact. Anything it flags as missing, you answer.

For a digital product specifically, the details that convert are also the details that rank: what is in the file, how many of them, the format, how delivery works, what the licence permits, and what happens if it does not work. That last one is a link to the refund policy, and it should be a real one.

Search Console, and Merchant Center for a digital product

Verify the property for the exact production hostname — the custom domain, not the .myshopify.com one — and submit /sitemap.xml. Then watch coverage rather than resubmitting: "Discovered — currently not indexed" is a quality signal, not a technical fault.

Merchant Center deserves a straight answer, because a lot of advice assumes every store is eligible. Google's unsupported Shopping content policy lists, verbatim, "eBooks and digital books (not including audiobooks)" with the examples "PDFs, EPUB books, MOBI", and separately lists services as "labour, time, effort, expertise or actions which don't result in ownership of a tangible product".

A downloadable document product sits close enough to both of those that eligibility is genuinely uncertain. The correct action is to read the current policy against your specific product and decide, not to set up a feed and hope. If the answer is no, or unclear, do not add merchant markup or a product feed anyway — misrepresentation is the single most common cause of Merchant Center suspension, and there is no SEO benefit to markup for a programme you are not in.

None of this affects organic search. A digital product ranks in web search on the same terms as anything else.

Validating after every theme push

Shopify theme changes go live the moment they are pushed, and a broken Liquid tag does not produce a 500 — it renders the error as text on the page. So the check after every push is not "did it deploy" but "what does the page say now":

  • Fetch the affected URLs and search the response for Liquid error
  • Confirm the title, description and canonical are what you expect
  • Parse every JSON-LD block
  • Re-run the internal-link crawl

Write the search for Liquid error carefully. A naive pattern will match an article that mentions the phrase in prose — that happened here, and reported a perfectly healthy page as broken. Match Shopify's actual format, and control-test it against both a page with a real error and a page that merely talks about them.

Where to go next

For building the store in the first place, how to build a Shopify store with Claude Code covers the theme architecture, credentials, digital delivery and going live. For the platform-independent SEO work, the SEO workflow is the pillar this sits under, and running a technical SEO audit covers proving your checks can fail. For auditing the whole storefront rather than its SEO, see the website audit guide. The platform rules worth writing down are in the Shopify example in the CLAUDE.md guide. The free SEO checklist is the short form of all of it.

Sources and further reading

More Claude Code guides

Free download

The CLAUDE.md Starter Kit, free

Four working CLAUDE.md files you can drop into a project today, plus the one-page checklist for what belongs in one and how to tell whether yours is actually working.

  • CLAUDE.md for a static marketing site
  • CLAUDE.md for a web application, with security and migration rules
  • CLAUDE.md for a Shopify theme, including the gotchas that cost hours
  • CLAUDE.md for a shared package in a monorepo
  • A one-page checklist, and how to test the file is actually working

The download appears here as soon as you submit. I will also email you when there is a new guide worth reading. No fixed schedule, no selling your address, unsubscribe from any email. See the privacy policy.