HHollow Point
Case study / Medusa migration + SEO/case-studies/shopify-to-medusa-url-parity

Shopify-to-Medusa SEO migration: proving URL and redirect parity before launch

A large UK ecommerce retailer had 2,938 current storefront routes and 9,418 historical redirects. We treated both as controlled data migrations, with collision review, rollback and runtime verification before cutover.

11 min read
2,938 current Shopify routes compared with 2,938 expected Medusa routes with zero route mismatches
The result proves pre-cutover route parity. It does not yet prove that rankings or traffic were preserved after the public move.

At a glance

Migration
Shopify to a custom Medusa commerce backend and Next.js storefront
Catalogue context
Large, established UK regulated ecommerce retailer
Current routes
2,938 Shopify paths vs 2,938 expected Medusa paths
Parity result
Zero route mismatches
Redirect history
9,418 reviewed and imported active redirects
Truth boundary
Pre-cutover technical verification; post-launch SEO outcomes are not yet claimed

The SEO migration risk was not the new homepage

Rebuilding an ecommerce storefront creates obvious work: product pages, collections, navigation, search, checkout and account journeys.

The quieter risk sits underneath them.

An established retailer accumulates years of URLs. Some are current product, collection, page or blog routes. Others are historical paths that already redirect. Marketing campaigns, suppliers, customer bookmarks, search engines and external sites may still reference them.

If the new platform changes those routes without a complete map, the business can lose more than traffic. It can break customer journeys, overwrite valid new pages with stale redirects and make problems difficult to diagnose after the domain moves.

For this Shopify-to-Medusa SEO migration, we did not treat URL handling as a launch-day spreadsheet. We treated current routes and historical redirects as two separate, versioned data migrations.

What 1:1 parity actually means

The first job was to establish two independent inventories:

  1. Every current route that Shopify could serve and that the new storefront needed to preserve.
  2. Every route the Medusa and Next.js build was expected to serve from the migrated catalogue and content.

The inventories covered products, collections, pages and blog content. Paths were normalised so superficial formatting differences did not hide real discrepancies.

The comparison produced:

  • 2,938 current Shopify paths.
  • 2,938 expected Medusa paths.
  • Zero route mismatches.

This result meant every current source route had a planned equivalent in the destination inventory.

It did not mean the migration had already preserved rankings. Search performance depends on what happens after the public cutover: status codes, canonicals, internal links, crawl behaviour, indexation and how search engines process the move. Route parity is the technical prerequisite, not the final outcome.

Historical redirects were a different problem

The retailer also had years of redirect history.

A redirect file can look simpler than a route inventory because each row appears to be only a source and target. In practice, a mature redirect set can contain:

  • Duplicate sources.
  • Chains where one redirect points to another redirect.
  • Loops.
  • Sources that now collide with a valid route on the new storefront.
  • Stale targets and homepage catch-alls.
  • External destinations.
  • Inconsistent status codes or path formats.

Importing that history blindly would have allowed old rules to override valid Medusa pages. We therefore separated the redirect review from the current-route parity test.

The redirect decision process

Each redirect needed a decision before import.

Keep

A historical source with a valid final destination could be retained.

Collapse

Where a source pointed to another redirect, the chain could be collapsed to the final destination. That reduced crawler hops and made runtime behaviour easier to reason about.

Exclude a collision

If a historical source was now a real route in the Medusa storefront, the route had to win. The old redirect was held back rather than allowed to hijack a valid page.

Remove a loop

Redirect loops were excluded rather than imported into the runtime system.

Review external targets

External destinations were separated for deliberate review instead of being treated like normal internal mappings.

The final review excluded 27 rows: 25 source collisions and two external targets. The exclusions were evidence that the process was not a bulk upload with a success message at the end.

Approval before import

The cleaned redirect set was produced as an approval preview. It recorded what would be imported, what had been excluded, the collision decisions and the intended target environment. No redirect data changed until the reviewed set was approved.

The applied import contained 9,418 active redirects. Rollback IDs were saved so the imported set could be removed deliberately if verification failed.

That approval and rollback boundary made the redirect work consistent with the wider migration: preview the exact write, apply it once, read the state back and retain a recovery path.

Verifying the database was not enough

After import, the Medusa admin verification compared the expected set with the actual stored redirects.

  • 9,418 expected and 9,418 present.
  • Zero missing.
  • Zero mismatched.
  • Zero extra.
  • Zero chains and zero loops.

Those checks proved that the data had been imported correctly. They did not prove that a browser request would receive the right response through the complete storefront stack. Runtime verification was a separate step.

Verification summary for 9,418 redirects, zero chains and loops, deliberate exclusions, runtime smoke tests and middleware performance
Database integrity, redirect health and storefront runtime behaviour were verified separately.

Testing real redirect behaviour

