WooCommerce to Shopify Product Migration Guide
A WooCommerce to Shopify product migration fails in the same few places on almost every store: variable products whose attributes don’t line up with Shopify options, variations set to “Any” value, nested categories that have nowhere to nest, and product data that lives in plugins rather than in WooCommerce itself. The products import either way. Whether they arrive filterable, correctly grouped and with their extra fields intact depends on mapping those four things before the export — not on the import tool you pick.
This guide is the product-data half of a WooCommerce to Shopify data migration: how each part of a WooCommerce catalogue translates into Shopify’s model, where the translation is lossy, and the order we work in. Customers, orders and passwords are a separate conversation, covered in our guide to what an ecommerce data migration actually moves.
How the two catalogue models differ
WooCommerce is WordPress underneath. A product is a post, its categories and tags are taxonomies, and almost everything else — attributes, variations, custom fields — is stored as post meta or in more taxonomies. That flexibility is why WooCommerce stores accumulate structure over the years: a plugin adds a field, a developer adds another, and the catalogue ends up modelled however each addition needed it to be.
Shopify is stricter. A product has up to three options, which generate up to 2,048 variants. Products are grouped into collections, which are flat. Anything that is not an option, a variant field or a standard product field goes into metafields — typed custom fields with a definition — or into metaobjects when the same structured content is shared across many products.
So the work is not moving records. It is deciding where every piece of WooCommerce structure belongs in a model with fewer, firmer slots.
Mapping WooCommerce product types to Shopify
WooCommerce core has four product types, plus two flags that change how a product behaves. Plugins add more. Here is where each one usually lands:
| WooCommerce | Lands in Shopify as | What to watch |
|---|---|---|
| Simple product | Product with a single default variant | Clean mapping. Check SKU, weight and sale price come across. |
| Variable product | One product; variation attributes become options, variations become variants | Three options, “Any” variations, attributes not used for variations (below). |
| Grouped product | No native equivalent — separate products presented together in the theme | Decide how the “buy these together” page is rebuilt before launch. |
| External / affiliate product | A product whose button links out, built in the theme | Shopify has no “external product” type; the outbound button is custom. |
| Virtual flag | Product with “physical product” switched off | Services and bookings — check fulfilment and shipping rules. |
| Downloadable flag | Product delivered through a digital-downloads app | Files and download limits move to the app, not the product record. |
| Plugin types (subscriptions, bundles, composites) | An app or a Cart Transform function, rebuilt rather than imported | Their data model is the plugin’s, not WooCommerce’s. Scope each one separately. |
Plugin-defined product types are the ones that cause late surprises, because an export of “all products” includes them while silently dropping the rules that made them work. Bundles in particular need a deliberate data model on Shopify — we compare the three options in our guide to building a box builder on Shopify.
Variable products: attributes, variations and the “Any” trap
Variable products are where a WooCommerce to Shopify product migration is won or lost. A variable product carries attributes, and each variation is a combination of attribute values with its own SKU, price, stock, image, weight and more. Shopify’s version is a product with options and variants — similar enough to look like a straight copy, different enough to break one.
Global and custom attributes
WooCommerce has two kinds of attribute. Global attributes are defined once under Products › Attributes and reused across the catalogue. Custom attributes are typed directly into one product. Over time most stores end up with both, often describing the same thing: a global “Size” on newer products, a custom “size” or “Sizes” on older ones.
Shopify options are named per product, so this inconsistency imports faithfully — and then shows up as filters that split the same attribute into three. Normalise attribute names and values in the source data first: one name, one spelling, one value list. It is far easier in a spreadsheet than across hundreds of live products afterwards.
“Used for variations” decides option or metafield
Every attribute on a variable product has a “Used for variations” checkbox. Ticked, it generates variations and becomes a Shopify option. Unticked, it is descriptive — material, fit, country of origin — and belongs in a metafield, ideally one with a definition so it can drive storefront filters and automated collections.

Variations set to “Any” must be expanded
WooCommerce lets a variation match “Any” value of an attribute — one variation for “Black, any size” instead of four. It is a convenient shortcut when every size costs the same and stock is not tracked per size. Shopify has no wildcard: every variant is one explicit combination of option values.
So each “Any” variation has to be expanded into one variant per value before import, each with its own SKU and inventory. That changes stock management: if the old store tracked one stock figure for “Black, any size”, someone has to decide how that number splits across the new variants. Flag every “Any” variation during the audit, not on launch day.

