Key takeaways
- Products, images, categories and prices move cleanly. Customer passwords, subscriptions and plugin-generated content do not.
- Shopify caps every product at 3 options and 100 variants. WooCommerce does not. Find the products that break this rule before you import, not after.
- Every product URL changes. A 301 redirect map is the difference between a migration and a traffic collapse.
- The export is the fast part. Budget your time for variant remapping and verification.
Most WooCommerce to Shopify migrations do not fail at the import step. They fail two weeks later, when someone notices that a third of the catalogue lost its size options, or that organic traffic halved because 900 product URLs now return 404.
The mechanical part of moving products is genuinely easy in 2026. What follows is the order of operations that catches the expensive problems while they are still cheap to fix.
What actually transfers, and what does not
Be honest with yourself about this table before you promise anyone a timeline.
| Data | Transfers? | What to know |
|---|---|---|
| Product titles, descriptions, prices | Yes | Clean, one-to-one. HTML in descriptions survives. |
| Product images | Yes | By URL. The source must stay online until Shopify has fetched them. |
| Variants | Mostly | Subject to the 3 option / 100 variant ceiling. See below. |
| Categories | Manual mapping | Shopify has collections, not a nested category tree. |
| SKUs, stock levels, weights | Yes | Map directly to variant fields. |
| Customer accounts | Partially | Names and addresses yes. Passwords never. |
| Order history | Reference only | Importable, but rarely behaves like a native order. |
| Reviews | App dependent | Lives in a plugin on Woo and an app on Shopify. Export separately. |
| Subscriptions | No | Must be rebuilt and customers re-authorised. |
| Page builder content | No | Elementor and similar output shortcodes Shopify cannot render. |
Subscriptions deserve their own project plan. Payment authorisations are tied to your Woo payment gateway and cannot be transferred to Shopify's. Every subscriber has to re-enter payment details, and a meaningful percentage will not. If you run subscriptions, decide whether the migration is worth that churn before doing anything else.
Step 1: Get a complete export of the catalogue
You need a file containing every product, every variation, and the full image URL list. Three routes, in ascending order of reliability:
- The built-in exporter. Products, All Products, Export. Free and adequate for small catalogues. It runs in the browser and times out on large ones, which produces a partial file that looks complete. If you use it, export category by category.
- A paid export plugin. Adds filtering and custom column names, but you still have to work out the Shopify mapping yourself, and you are still bound by your host's PHP limits.
- Scrapify. Reads the storefront rather than the database, so it needs no admin access and cannot time out mid-catalogue. It also writes the Shopify schema directly, which removes the entire remapping step below. Free to try on any store.
We cover all five approaches, including the WP-CLI and direct SQL routes, in how to export all WooCommerce products to CSV.
Whatever you use, sanity check the row count against Products, All Products in wp-admin before continuing. A truncated export is the single most common cause of "half my products are missing".
Step 2: Handle the variant ceiling before you import
This is the one that surprises people. A Shopify product accepts three option names maximum and 100 variant combinations maximum. WooCommerce imposes neither limit.
A t-shirt with 5 sizes, 6 colours and 2 fits is 60 combinations across 3 options, which is fine. Add a fourth option such as sleeve length and Shopify rejects the product outright, no matter how few combinations result.
Find the offenders before import. In your export, count distinct attribute names per product and flag anything above three, then count variation rows per parent and flag anything above 100. For each flagged product you have three choices:
- Collapse an option into the title. Split "Classic Tee" with a Fit option into "Classic Tee, Regular Fit" and "Classic Tee, Slim Fit" as two products.
- Drop the option. If one attribute has a single value across every variation, it is not really an option.
- Use a variant app. Shopify apps can present more options through metafields, but they do not raise the underlying limit and they add a dependency.
Do this on a spreadsheet, not in Shopify. Sorting your export by variant count and fixing the top 20 products takes an hour. Discovering the same 20 products as import errors, one at a time, takes a day.
Step 3: Map categories to collections
WooCommerce categories are hierarchical: Clothing > Shirts > Long Sleeve is a real tree with parent relationships. Shopify collections are flat. There is no such thing as a sub-collection.
Two workable patterns:
- Flatten to the leaf. Every product joins a collection named after its deepest category. Simple, and navigation is built manually in the Shopify menu editor.
- Tag and automate. Import each level of the tree as a product tag, then build automated collections whose condition is "product tag equals Shirts". This reproduces hierarchy in behaviour if not in structure, and new products self-file.
The second is more work up front and much less work forever after. If your catalogue grows, use it.
Step 4: Fix the images before you cut anything over
Shopify imports images by fetching the URL in the Image Src column. Three things break this:
- The source going offline. Do not cancel WooCommerce hosting until you have confirmed every image is in Shopify's CDN. Shopify does not re-fetch later.
- Hotlink protection. If your CDN or security plugin blocks requests without a matching referer, Shopify's fetcher gets a 403 and the image is silently skipped.
- Relative URLs. Some exports emit
/wp-content/uploads/tee.jpg. Shopify needs the absolutehttps://form.
After import, filter your Shopify products by "no image" and check the count is zero. Do this before anything else, because it is the fix that stops being possible once the old site is gone.
Export in Shopify format directly
Paste a WooCommerce store URL into Scrapify and download a CSV already shaped to Shopify's schema, with Handle grouping and variant rows written for you. Free to try, no card needed.
Step 5: Import and read the report properly
In Shopify admin go to Products, Import, and upload your CSV. Leave "Overwrite any current products that have the same handle" unticked on the first run so a mistake does not destroy existing data.
Shopify emails a results report when the job finishes. Read it. It lists per-row failures that are invisible in the admin UI, and the two you will see most are:
- Duplicate handle. Two different products resolved to the same slug. Usually from titles differing only by punctuation.
- Invalid option combination. The variant ceiling from step 2, caught late.
If you are unsure how Shopify groups your rows into products, the Shopify product CSV template explained walks through every column and the Handle rules that govern grouping.
Step 6: Build the redirect map
Shopify forces its URL structure. Product pages live under /products/ and collections under /collections/. Your WooCommerce URLs were probably /product/ and /product-category/, and may have been customised further. In practice, every indexed URL on the site changes.
Without redirects, Google drops those pages, existing backlinks point at 404s, and rankings you spent years earning disappear. With redirects, most authority carries across within a few weeks.
The process:
- Get the real URL list. Export from Google Search Console rather than crawling, because Search Console knows about pages your crawler will not find, including ones with backlinks.
- Map old to new. Two columns in a spreadsheet. Product handles usually derive predictably from titles, so a formula covers most rows.
- Load them into Shopify. Online Store, Navigation, URL Redirects. Bulk import accepts a two-column CSV.
- Handle the leftovers. Anything with no equivalent redirects to its closest collection, not to the homepage. A homepage redirect for a discontinued product is treated by Google as a soft 404.
Step 7: Verify before you touch DNS
Run this checklist against the Shopify store while it is still on the myshopify.com domain:
- Product count matches the WooCommerce count, exactly.
- Zero products without images.
- Total variant count matches, allowing for any you deliberately collapsed.
- Spot check 20 products across different categories: price, compare-at price, SKU, stock, description formatting.
- Every collection has products in it.
- Place a real test order end to end, including a refund.
- Spot check 20 redirects with a header checker, confirming 301 and not 302.
Only then switch DNS. Then keep the WooCommerce install running, unlinked, for at least 30 days as an escape hatch.
The faster route
If steps 1 through 4 sound like a week you do not have, there are two shortcuts.
You can point Scrapify at the WooCommerce store and get a Shopify-schema CSV back in seconds, with variants grouped and image URLs absolute, then handle mapping and redirects yourself. Or you can hand the whole job to our done-for-you migration service, where we run the export, the remapping, the import and the verification, and hand back a store that has already passed the checklist above.
Either way, the redirect map is yours to own. It is the part no tool can guess, and the part that determines whether the migration costs you traffic.