seo.yatna.ai
Technical SEO

Shopify Technical SEO Audit: 14 Issues Shopify Themes Hide From You

Shopify handles some SEO basics automatically, but 14 structural issues persist across nearly every store — and most theme developers never mention them.

  • Shopify creates two canonical URLs for every product — /products/ and /collections/handle/products/ — and its own canonicalization is inconsistent across themes and apps.
  • Shopify's robots.txt is locked and cannot be freely edited — adding AI crawler rules requires a custom robots.txt.liquid template, which most merchants don't know exists.
  • Shopify blogs don't auto-generate Article JSON-LD schema — every Shopify blog post is unstructured from Google's structured data perspective unless you add schema manually.
  • Product variant URLs are indexed by default — each colour/size combination creates a separate indexed URL that competes with the main product page for the same keywords.
  • llms.txt cannot be served from a standard Shopify page — it requires a custom page template with specific routing, which most Shopify SEO guides never address.
By Ishan Sharma15 min read
Shopify Technical SEO Audit: 14 Issues Shopify Themes Hide From You

Key Takeaways

  • Shopify has SEO fundamentals built in — sitemaps, canonical tags, HTTPS, and basic meta tags are handled automatically. The problems are structural and harder to fix.
  • Product variant and collection URL duplication are the most widespread Shopify SEO issues, affecting every store regardless of theme.
  • robots.txt customisation requires a Liquid template — the default Shopify robots.txt cannot be edited through the theme editor and blocks many AI crawlers.
  • Shopify blogs have no Article schema by default — every post is structurally invisible to structured data processors unless schema is added via theme customisation or app.
  • llms.txt on Shopify requires a custom workaround — no native Shopify feature serves a plain-text file at a custom URL path outside of /pages/.

Shopify is the most popular e-commerce platform in the world, and it does a reasonable job with baseline SEO: sitemaps are generated automatically, canonical tags are applied, HTTPS is included with every plan, and basic meta tag fields are editable without code. For small stores with simple catalogues, these defaults get you most of the way there.

But as your catalogue grows, as you add apps, as your blog becomes a content channel, and as AI search becomes a meaningful traffic source, Shopify's defaults start showing structural limitations. This guide documents the 14 technical SEO issues that appear consistently across Shopify stores at scale — issues that Shopify's own documentation doesn't highlight and that most theme developers don't disclose.


Issue 1: Product Variant Duplicate Content

What happens: When a customer selects a product variant (colour, size, material), Shopify updates the URL with a variant parameter: /products/sneaker-model?variant=12345678. By default, these variant URLs are indexed by Google.

A product with 20 colour and size combinations generates 20 indexed URLs, all containing nearly identical content — same product description, same images (mostly), same metadata — each competing with the canonical product URL for the same keywords.

The fix: Shopify's theme adds a <link rel="canonical"> tag to product pages, but the canonical on variant URLs should point to the main product URL (without the variant parameter). Check your theme's product.liquid or product-template.liquid to verify the canonical tag is {{ shop.url }}/products/{{ product.handle }} — not {{ request.origin }}{{ request.path }} with the variant parameter included.

If your theme's canonical includes the variant parameter, edit the canonical tag in the product template to strip variant parameters:

<link rel="canonical" href="{{ shop.url }}/products/{{ product.handle }}">

Issue 2: /collections/ and /products/ Duplicate URLs

What happens: Shopify creates two valid URL paths for every product:

  • /products/product-handle — the direct product URL
  • /collections/collection-handle/products/product-handle — the product accessed via a collection

Both URLs return the same product page content. Both are included in Shopify's sitemap. Both are crawlable by Googlebot. The canonical tag on the collection-path URL should point to the /products/ URL, but many themes and Shopify apps either set the canonical incorrectly or allow both to be indexed without canonicalization.

The fix: verify that the canonical tag on collection-path product pages points to /products/[handle], not to the current collection URL. In product.liquid:

<link rel="canonical" href="{{ shop.url }}/products/{{ product.handle }}">

Check that this canonical is not being overridden by a third-party SEO app. Some apps rewrite canonical tags and may introduce errors if configured incorrectly.


Issue 3: Theme JSON-LD Schema Conflicts With Custom Schema

What happens: many Shopify themes include built-in JSON-LD schema for Product, Organization, and BreadcrumbList types. When you add custom schema — either through a schema app or manual Liquid edits — you may end up with two conflicting Product schema objects on the same page, with different property values.

Google's structured data validator will flag duplicate schema of the same type on a page. The conflict between theme-generated schema and app-generated schema is one of the most common sources of Shopify schema validation errors.

