Platforms · Shopify
Shopify makes some things easy. It makes other things harder than they should be. Most agencies haven't learned the difference.
SEO for Shopify and Shopify Plus stores. We solve the platform's specific problems — Liquid theme rendering, faceted collection indexation, product duplication, and app-induced speed loss — alongside the universal work of category page optimization, schema, and AI engine citation.
Shopify at a glance
- Platform share
- ~10% of all ecommerce
- Plus tier sites
- 30,000+ globally
- Default rendering
- Liquid + JavaScript
- Apps installed (avg)
- 12-18 per store
The problem
Shopify gives you fast hosting and takes URL flexibility in exchange.
Shopify ships with clean URLs, automatic sitemaps, and fast hosting — most agencies stop there. But the platform forces /collections/ and /products/ URL prefixes, renders parts of the storefront with JavaScript that Googlebot doesn't always wait for, generates duplicate product URLs through collection-to-product variants, and lets third-party apps inject blocking scripts that quietly destroy Core Web Vitals. A Shopify SEO agency earns its fee on those hard parts, not on the easy default setup.
Platform-specific gotchas
The Shopify traps we fix on every engagement
These are the issues we find on most Shopify sites — including ones that previously hired SEO agencies. If your site has these, fixing them is usually the highest-leverage technical work available.
Faceted collection URLs duplicating content
The problem
When customers filter a collection by size, color, or price, Shopify generates new URLs like /collections/dresses?filter.v.option.color=blue. These are crawlable and often indexed, creating thousands of near-duplicate URLs that dilute collection page authority.
The fix
Set canonical tags to the clean collection URL and use robots.txt to block filter parameter crawl paths. For high-volume filters that genuinely deserve indexation (e.g. /collections/dresses/blue), build them as separate landing pages with unique copy.
theme.liquid — force canonical to clean collection URL
{%- if template contains 'collection' and request.path contains '?' -%}
<link rel="canonical" href="{{ canonical_url | split: '?' | first }}">
{%- else -%}
<link rel="canonical" href="{{ canonical_url }}">
{%- endif -%}Product URLs duplicating across collections
The problem
Shopify creates a product URL inside every collection it belongs to: /collections/dresses/products/red-dress AND /collections/sale/products/red-dress AND /products/red-dress. All three resolve. Without canonical control, Google sees duplicate content.
The fix
Always canonicalize to the bare /products/{handle} URL, never the collection-prefixed version. The default product.liquid template gets this right; most custom themes break it.
product.liquid — canonical to bare product URL
<link rel="canonical" href="{{ shop.url }}{{ product.url | split: '?' | first | remove_first: '/collections/' | split: '/products/' | last | prepend: '/products/' }}">Apps injecting render-blocking scripts
The problem
The average Shopify store has 12-18 apps installed. Many inject JavaScript into the <head> or before critical CSS, blocking the main render and tanking LCP. Most store owners don't realize an app is the culprit.
The fix
Audit installed apps quarterly. For each, ask: is the value worth the performance cost? Tools like Shopify's built-in Web Performance dashboard and PageSpeed Insights identify the worst offenders. Move non-critical scripts (review widgets, chat, upsells) to lazy-load or defer.
Lazy-load non-critical app scripts
<!-- Bad: app script loads synchronously, blocks render -->
<script src="https://app-domain.com/widget.js"></script>
<!-- Good: defer to after page interactive -->
<script src="https://app-domain.com/widget.js" defer></script>
<!-- Better: lazy-load on user interaction -->
<script>
['scroll', 'click', 'touchstart'].forEach(evt => {
window.addEventListener(evt, loadWidget, { once: true, passive: true });
});
function loadWidget() {
const s = document.createElement('script');
s.src = 'https://app-domain.com/widget.js';
document.head.appendChild(s);
}
</script>JavaScript-rendered product variants invisible to crawlers
The problem
Many themes load variant data (color swatches, size selectors, conditional content) via JavaScript after page load. Googlebot may not wait for the JS to execute, and AI crawlers definitely don't. Critical content stays invisible.
The fix
Server-render variant data into the initial HTML wherever possible. For variant-specific content (size guides, material details), use Liquid conditionals to render all variants' content into the DOM, then show/hide with CSS. Crawlers see everything; users see what they selected.
/products/ and /collections/ URL prefixes can't be removed
The problem
Unlike WooCommerce or custom builds, Shopify enforces the /products/ and /collections/ prefix on every URL. You can't have /red-dress — it has to be /products/red-dress. This affects keyword targeting and URL length.
The fix
Work with the constraint, not against it. Pick product handles (the slug after /products/) that read naturally and contain target keywords. For SEO landing pages that need clean URLs (e.g. for paid campaigns or specific content), build them as pages (/pages/{slug}) which don't carry prefixes.
Default product page lacks proper Product schema
The problem
Out of the box, Shopify includes basic Product schema in some themes but often misses Offer details, AggregateRating, and Brand. Most themes generate incomplete schema that fails Google's rich result requirements.
The fix
Add comprehensive Product + Offer + AggregateRating + Brand schema. Generate it server-side via Liquid so it's in the initial HTML, not injected by JavaScript. Validate every template with Google's Rich Results Test.
Shopify tools we use (and avoid)
Our opinionated Shopify stack
We're skeptical of agencies that recommend whatever's affiliate-friendly. Here's what we actually install on Shopify engagements — and what we tell clients to remove.
JSON-LD for SEO
We recommendAuto-injects comprehensive schema markup across product, collection, article, and brand pages.
The best schema app on Shopify. Handles Product, Offer, AggregateRating, Article, BreadcrumbList, and Organization without manual Liquid work. We install this on most engagements.
SearchPie
Use with careOn-page SEO suite — meta tags, image alt text, broken link tracking, and schema.
Useful for stores without internal SEO capacity. The schema layer overlaps with JSON-LD for SEO; pick one, not both.
Plug In SEO
Use with careSite-wide SEO audit and on-page recommendations.
Solid for ongoing audits during DIY SEO. We don't use it during agency engagements because the recommendations are generic; for self-managed stores it's a reasonable cost.
Avada SEO & Image Optimizer
Use with careImage compression, alt text automation, and basic on-page SEO.
Good for image optimization. The schema feature is shallower than JSON-LD for SEO. Use Avada for images, dedicated apps for schema.
Yoast SEO for Shopify
We avoidPort of the WordPress Yoast plugin.
Avoid. Yoast on Shopify lacks the integration depth it has on WordPress and the features it does have are covered better by Shopify-native apps. It's confusing to install Yoast on a non-WordPress platform.
Schema implementation
Structured data done correctly on Shopify
Schema is one of the highest-leverage technical investments for AI engine citation. Here's how we implement each type on Shopify.
Product
schema.org/ProductWhy it matters
Eligible for Google Shopping rich results, AI engine citation for product queries, and Merchant Center alignment.
How we implement it
Render in product.liquid as a JSON-LD script tag. Include name, description, image, brand, offers (with price/currency/availability), and aggregateRating when reviews exist. Server-render, never JavaScript-inject.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": {{ product.title | json }},
"description": {{ product.description | strip_html | json }},
"image": {{ product.featured_image | image_url: width: 1200 | prepend: 'https:' | json }},
"brand": {
"@type": "Brand",
"name": {{ product.vendor | json }}
},
"offers": {
"@type": "Offer",
"url": "{{ shop.url }}{{ product.url }}",
"priceCurrency": {{ cart.currency.iso_code | json }},
"price": {{ product.price | money_without_currency | remove: ',' | json }},
"availability": "{% if product.available %}https://schema.org/InStock{% else %}https://schema.org/OutOfStock{% endif %}"
}{% if product.metafields.reviews.rating_count > 0 %},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": {{ product.metafields.reviews.rating | json }},
"reviewCount": {{ product.metafields.reviews.rating_count | json }}
}{% endif %}
}
</script>BreadcrumbList
schema.org/BreadcrumbListWhy it matters
Rich results in SERPs with breadcrumb display; helps Google understand site hierarchy.
How we implement it
Render in the layout or a snippet shared across collection and product pages. The challenge on Shopify is the collection-then-product hierarchy; render breadcrumbs that match the canonical path, not the navigated path.
Organization
schema.org/OrganizationWhy it matters
Identifies your brand entity for Knowledge Graph eligibility and AI engine citation.
How we implement it
Render once in theme.liquid <head>. Include logo, sameAs links to all social profiles, contactPoint, and address. This is one-time setup per theme.
FAQPage
schema.org/FAQPageWhy it matters
Product, collection, and content pages with FAQ sections become eligible for FAQ rich results in SERPs.
How we implement it
Build a FAQ section snippet in Liquid that renders both the visible FAQ HTML and the matching FAQPage JSON-LD. Reusable across product pages, collection pages, and article pages.
What you get
Deliverables on a Shopify engagement
Theme-level technical audit
Liquid theme inspection for canonical handling, schema generation, faceted nav rules, and JavaScript rendering issues.
App audit + performance triage
Every installed app evaluated for value vs performance cost; remediation plan for the worst offenders.
Schema saturation
Product, Offer, AggregateRating, Article, FAQPage, BreadcrumbList, Organization — server-rendered via Liquid, validated.
Category page rebuild (top 20-50)
Revenue-weighted prioritization, copy + schema + internal linking + faceted nav handling.
Product page template upgrade
Sitewide PDP template improvements that propagate to every product without manual per-SKU work.
Google Merchant Center alignment
Product feed optimization and schema alignment for organic + Shopping crossover.
Services that fit shopify sites
The mix we usually recommend
SEO
Ecommerce SEO Services | Shopify & Revenue Growth
Our flagship ecommerce SEO service — category pages, PDPs, and buying guides built for Shopify.
SEO
Technical SEO Services | Core Web Vitals & Schema
Liquid theme work, schema implementation, and app audits are technical SEO problems.
SEO
AI SEO Services | ChatGPT & Perplexity Citations
AI Overviews now appear on most product comparison queries. We make sure your Shopify store is cited.
Industries that typically use Shopify
Common Shopify buyer profiles
Common questions
About Shopify SEO
Do you work with Shopify Plus specifically?
Can you build a custom Shopify theme?
How do you handle Shopify's mandatory /products/ and /collections/ URL prefixes?
Will you audit our installed apps?
How fast do Shopify SEO results show up?
Send me your Shopify site. I'll tell you honestly what's broken.
A 45-minute call where I look at your Shopify site live and tell you what I'd prioritize. If we're a fit, we'll talk about working together. If not, I'll point you to who I'd hire instead.
Free · 45 min · No obligation