The first smoke set focused on paths that had previously failed. All 29 passed after the fixes.

A second stratified test sampled 200 redirects across the data rather than checking only the easiest examples. All 200 passed.

The runtime tests checked the behaviour users and crawlers would actually encounter:

  • The old path returned the intended permanent or temporary status.
  • Internal targets resolved to the correct destination.
  • Route normalisation did not add an unexpected country or category prefix.
  • A redirected request did not enter another chain.
  • Loops and malformed targets did not reach the storefront.
  • Valid new routes remained valid routes.

This was where a correct database import became a credible pre-cutover implementation.

The performance problem hiding inside the correct solution

The first redirect runtime implementation was functionally correct but expensive. Storefront middleware cold-loaded the full 9,418-row redirect map, roughly 903KB, so it could test each incoming path. That meant a request with no redirect could still pay the cost of retrieving the complete map.

The fix changed the backend contract from a full-map fetch to a per-path lookup.

For an exact match, the response was roughly 108 bytes. A non-match returned a similarly small result. The middleware could now ask one narrow question: does this path have a redirect?

This reduced cold-route work without weakening the redirect verification. It also illustrates why migration parity cannot stop at the data layer. A solution can be correct and still create a storefront performance problem.

Why redirects are part of the product architecture

Shopify's redirect tools are integrated into the platform. Moving to Medusa meant the replacement needed more than an import script.

  • A redirect data model.
  • Controlled admin import and management.
  • Chain and loop health checks.
  • A storefront read path and middleware enforcement.
  • Collision rules protecting real routes.
  • Test tooling and rollback.

That is the broader lesson from a custom commerce build. Platform migration is not only moving products and orders. It is identifying the operational and SEO behaviour the old platform provided, then deciding explicitly how the new stack will own it.

What happens at cutover

The pre-cutover result is strong: current-route parity is complete, the reviewed redirect set is present, health checks are clean and the runtime samples pass.

The public migration still needs its own measurement phase.

  1. Submit and verify the public sitemap.
  2. Test representative current routes and historical redirects against the live domain.
  3. Crawl status codes, canonicals and internal links.
  4. Monitor Google Search Console for indexing changes, unexpected 404s and crawl errors.
  5. Compare clicks, impressions, indexed pages and priority landing-page groups against the pre-cutover baseline.
  6. Update this case after a meaningful observation window.

Only then should the article use language such as rankings preserved, recovered or changed.

Google's site-move guidance recommends mapping old URLs to new ones, using server-side permanent redirects and monitoring both old and new sites. The implementation in this case was designed to make those checks measurable rather than hopeful.

A reusable migration sequence

  1. Inventory current source routes independently of the redirect export.
  2. Generate expected destination routes from the migrated data.
  3. Normalise and compare the inventories.
  4. Resolve every mismatch before cutover.
  5. Clean the historical redirect set.
  6. Protect valid destination routes from source collisions.
  7. Preview and approve the exact import.
  8. Save rollback information.
  9. Verify stored data against the approved set.
  10. Test runtime behaviour with former failures and a representative sample.
  11. Measure performance as well as correctness.
  12. Collect post-cutover search evidence before claiming the SEO outcome.

The objective is not a spreadsheet with two matching row counts. It is a chain of evidence from source inventory to browser response.

Shopify-to-Medusa SEO migration: common questions

How do you preserve SEO during an ecommerce migration?

Inventory the existing search surface, map every current route, preserve equivalent URLs where practical, review historical redirects separately, verify status codes and canonicals at runtime, and monitor the live site after cutover. Pre-launch parity reduces risk; only post-launch evidence can show the search outcome.

Do storefront URLs need to remain identical?

Not always. A deliberate permanent redirect can transfer users and search engines to a new equivalent. In this project, 1:1 parity was chosen for current routes because preserving familiar paths reduced avoidable migration variables while the platform changed underneath them.

How should migration redirects be tested?

Validate the approved redirect set in storage, then test real requests through the storefront. Check final destinations, status codes, chains, loops, collisions with valid routes and representative samples rather than relying on import row counts alone.

When can a migration claim that rankings were preserved?

After cutover, once live crawling, indexation and Google Search Console data have been observed over a meaningful period. Route parity and clean redirect tests are prerequisites, not proof of preserved rankings.

Method note

This case is based on saved Shopify and Medusa route inventories, redirect review and import artifacts, admin verification, redirect-health results and runtime smoke tests. The retailer is anonymised; domains, paths, environment IDs, redirect rows and rollback IDs are excluded. All current results are pre-cutover technical verification. No claim is made yet about post-launch rankings, traffic or index coverage.

NEXT STEP / HOLLOW POINT

Make the migration evidence-led before the domain moves.

Hollowpoint combines commerce engineering, data migration and technical SEO ownership in one controlled replatforming plan.