The fix: before adding any custom schema, check your theme's layout/theme.liquid and snippets/ folder for existing JSON-LD script tags. If the theme generates Product schema, either:

  1. Disable the theme's schema and replace it with your custom implementation entirely, or
  2. Extend the theme's schema within the same script block rather than adding a separate block

A useful diagnostic: view your product page source and search for application/ld+json — count how many instances appear. More than one JSON-LD block for the same schema type is a conflict.


Issue 4: Faceted Navigation Parameters Indexed

What happens: Shopify's collection filtering system — enabled via the Search & Discovery app or through custom filter implementations — generates URL parameters for filter states: /collections/shoes?filter.p.m.product_type=sneakers&sort_by=price-ascending. These filtered collection URLs are indexed by default.

For a collection with 6 filter dimensions and 10 options each, the potential indexed URL space runs into millions of near-duplicate URLs — each a filtered view of the same collection with different product subsets.

The fix: Shopify's Search & Discovery app provides filter URL structures that can be addressed with canonical tags and robots.txt rules. For custom filter implementations, add canonical tags on filtered pages pointing to the unfiltered collection URL. Use Google Search Console's URL Parameters tool to communicate that these parameters don't generate unique content.

For large stores with significant filter usage, consider a JavaScript-based filtering approach that doesn't change the URL at all — keeping the collection URL clean and canonical while filters change the displayed products client-side only.


Issue 5: Image Alt Text Missing on Product Images

What happens: Shopify allows alt text per product image, but many stores never populate this field. The Shopify admin image alt text field is easily missed during product setup, and bulk product imports via CSV often bring images in without alt text.

Product images without alt text miss a significant optimisation opportunity — product image alt text is a direct keyword signal for Google Images, a source of product discovery traffic that many e-commerce sites underestimate.

The fix: audit product images via the Shopify admin bulk editor or a CSV export. The alt text for product images should follow the pattern: [Product Name] — [Key Attribute] — [Brand]. For a product image showing a red Nike running shoe from the side: "Nike Air Zoom Pegasus 40 — Red — Side View".

Shopify also allows alt text to be set in product.liquid as a fallback: {{ image.alt | default: product.title }}. This ensures images without explicit alt text use the product title rather than empty alt attributes.


Issue 6: Slow LCP From Hero Images

What happens: Shopify's image CDN (powered by Imgix) serves optimised images, but LCP (Largest Contentful Paint) performance depends on how the theme requests images. Many Shopify themes load hero section images via CSS background images (not <img> tags), which are not eligible for fetchpriority="high" — a browser optimisation that pre-loads the largest above-the-fold image.

Additionally, many themes load hero images at full resolution before applying CSS sizing, and some use JavaScript-dependent image loading that delays the LCP element.

The fix: ensure the above-the-fold hero image is an <img> element with fetchpriority="high" and explicit width/height attributes. In Shopify Liquid:

{{ section.settings.image | image_url: width: 1200 | image_tag:
  loading: 'eager',
  fetchpriority: 'high',
  width: section.settings.image.width,
  height: section.settings.image.height
}}

Use Shopify's image URL transformations to request the appropriate size for the container rather than loading the full-resolution image. Check LCP scores in Google Search Console's Core Web Vitals report for your most-visited collection and product pages.


Issue 7: Breadcrumb Schema Not Matching URL Structure

What happens: many Shopify themes add BreadcrumbList schema to product and collection pages, but the schema reflects the navigation breadcrumb visible on the page — which may show the category path the user navigated through, not the canonical URL structure. When a customer arrives at a product via a collection breadcrumb, the BreadcrumbList schema may show /collections/shoes/products/sneaker while the canonical URL is /products/sneaker. The schema-to-URL mismatch causes validation errors and suppresses breadcrumb rich results.

The fix: ensure BreadcrumbList schema always uses the canonical URL for the final item (the current page), and that parent item URLs reflect actual indexable pages. If the canonical product URL is /products/handle, the last BreadcrumbList item should use that URL, not the collection-path variant.


Issue 8: robots.txt Locked — Cannot Add AI Crawlers

What happens: Shopify's default robots.txt cannot be edited through the theme editor or admin panel. It is generated from a system template and blocks several user-agents by default. The critical SEO implication: AI crawlers including GPTBot, ClaudeBot, anthropic-ai, ChatGPT-User, and PerplexityBot are not explicitly allowed in most Shopify stores' robots.txt.

With AI assistants increasingly answering "best [product category]" queries and citing specific stores and products, being blocked to AI crawlers is a direct traffic and revenue impact.