When three options are not enough
A WooCommerce product can use more variation attributes than Shopify’s three options. When it does, the choices are the same ones any platform move faces: split the product into several (one per fabric, say, grouped back together in the theme), turn the least important attribute into a line item property chosen at add-to-cart, or keep it as a metafield if it never affected price or stock in the first place. The variant ceiling of 2,048 is rarely the binding limit; the three options usually are.
Categories and tags become collections
WooCommerce product categories are hierarchical. “Women › Tops › Hoodies” is a real tree, and a product assigned to “Hoodies” shows up when a shopper browses “Women”. Shopify collections are flat — there is no parent collection that automatically contains its children’s products.
Two Shopify features rebuild what the tree did:
- Automated collections rebuild membership. A “Women” collection can pull in every product with a tag, product type, vendor, product category or — for true/false, integer, decimal, rating and single-line-text definitions — a metafield value, with up to 60 conditions per collection. Carry each product’s full category path across as tags or a metafield and the parent collections build themselves.
- Navigation menus rebuild the hierarchy shoppers see. A top-level menu item can hold up to two levels of nested drop-downs, so a three-level WooCommerce tree fits; anything deeper has to be flattened.
WooCommerce tags usually map straight to Shopify product tags. Treat them with suspicion all the same: years of ad-hoc tagging is worth cleaning before it starts driving automated collections.

Custom fields and plugin data
Everything WooCommerce stores outside its core product fields needs a destination of its own. The common sources:
- Custom fields (from ACF or hand-coded meta) become metafields. Define them on Shopify first, with the right type — a number stored as text cannot be filtered as a number.
- Product add-ons — engraving text, gift messages, optional extras chosen at add-to-cart — usually become line item properties, captured in the theme or an app. Paid add-ons need a priced mechanism, not just a text field.
- SEO plugin titles and descriptions (Yoast, Rank Math) live in post meta and do not come across with a standard product export. Map them into Shopify’s SEO title and description fields; our guide to writing Shopify meta descriptions and title tags covers what to keep and what to rewrite.
- Reviews are WordPress comments in core WooCommerce, or a plugin’s own tables. Either way they move through a review app’s importer, not the product import.
Product URLs change shape
WooCommerce product URLs default to /product/hoodie/ and categories to /product-category/women/, though permalink settings mean many stores differ. Shopify’s are fixed: /products/hoodie and /collections/women. Every product and category URL changes, so each one needs a 301 redirect — built from the store’s actual URLs and ranking pages, not a pattern. Our guide to 301 redirects for a platform migration covers how to build and test that map.
Keep handles identical to the old slugs where you can. It makes the redirect map one-to-one and easy to check.
The order we work in
- Export and inventory. Every product type, every attribute (global and custom), every plugin that writes product data.
- Normalise in the spreadsheet. One name per attribute, one spelling per value, “Any” variations expanded, category paths captured.
- Define Shopify first. Metafield definitions, product categories and collection rules exist before the first product does.
- Import a sample. Twenty awkward products — the deepest variable product, a grouped product, one with add-ons — checked by hand on the storefront.
- Full import, then verify. Product and variant counts against the source, filters tested, collections checked against the old category archives.
- Redirects and a final delta. The 301 map goes live with DNS, and anything edited in WooCommerce since the import is re-synced.
The full sequence, from audit to launch, is in our free Shopify migration checklist. If you are coming from Magento rather than WooCommerce, the same questions play out differently — see our Magento to Shopify product migration guide.
Frequently asked questions
Can I import WooCommerce products into Shopify with a CSV?
Yes, for simple and straightforward variable products, provided the CSV is reshaped into Shopify’s product import format, with one row per variant. A plain WooCommerce export will not import as-is, and CSV alone will not carry metafields, add-ons or plugin data cleanly. Larger or messier catalogues usually go through a migration app or a scripted import against the Admin API.
Do WooCommerce variation images come across?
They can. Each WooCommerce variation has its own image, and a Shopify variant can be linked to one of the product’s media items. The image has to be uploaded to the product and then associated with the variant, which most migration tools do — check it on the sample import rather than assuming.
What happens to WooCommerce subscription products?
The product can be recreated, but active subscriptions do not move with it. Subscription contracts and billing schedules belong to the subscription plugin and must be migrated into a Shopify subscription app as a separate, consent-aware workstream.
The takeaway
A WooCommerce catalogue is shaped by years of plugins and quick fixes; Shopify’s is shaped by a small set of firm rules. Map attributes to options or metafields, expand every “Any” variation, rebuild the category tree as collections plus a menu, and give every plugin field a defined home — then the import is the easy part. For the rest of the move, read our complete WooCommerce to Shopify migration guide, or let us plan and run your WooCommerce to Shopify migration end to end.