How to Migrate a Store From Shopify to WooCommerce Without Losing SEO
This playbook outlines the exact technical steps to migrate an e-commerce store from any platform (Shopify, Magento, or custom engines) to WooCommerce. It is designed for developers and technical store owners who need to execute a zero-downtime, SEO-safe migration.
Phase 1: Data Export and Schema Mapping
Data migration must follow a strict order of operations to maintain relational database integrity: 1. Attributes & Taxonomies (Categories, Tags, Variations) 2. Products (Simple, Variable, Grouped) 3. Customers (Billing/Shipping addresses, User accounts) 4. Orders (Linked to products and customers)
1. Database Schema Mapping
WooCommerce stores data across several WordPress database tables. Map your source CSV/SQL fields to the following target tables:
| Source Entity | WooCommerce Table | Target Field / Meta Key |
|---|---|---|
| Product SKU | wp_postmeta |
_sku |
| Price | wp_postmeta |
_price & _regular_price |
| Stock Quantity | wp_postmeta |
_stock & _manage_stock (yes/no) |
| Customer Email | wp_users |
user_email |
| Billing Phone | wp_usermeta |
billing_phone |
| Order Total | wp_postmeta |
_order_total |
| Order Items | wp_woocommerce_order_items |
order_item_name, order_item_type |
2. Execution via WP-CLI
For large datasets (10k+ products/orders), avoid web-based importers to prevent PHP timeout errors. Use WP-CLI.
First, install the WooCommerce CLI tool if not already active:
wp plugin install woocommerce --activate
To import products via CSV using WP-CLI:
wp wc product import /path/to/products.csv --user=1 --mapping=/path/to/mapping-config.json
Note: Generate the mapping-config.json by running a manual GUI import once with a 5-row sample and exporting the configuration.
Phase 2: Preserving Metadata and Custom Fields
1. Customer Passwords
You cannot decrypt passwords from Shopify (bcrypt/SHA-256 with site-specific salt) or Magento.
Solution: Import customers with random passwords and use a hook to intercept login failures, or force a password reset on their first visit. Add this snippet to your child theme's functions.php to notify migrated users:
add_action('wp_login_failed', 'handle_migrated_user_login');
function handle_migrated_user_login($username) {
$user = get_user_by('login', $username);
if ($user && get_user_meta($user->ID, '_is_migrated_user', true)) {
// Redirect to password reset with custom notice
wc_add_notice(__('Please reset your password to access your migrated account.'), 'notice');
wp_redirect(wc_get_endpoint_url('lost-password'));
exit;
}
}
2. Order History Retention
To link imported orders to imported customers, you must map the old customer IDs to the new WordPress User IDs. Create a lookup table during the customer import phase, then run a post-import SQL query to update order attribution:
UPDATE wp_postmeta pm1
JOIN wp_usermeta um ON um.meta_key = '_old_customer_id' AND um.meta_value = pm1.meta_value
SET pm1.meta_value = um.user_id
WHERE pm1.meta_key = '_customer_user';
Phase 3: URL Mapping and 301 Redirects
Preserving SEO rankings requires mapping every legacy URL to its new WooCommerce equivalent.
1. Generate the Redirect Map
Export your legacy URL structure and map it to the new WooCommerce structure.
* Shopify Product: /products/leather-boots $\rightarrow$ /product/leather-boots/
* Shopify Category: /collections/footwear $\rightarrow$ /product-category/footwear/
2. Implement Nginx Redirects
For maximum performance, handle redirects at the server level rather than using database-heavy WordPress plugins. Add a Map block to your Nginx configuration:
# Add to /etc/nginx/nginx.conf inside http block
map $request_uri $new_uri {
/products/leather-boots /product/leather-boots/;
/collections/footwear /product-category/footwear/;
}
# Add to your server block
server {
...
if ($new_uri) {
return 301 $new_uri;
}
...
}
Test and reload Nginx:
nginx -t && systemctl reload nginx
Phase 4: Payment Gateway and Checkout Setup
1. Webhook Configuration
When setting up Stripe or PayPal, configure webhooks to ensure order statuses update correctly if a user closes the browser before the redirect finishes.
In Stripe Dashboard, point your webhook endpoint to:
https://yourdomain.com/?wc-api=wc_stripe
Select these events:
* payment_intent.succeeded
* payment_intent.payment_failed
* charge.refunded
2. CLI Verification of Payment Gateways
Verify that the payment gateways are active and configured correctly:
wp wc tool run clear_transients --user=1
wp option get woocommerce_stripe_settings
Phase 5: SEO Verification and Launch Checklist
Do not point your domain to the new server until you complete these verification steps.
1. Verify Redirects via Terminal
Run a curl command to ensure your 301 redirects are working and returning the correct HTTP status code:
curl -I https://yourdomain.com/products/leather-boots
Expected Output:
HTTP/1.1 301 Moved Permanently
Location: https://yourdomain.com/product/leather-boots/
2. Generate and Validate Sitemap
- Install an SEO plugin (e.g., RankMath or Yoast).
- Ensure product, category, and page sitemaps are generated.
- Exclude utility pages (Cart, Checkout, My Account) from indexation via
robots.txt:
User-agent: *
Disallow: /cart/
Disallow: /checkout/
Disallow: /*add-to-cart=*
3. Google Search Console (GSC) Update
- Keep your old site verified in GSC.
- Submit the new
sitemap_index.xmlin GSC. - Monitor the Pages report for 404 spikes daily for 14 days post-launch.
Pre-Launch Checklist
- [ ] Database Integrity: Verify that the total count of products, customers, and orders matches the legacy system.
- [ ] SSL Certificate: Ensure Let's Encrypt or your custom SSL is active on the live server.
- [ ] Tax Settings: Verify tax rates match the legacy store settings for all target jurisdictions.
- [ ] Shipping Zones: Test flat rates, weight-based rates, and API-based carrier integrations.
- [ ] Email Templates: Test transactional emails (New Order, Customer Invoice) to ensure they are not landing in spam.
- [ ] Search Functionality: Ensure product search index is built (especially if using Elasticsearch/Jetpack Search).
Common Migration Mistakes to Avoid
- Serialized Data Corruption: When running search-and-replace on database dumps to change domains, do not use raw SQL. Serialized PHP arrays store string lengths (e.g.,
s:12:"yourdomain.com"). Changing the domain name breaks these arrays. Use WP-CLI instead:bash wp search-replace 'https://olddomain.com' 'https://newdomain.com' --precise --all-tables - Ignoring Image Metadata: Importing images without alt tags and captions destroys image search rankings. Ensure your CSV import maps old image alt text to the WP attachment metadata.
- Leaving "Discourage Search Engines" Checked: Under Settings > Reading, ensure the search engine visibility box is unchecked before going live.
Need this done for you? Hire me on Freelancehunt: https://freelancehunt.com/freelancer/sspoisk
Комментарии
Отправить комментарий