The fix: Shopify allows robots.txt customisation via a robots.txt.liquid template file. To create one:

  1. In the Shopify admin, go to Online Store > Themes > Edit code
  2. Under Templates, click "Add a new template"
  3. Select robots.txt as the template type
  4. Shopify generates a default robots.txt.liquid that matches the current robots.txt
  5. Add AI crawler rules within the Liquid template:
{% # Add AI crawler permissions before the default rules %}
User-agent: GPTBot
Allow: /

User-agent: ChatGPT-User
Allow: /

User-agent: ClaudeBot
Allow: /

User-agent: anthropic-ai
Allow: /

User-agent: PerplexityBot
Allow: /

{% # Existing default rules below %}
{{ content_for_robots }}

After adding the template, verify your live robots.txt at yourdomain.com/robots.txt to confirm the changes are active.


Issue 9: Blog Without Article Schema

What happens: Shopify's blog system does not generate Article JSON-LD schema for blog posts. Every Shopify blog post is published without structured data from Google's perspective — no datePublished, no author entity, no publisher organisation. This is an E-E-A-T weakness: Google has no structured signal to confirm authorship and expertise for your content.

For stores using their blog as a content marketing channel, this means every article competes for rankings without the E-E-A-T structured signals that equivalent off-platform content typically includes.

The fix: add Article schema to your article.liquid template. The schema should include the article title, author (as a Person entity), publication date, modified date, publisher (as an Organization), and a link to the author's profile page if one exists:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": {{ article.title | json }},
  "author": {
    "@type": "Person",
    "name": {{ article.author | json }}
  },
  "datePublished": {{ article.published_at | date: '%Y-%m-%dT%H:%M:%S' | json }},
  "dateModified": {{ article.updated_at | date: '%Y-%m-%dT%H:%M:%S' | json }},
  "publisher": {
    "@type": "Organization",
    "name": {{ shop.name | json }},
    "logo": {
      "@type": "ImageObject",
      "url": {{ settings.logo | img_url: '200x' | prepend: 'https:' | json }}
    }
  },
  "image": {% if article.image %}{{ article.image | img_url: '1200x630' | prepend: 'https:' | json }}{% else %}null{% endif %},
  "description": {{ article.excerpt_or_content | strip_html | truncatewords: 30 | json }}
}
</script>

Issue 10: Missing Product Schema on Core Product Pages

What happens: Shopify themes often include partial Product schema — sometimes just @type: Product with a name and price — but omit properties that trigger rich results: aggregateRating, offers with availability and condition, brand, and gtin. Google requires the offers property with a valid availability value to show pricing and availability in product rich results.

The fix: ensure your product schema template includes the full required set for rich result eligibility:

  • name, description, image (array of image URLs)
  • brand as an Organization entity
  • offers with price, priceCurrency, availability (schema.org/InStock or schema.org/OutOfStock), itemCondition
  • aggregateRating with ratingValue and reviewCount (only if genuine reviews exist)
  • gtin13 or gtin12 (barcode/UPC) if available — improves product identification confidence

Issue 11: Pagination Without rel="next/prev" (and the Google Situation)

What happens: Google deprecated support for rel="next" and rel="prev" pagination hints in 2019. However, other search engines (Bing) and AI crawlers still use these hints to understand paginated content relationships. Shopify's default collection pagination doesn't add these rel attributes.

The more significant pagination issue on Shopify is that paginated collection pages are indexed independently and can rank — but they contain thin content (just a subset of products) and often have poor click-through rates when they rank for navigational queries.

The fix: add rel="prev" and rel="next" links to paginated collection pages for Bing and AI crawler benefit. More importantly, ensure paginated pages have unique, descriptive title tags that include the page number: "Women's Running Shoes — Page 2 | YourStore" rather than the same title as page 1, which creates duplicate title tag issues.


Issue 12: Social Meta Tags Not Generated by Default Themes

What happens: Shopify's default theme may not generate Open Graph (og:) and Twitter Card (twitter:) meta tags for all page types. Product pages typically have og:image from the first product image, but blog posts, collection pages, and the homepage may have generic or missing social meta tags.

When social meta tags are missing, social media platforms generate unpredictable preview cards — often pulling wrong images or no images — reducing click-through rates from social shares.

The fix: check your layout/theme.liquid for og: and twitter: meta tag generation. A complete implementation should cover:

  • og:title — the page title
  • og:description — the page meta description
  • og:image — a specific 1200x630 image for each page type
  • og:url — the canonical URL
  • twitter:card — set to summary_large_image for product and article pages

Many Shopify themes include these for the homepage and products but omit them for collections and blog posts. Audit with a browser inspect of each page type and add any missing tags in the relevant template files.


Issue 13: No llms.txt

What happens: there is no native Shopify feature that serves a plain-text file at /llms.txt. Shopify pages are served at /pages/[handle] with HTML wrapping — not as a raw plain-text response at a custom path. AI assistants looking for yourdomain.com/llms.txt will receive a 404 from a standard Shopify setup.

For e-commerce stores, an accurate llms.txt is particularly valuable: AI assistants frequently describe product features, pricing, shipping policies, and return policies from training data that may be outdated. A current llms.txt gives AI systems authoritative product and policy information.

The fix: Shopify does not support serving arbitrary files at custom URL paths without custom apps or workarounds. The cleanest approach is a custom page template that:

  1. Creates a new Shopify page with the handle llms-txt
  2. Creates a custom page.llms-txt.liquid template that outputs plain text with the correct content-type header

Note: Shopify does not natively support custom Content-Type headers via Liquid templates. The practical workaround is to publish the llms.txt content as a public page at /pages/llms-txt and use a Shopify App Proxy or CDN rule to serve a response at /llms.txt. If your store is behind a CDN (Cloudflare, Fastly), configure the CDN to serve the llms.txt content directly without routing through Shopify.


Issue 14: Checkout Pages in Sitemap

What happens: Shopify's system-generated sitemap does not include checkout pages, but some app-generated sitemaps, custom sitemap configurations, and older Shopify setups can include checkout, cart, account, and password pages. These pages should not be indexed — they are functional pages that provide no SEO value and can dilute crawl budget on large stores.

The fix: audit your sitemap.xml (typically at yourdomain.com/sitemap.xml) for any non-content URLs: /cart, /checkout, /account, /account/login, /account/register, /password. These should not appear in your sitemap. If they do, the source is likely a third-party SEO or sitemap app — review the app's settings to exclude these paths.

For these pages, also confirm that noindex meta tags are in place. Shopify's default configuration noindexes /account and /checkout paths, but third-party themes or apps can inadvertently override this.


Run a Shopify SEO Audit

These 14 issues require checking across multiple page types, template files, and configuration settings. Manual audits miss issues that only surface on specific product or collection configurations, and Shopify's theme update cycles can reintroduce fixed issues when a theme is updated.

An automated SEO audit catches all 14 issue types programmatically — checking canonical tags, schema validity, robots.txt configuration, sitemap integrity, meta tag completeness, and AI crawler access across your actual live URLs.

Run a free Shopify SEO audit at seo.yatna.ai — specifically configured for Shopify stores, with findings categorised by impact and fix instructions that reference your specific theme.

For e-commerce stores on platforms beyond Shopify:

E-commerce SEO audit — all platforms


FAQ

Does fixing these issues require a Shopify developer?

Some issues (robots.txt.liquid, product schema in Liquid, custom page templates) require basic Liquid template editing — straightforward for anyone comfortable editing code but technically outside the Shopify theme editor's no-code capabilities. Other issues (product alt text, canonical verification, social meta tags) can be addressed without code through the admin and theme editor. Prioritise the no-code fixes first for quick wins.

Will these issues affect my store if I have fewer than 100 products?

Yes — most of these issues affect stores of any size. Product variant canonicalization, AI crawler blocking, missing Article schema on blog posts, and missing Product schema are relevant regardless of catalogue size. Faceted navigation and crawl budget issues become more impactful as catalogue size grows.

Does Shopify's built-in SEO handle the basics well enough?

For small stores with simple catalogues, yes — Shopify's defaults are sufficient to get indexed and rank for brand-name queries. The issues in this guide become progressively more impactful as the catalogue grows, the blog becomes a content channel, and AI search becomes a meaningful traffic source. The ROI on fixing these issues increases significantly above 500 products or 50 blog posts.

How often should I run a Shopify SEO audit?

Quarterly is a reasonable cadence for growing stores. Shopify app installations frequently modify theme files, schema, and meta tag configuration — a new app can introduce schema conflicts or robots.txt issues without obvious symptoms. An automated audit on a regular schedule catches these regressions before they compound.

About the Author

Ishan Sharma

Ishan Sharma

Head of SEO & AI Search Strategy

Ishan Sharma is Head of SEO & AI Search Strategy at seo.yatna.ai. With over 10 years of technical SEO experience across SaaS, e-commerce, and media brands, he specialises in schema markup, Core Web Vitals, and the emerging discipline of Generative Engine Optimisation (GEO). Ishan has audited over 2,000 websites and writes extensively about how structured data and AI readiness signals determine which sites get cited by ChatGPT, Perplexity, and Claude. He is a contributor to Search Engine Journal and speaks regularly at BrightonSEO.

LinkedIn →