One Shopify collection is already feeding 412 filter URLs into the index, and the WooCommerce staging site we stood up against it generated nearly the same volume through layered navigation in six days. That is the comparison. Not a feature grid. Not a theme demo. The stack either lets us close those URLs, or it keeps minting them every time someone ticks a colour and a size.

Shopify SEO and WooCommerce SEO fail in the same place: collection pages, filters, and indexation. They fail in different ways, and the way they fail decides whether we can keep the crawl on products that can rank.

The crawl is the real comparison

Google does not care that one store is hosted for you and the other sits on WordPress. It cares how many URLs resolve, whether each one has a job, and whether the canonical story is honest. Both platforms will happily serve a 200 on a thin sort or filter combination unless someone stops them.

On Shopify the leak is usually the collection plus the Search & Discovery filters, plus `/collections/all`, plus products living in more than one collection. On WooCommerce the leak is layered nav, `?filter_` parameters, product-category pagination, leftover tag archives, and attachment pages nobody remembered to kill.

If the live index already shows more URLs than products, the stack debate is secondary. We fix the crawl first, then we decide whether the platform will let that fix hold.

Collection pages

Collection pages are the ranking surface for category intent. They are also the cheapest way to duplicate the whole catalogue.

Shopify gives you a collection title, a description field, a featured image, and a product grid. The template is Liquid. Unique copy above the grid is possible, but only if the theme exposes the field and nobody overwrites it with a page builder section that repeats across every collection. Subcollections are clumsy. A collection that is just a filtered view of another collection will look like a twin in the index.

WooCommerce uses product categories as archives. The archive template is PHP. We can put unique copy, a custom H1, and a different module order on one category without touching the others, provided the theme is a real child theme and not a closed builder skin. We can also noindex a thin category from the SEO plugin without waiting on an app review.

That extra control is why WooCommerce wins on messy catalogues. Shopify wins when collections are few, curated, and actually written. A store with eight real collections and 200 products is a different job from a store with 80 collections that are just colourways.

Filters, parameters and indexation

Filters are the decision that most store owners postpone until Search Console is already full of parameter URLs.

Shopify native filters and many filter apps append query strings. Some render as 200s with self-canonicals back to the clean collection. Some do not. Ajax filters that never change the URL are kinder to the crawl, but they hide state from Google and from the shopper who wants to share a filtered view. There is no perfect native switch that says “index the collection, ignore every combination.” An app can paper over it. An app can also inject three new scripts and a second sitemap.

WooCommerce layered navigation is worse when it is left on defaults. Attribute archives, `filter_color`, `min_price`, `orderby=price` - each one is a URL unless we noindex, canonicalise, or block it. FacetWP, Filter Everything, and the core widgets all behave differently. We treat the filter plugin as part of the SEO stack, not as merchandising decoration.

The test is simple. Click two filters. View source. Check the canonical, the robots meta, and whether a new URL appeared. Do it on both stacks before you commit the catalogue.

Apps on Shopify, plugins on WooCommerce

Shopify SEO is an app problem wearing a theme. Metafields, JSON-LD, redirects, bulk title rewrites, alt text, and filter control all live in the app list. Each app is another vendor, another script, another thing that can rewrite a canonical without telling you.

We keep the app count low on purpose. One SEO app that owns titles, metas, JSON-LD and redirects. One filter approach. Nothing that claims to “auto-blog” collection copy. If an app needs storefront access to inject JSON-LD that the theme already outputs, it is a duplicate and it will clash.

WooCommerce SEO is a plugin problem wearing WordPress. Yoast or Rank Math (pick one), a redirect plugin we trust, a sitemap we can open and read, and the WooCommerce settings for permalinks and product archives. Plugin conflicts are real. A caching plugin that serves a stale canonical is a ranking incident, not a curiosity.

The difference is access. On Shopify we work inside the doors they leave open. On WooCommerce we can open the theme, the functions file, and the robots.txt. That is also how a junior developer breaks the store on a Friday. Control and risk travel together.

Canonicals, sitemaps and robots.txt

Shopify writes a canonical on most templates. Collection pagination often canonicalises to itself page by page, which is acceptable. Filter URLs that self-canonicalise to the dirty URL are not. The native sitemap lists products, collections, pages and blogs. It will list things you wish it would not. robots.txt on Shopify is constrained; we can add rules, we cannot treat it like a blank file on our own host.

WooCommerce plus an SEO plugin lets us shape all three. Category archives can canonicalise to themselves, paginated series can use rel next/prev or a clean self-canonical policy we actually chose, and thin taxonomies can be noindexed and dropped from the sitemap. robots.txt can block cart, checkout, my-account, and the query strings we have already decided are junk.

Google still wants a short path from a list to a product and unique information on the product itself. That is the spine of the Google ecommerce SEO overview, and both stacks only match it when collection pages stay limited and product URLs stay stable.

If the sitemap is twice the size of the product count, we do not submit it and hope. We cut.

