Migrating from WooCommerce to Shopify Plus requires four overlapping systems: a bulk product and inventory importer that stores original WooCommerce IDs as reference metadata; a URL redirect router that intercepts legacy paths and serves 301s to new Shopify URLs; a separate Postgres archive for historical orders that Shopify's API cannot expose; and a pre-launch crawl audit that tests every redirect before DNS cutover. Each runs independently but must be orchestrated to avoid data loss or SEO leakage.
A mid-market retail merchant operating WooCommerce needed to migrate to Shopify Plus while preserving 8 years of order history with original timestamps, maintaining every legacy URL with 301 redirects, and protecting SEO authority across the transition.
Four pieces
Migration
Product & Inventory Import
Pulls the WooCommerce product catalog, SKUs, pricing, inventory, and custom fields into Shopify Plus, storing the original WooCommerce IDs as reference data in metafields so discrepancies can be traced later.
Pair with a CSV or JSON export from WooCommerce REST API; use metafieldsSet to store original WC product ID under namespace 'wc_legacy' key 'product_id' for traceability.
Migration
URL Redirect Router
Maps every WooCommerce product, category, and post URL to its new Shopify equivalent via a lookup table, serving 301 redirects that search engines follow and preserving all backlink authority.
Shopify Plus theme extension + Heroku redirect service
theme/snippets/legacy-redirect-check.liquidliquid
{% comment %}
Legacy URL redirect checker — intercept old WC URLs and 301 them to new Shopify ones.
Store redirect map in a JSON metafield on the store's settings.
{% endcomment %}
{% assign wc_redirects = shop.metafields.migrations.wc_url_map | parse_json %}
{% assign current_path = request.path | downcase %}
{% for mapping in wc_redirects %}
{% if current_path == mapping.old_path %}
{% comment %} Match found; render 301 redirect {% endcomment %}
<meta http-equiv="refresh" content="0; url={{ mapping.new_url }}" />
<script>
if (navigator.userAgent.indexOf('Googlebot') !== -1 || navigator.userAgent.indexOf('bingbot') !== -1) {
window.location.href = '{{ mapping.new_url }}';
}
</script>
{% break %}
{% endif %}
{% endfor %}
For true 301 responses (not meta-refresh), use a Heroku middleware that intercepts requests and returns HTTP 301; upload the redirect map as a Shopify metafield CSV.
Operations
Historical Order Archive
Stores 8 years of WooCommerce orders in a secure, queryable archive with original timestamps and customer data intact, accessible to the team without cluttering Shopify's order list.
Postgres database + custom admin dashboard
Migration
Pre-Launch SEO Audit
Runs an automated crawl of the live WooCommerce site, builds the redirect map, tests every 301 response, and flags broken or missing mappings before going live.
Crawl service + Heroku validation job
Shopify Flow editor: When → Thenflow
Trigger: Manual workflow start or scheduled daily at 2 AM
Condition: Check if "migration_stage" metafield equals "pre_launch"
Actions:
1. Send HTTP request to Heroku crawl service:
POST /crawl/validate-redirects
Body: { wc_domain: "legacy-site.com", shopify_domain: "new-site.myshopify.com" }
2. Wait for response; parse redirect_success_count and redirect_fail_urls
3. If redirect_fail_urls.length > 0:
→ Slack notification: "Redirect audit failed on {{redirect_fail_urls.count}} URLs — review dashboard"
4. If all pass:
→ Email store owner: "Pre-launch audit passed. Safe to flip DNS."
Got a similar problem?
Sketch your build in 30 seconds — voice, type, or attach a screenshot.