How to migrate from WooCommerce to Shopify, step by step
WooCommerce gives you your data more freely than any other platform — the hard part is what Shopify will accept, and the order that keeps orders, images and rankings intact while you move. This is the whole sequence, cited to the documentation it came from.
Written for someone doing this themselves. Every step links to the documentation it came from, so you can check it rather than trust us. If you would rather not do it, we will quote it.
The checklist
Every step, in the order it has to happen.
Before you touch anything1
WP admin → Products → All Products · WooCommerce → Status · Plugins
Watch out: Shopify allows 3 options and 2,048 variants per product. Any product with four or more attributes is a known rebuild — find them now, not mid-import.
Get your data out3
WP admin → Products → All Products → Export → Generate CSV
Watch out: The exporter mangles variation names on products with 3+ attributes (or 2+ where a name has multiple words). There is no published row limit — the ceiling is PHP memory, so batch big catalogues.
WooCommerce → Exports (extension), or the plugin’s own export screen
Watch out: The free WebToffee product exporter excludes variable products — use the native exporter for products and a plugin only for customers, orders and coupons.
WP admin → Tools → Export → Download Export File
Watch out: Shopify cannot read the WXR file directly, and has no native blog or page importer — this export feeds a conversion through Matrixify or the API.
Build in parallel5
Shopify admin → Products → Import
Watch out: Collection is the only column you may add to the CSV, and imports cap at 15 MB. Untick “publish to all sales channels” so nothing goes live half-built.
Shopify admin → Customers → Import
Watch out: Only the default address imports — every additional saved address is discarded. Marketing consent must be a yes you can actually evidence.
Settings → Notifications (off first) → Matrixify → New Import
Watch out: Turn off new-order notifications first, and keep Send Receipt false — get this wrong and the entire order history emails itself to your customer list.
Online Store → Themes · Online Store → Pages
Watch out: Product and blog body HTML transfers; the layout around it does not. Page-builder apps reintroduce exactly the lock-in you are leaving.
Settings → Payments
Watch out: Full card migration is Plus-only via Shopify’s Professional Services. The token route works on any plan but keeps legacy contracts on a secondary gateway — plan subscriber communication around the first renewal.
Keep your rankings1
Content → Menus → URL redirects → Import
Watch out: Build the map from a crawl of live URLs, never from the permalink pattern — WooCommerce 10.5 changed which category appears in product paths, so synthesised URLs lie.
Cut over2
Registrar DNS panel · Shopify → Settings → Domains
Watch out: Both stores are reachable during propagation, so orders can land in WooCommerce after you think you have moved. Disable its checkout for the window.
Online Store → Preferences · Google Search Console
Watch out: 301s are cached by browsers and search engines — a wrong redirect published at launch persists in caches after you fix it. Walk the top URLs by hand.
After the switch1
Customers → Send account invite
Watch out: Kill WordPress hosting before Shopify has fetched every image and you get permanent gaps. Keep it alive, read-only, for a grace period.
What does not come with you
Every migration guide that promises everything moves is selling something. These are the things that genuinely do not, and what to do instead.
Customer passwords
Passwords are encrypted outside Shopify and no export carries them.
Instead: Use Shopify’s new customer accounts — sign-in is a one-time email code, so there is no password to lose. On legacy accounts, send invites.
Saved cards and subscriptions
Card data is PCI-scoped. Full card migration needs Shopify Plus plus Shopify’s own Professional Services; wallets and PayPal billing agreements are excluded outright.
Instead: Token migration on any plan: your Stripe/Braintree/PayPal account connects as a secondary gateway billing existing contracts. Shopify’s own wording: full migration “can take months or even years”.
Gift card balances
Shopify’s gift card CSV cannot create cards, and exports reveal only the last four characters of codes.
Instead: A scripted import via the gift card API — the required scopes are granted by Shopify support on request.
Product reviews
Shopify states there is no supported path for WooCommerce reviews.
Instead: Export what you can from WordPress and re-import through Judge.me’s CSV format — reviews need a body, not just stars.
Discount codes, natively
Shopify can export discounts to CSV but cannot import them.
Instead: Matrixify’s Discounts sheet imports code and automatic discounts.
Page-builder layouts
Elementor and Divi layouts are WordPress post-meta blobs with no Shopify representation.
Instead: Rebuild in Online Store 2.0 sections. Budget it as design work, not migration.
Custom post types and ACF fields
Shopify has no arbitrary post types, and metaobjects get no automatic front-end routing.
Instead: Model them as metaobjects and metafields under Settings → Custom data, and build the templates that render them.
Extra customer addresses
Shopify’s customer CSV carries only the default address.
Instead: Push additional addresses via the Admin API, or let customers re-add them.
Your URLs, mapped.
WooCommerce and Shopify disagree about URL shapes, so every old address needs a 301 to its new home. This is the mapping.
| WooCommerce | Shopify | Note |
|---|---|---|
| /product/linen-throw/ | /products/linen-throw | The default permalink shape. Handles usually survive; Shopify drops the trailing slash. |
| /shop/bedding/linen-throw/ | /products/linen-throw | Shop-base permalinks: export the live URLs from a crawl — WooCommerce 10.5 changed which category appears in the path. |
| /product-category/bedding/ | /collections/bedding | |
| /product-category/clothing/hoodies/ | /collections/hoodies | Shopify collections do not nest — every level of a category tree needs its own row. |
| /product-tag/casual/ | /collections/casual | Needs a matching collection; Shopify has no tag archive route. |
| /shop/page/2/ | (not reliably redirectable) | Path-segment pagination cannot be redirected to query-string pagination — let these 404. |
| /about-us/ | /pages/about-us | |
| /2024/03/how-we-weave/ | /blogs/news/how-we-weave | Date-based permalinks produce no reusable pattern — every post gets an explicit row. |
| /my-account/ | /account | |
| /sitemap_index.xml | /sitemap.xml | Shopify generates its own sitemap; resubmit it in Search Console. |
Your plugins, matched.
- Yoast SEO / Rank MathShopify SEO (built in)
Titles, metas and the sitemap are built in, but there is no keyword analysis and the sitemap is not editable.
- Elementor / DiviTheme sections or PageFly
Zero layout transfers — rebuild in theme sections, or accept that PageFly/Shogun reintroduce builder lock-in.
- WooCommerce SubscriptionsShopify Subscriptions / Recharge
Products move; contracts and payment tokens do not. Plan the payment-method migration separately.
- WooCommerce BookingsSesami and similar apps
No native Shopify booking feature; existing bookings do not migrate.
- WooCommerce MembershipsAppstle Memberships
Shopify has no native content gating; LMS-style content moves off-platform.
- Native product reviewsJudge.me / Loox
Reviews with a rating only cannot be imported into Judge.me — a body is required.
- Klaviyo / Mailchimp for WooSame tool, Shopify app
Lists port cleanly; every automation flow is rebuilt by hand.
- Stripe / PayPal gatewaysShopify Payments
Anything not processed through Shopify Payments (or PayPal Express / Shop Pay) carries an extra per-transaction fee.
- Advanced Custom FieldsMetafields + metaobjects
No automated bridge — field definitions are re-modelled by hand, and metaobjects get no page routing for free.
- Wordfence / WP Rocket / backupsNothing
Not needed at all — hosting, CDN, caching and PCI compliance are Shopify’s problem now.
What goes wrong.
Your entire order history emails itself to your customers
Why: Historical order imports fire order-confirmation emails unless notifications are off and the import tool’s receipt flags are false.
Avoid it: Deactivate new-order notifications in Settings → Notifications before the order import, keep Send Receipt false, and test five orders on a development store first.
Product images silently disappear weeks after launch
Why: Shopify fetches product images from your WordPress server asynchronously; cancelling hosting or enabling hotlink protection breaks fetches still in flight.
Avoid it: Keep WordPress hosting live and publicly readable until every image is confirmed in Shopify, plus a grace period.
Every collection is empty after import
Why: Shopify’s product export has no Collection column, and its import only honours one you add by hand.
Avoid it: Map WooCommerce categories into an added Collection column, or import collections with Matrixify.
A re-import wipes fields you had already fixed
Why: With “overwrite products with matching handles”, blank columns overwrite live data with blanks.
Avoid it: Delete columns you don’t mean to change rather than leaving them empty, and export a rollback first.
Variants get new IDs and every integration breaks
Why: Changing option values in a CSV deletes existing variant IDs and creates new ones.
Avoid it: Freeze option values once fulfilment or ERP integrations are connected; make option edits only pre-launch.
Half your redirects silently do nothing
Why: Shopify redirects only fire on URLs that would 404, ignore several reserved paths, and handle query strings unreliably.
Avoid it: After the import, crawl your top-traffic old URLs and assert a 301 on each — don’t trust the import summary.
Paginated category pages vanish with no redirect possible
Why: WooCommerce paginates with a path segment (/page/2/); Shopify uses a query string, which redirects cannot reliably target.
Avoid it: Accept paginated URLs as unrecoverable and make sure the base category URL redirects cleanly.
Orders land in the old store during cutover
Why: DNS propagation leaves both stores reachable for up to 48 hours, so orders can still land in WooCommerce.
Avoid it: Drop TTL to 300 a week before launch and disable WooCommerce checkout for the propagation window.
Or hand the whole list to someone who has done it.
Send your store URL and you get back a fixed price and a plan for your store specifically: SKU count, which plugins have Shopify equivalents, the redirect plan, and the risks we can see.
Get my free migration plan