Themes, Liquid and PHP templates

Theme lock-in is an SEO constraint, not an aesthetic one.

Shopify Online Store 2.0 themes give sections and metafields. We can add a unique block on a single collection if the theme allows it. We cannot always change the document title logic, the way variants render, or the heading order without forking the theme and then fighting theme updates. JSON-LD is often in a snippet that an app then duplicates. Heading structure is whatever the theme author felt like: an H1 in the header logo is still common.

WooCommerce on a proper child theme lets us change the archive template, the product template, and the heading outline. That only holds if someone is actually doing WordPress development instead of stacking page-builder modules on the shop page until the HTML is a soup of nested divs. A locked builder skin on WooCommerce is not “more flexible than Shopify.” It is Shopify with worse hosting.

We look at the theme the way we look at a roof: what can we open, what is glued, and what will leak when we next touch it.

Product copy you can actually unique

Indexation without unique copy is just a larger pile of near-duplicates.

Shopify product SEO fields are title, meta description, URL handle, and the description. Variants do not get their own indexable URL in the way people expect; variant selection is usually a parameter or a hash on the same product URL, which is correct. The work is writing 200 genuine descriptions and not pasting the manufacturer paragraph into all of them. Metafields can hold extra unique blocks if the theme renders them. If it does not, the metafield is a database entry nobody sees.

WooCommerce products are posts. Short description, long description, attributes, and any custom fields we add. Primary category in Yoast stops products sitting in two category paths. We can generate supporting copy for categories in a way Shopify collections resist, then edit the ones that matter by hand.

Neither stack writes the copy. Shopify will not save you from 400 identical descriptions. WooCommerce will not either. The stack only decides how painful it is to attach the unique block to the right template.

Weight of the storefront

Speed is not a branding exercise. It is how many apps you installed because the last one did not quite do the job.

Shopify’s CDN is a real advantage. TTFB is usually fine from most regions we care about. The damage is app pixels, review widgets, popups, and a theme that loads every section’s JS on every template. We cut apps before we buy speed apps. A speed app on top of seven other apps is how you get a 90 on a lab test and a slow collection grid on a phone.

WooCommerce speed is hosting, object cache, a sane image pipeline, and plugin restraint. It can beat Shopify on a well-run stack. It can also sit on cheap PHP hosting with an unoptimised builder and lose Core Web Vitals on every collection page. That is not a WooCommerce SEO problem in the abstract. It is an operations problem that will show up as ranking drag on the money templates.

We measure the collection grid and the product template, not the homepage. Homepage vanity scores do not pay for the store.

Migrations and the 301 window

Moving Shopify to WooCommerce, or the other way, is an SEO project with a cart attached.

Handles, collection paths, and `/products/` versus `/product/` do not map one-to-one. Shopify handles are in the URL. WooCommerce permalinks depend on settings that someone will “tidy” during the build. If that tidy happens after go-live, you have two URL systems and a month of 404s.

We export the live URL list first. Every product, every collection or category, every content page, every blog post that earns traffic. Then we map. Then we 301. Then we watch Search Console for the two weeks after cutover, not the afternoon of.

Apps do not migrate. Redirects inside a Shopify SEO app die with the storefront unless we export them. WooCommerce redirect plugins do not know what Shopify used to serve. Filters never map. We do not try to 301 old filter URLs; we let them 404 or 410 and keep the clean collection.

A migration is the wrong time to “also redesign.” Pick one wound.

How we pick a stack with you

We do not start from loyalty to a platform. We start from the catalogue, the collection plan, and who will touch the store after launch.

Shopify SEO is the right call when collections are few, the team will not log into hosting, app discipline is possible, and the product URLs can stay boring for years. We still have to police filters, `/collections/all`, duplicate collection membership, and the app list. That work sits inside our ecommerce SEO services when the store is already live or about to be.

WooCommerce SEO is the right call when we need archive-level robots, custom taxonomies, template-level unique copy, and a robots.txt we own. It is the wrong call when nobody will maintain WordPress, the theme is a closed builder, and every merchandising request becomes another plugin.

If the catalogue is still moving, freeze the URL pattern before you freeze the brand colours. Handles and category slugs are harder to change than a button style.

International, Markets, hreflang, and language folders are a separate fork. Do not pick a stack because a sales call said it “does multilingual.” Ask where the hreflang is rendered and who owns the duplicate locale URLs.

Do this next

Open the live index coverage report and count URLs against products. If you are still choosing, spin a staging copy of the other stack with the same collections and the same two filters, then crawl both. Look at collection pages, filter URLs, canonicals, and the sitemap. Ignore the theme demo.

Then write the collection list you are actually willing to keep unique. Eight honest collections beat forty empty ones on either platform.

If the crawl is already dirty, or the move is already booked, send us the sitemap, the collection list, and which apps or plugins are allowed to stay. We will scope an audit against that store, not against a generic stack war. If the fit is real, we work the indexation, the templates, and the redirects until the products are the thing Google is asked to rank.