The Decision Nobody Warned Us About
Every conversation about moving from Shopify to a custom Next.js storefront goes the same way.
Someone shows a Lighthouse score. Someone else mentions Core Web Vitals. A developer says "full control over the frontend." The business owner nods, thinking faster site equals more sales, and the project kicks off.
We had that same conversation with a US-based fashion e-commerce brand. They were on a standard Shopify theme — solid, not spectacular. Traffic was healthy. The product was good. But conversion was stuck, and the team was convinced a faster, more custom frontend would break them out of it.
So we rebuilt it in Next.js. We connected it to Shopify's Storefront API for inventory, payments, and orders. We deployed on Vercel with edge caching. We optimized every image, every font load, every component.
The performance results were exactly what we expected.
What the Store Looked Like Before
Before the migration, the store had the following baseline metrics, measured over a 60-day window:
- Conversion rate: 1.6% (consistent with the industry average of 1.4–1.8% for fashion Shopify stores)
- Lighthouse Performance Score (mobile): 54
- Largest Contentful Paint (LCP): 4.1 seconds
- Cumulative Layout Shift (CLS): 0.19 — failing threshold
- Interaction to Next Paint (INP): 340ms — failing threshold
- Cart abandonment rate: 73%
- Mobile traffic share: 68%
The store was failing all three Core Web Vitals on mobile. For a brand where nearly 7 in 10 visitors arrived on a phone, this was not an abstract SEO concern — it was a revenue leak.
The theme was heavily customized with third-party app scripts: a reviews widget, a loyalty program, a live chat tool, and a currency converter for international visitors. Every one of these loaded synchronously, blocking the main thread. The LCP hero image — a 2.3MB JPEG — was not lazy-loaded. The CLS was caused by a promotional banner that injected itself after page paint.
These were Shopify-specific constraints. The theme ecosystem makes it easy to install apps and difficult to control what they do to your page performance.
Why We Chose Next.js — and What We Were Giving Up
The decision to go headless was not made lightly, because the trade-offs are real.
What we gained with Next.js
Full server-side rendering control means Google gets fully rendered HTML on every crawl. Product pages are statically generated at build time — 1,400 product pages, pre-rendered and served from a CDN edge node closest to the visitor. Image optimization is built in via next/image, which automatically converts to WebP, sizes responsively, and lazy-loads below the fold. The INP problem disappears because we control exactly what JavaScript loads, when, and in what order.
What we gave up
Shopify's theme ecosystem is gone. Every feature the store relied on — reviews, loyalty points, live chat, currency switching — had to be rebuilt or replaced with headless-compatible alternatives. That is not free. It costs engineering time, integration work, and in some cases, switching to different vendors entirely.
The Shopify admin still runs the backend: products, inventory, orders, fulfillment, payments. Shopify Storefront API handles the data bridge. But the merchant's team had to relearn where to do what — some things happen in Shopify, some in the codebase, and knowing the boundary takes adjustment.
The Build: What We Actually Did
The migration took 11 weeks from kickoff to launch. Here is what the technical work involved:
Stack
- Next.js 14 (App Router) — frontend framework
- Shopify Storefront API — product data, cart, checkout
- Vercel — hosting with edge network
- Contentful — CMS for editorial content and landing pages
- Algolia — search (Shopify's native search does not carry over to headless)
- Klaviyo — email, replaced with headless SDK integration
Performance decisions
Every product image was migrated and re-served through Vercel's image CDN. The hero image that previously loaded at 2.3MB now serves at 87KB in WebP on mobile. We used next/font to eliminate the render-blocking Google Fonts request. Third-party scripts — reviews, live chat — were loaded after the main content using a deferred strategy that kept them out of the critical rendering path.
Static generation pre-rendered all 1,400 product pages and 38 collection pages at build time. A visitor loading a product page on mobile in Chicago is served a pre-built HTML file from a Vercel edge node, not a server response assembled on demand.
The result was a build that shipped less JavaScript, rendered faster, and gave the layout engine nothing to fight with.
The Performance Numbers After Launch
Measured over the first 30 days post-launch, against the same 60-day pre-launch baseline:
| Metric | Before (Shopify) | After (Next.js) | Change |
|---|---|---|---|
| Lighthouse (mobile) | 54 | 91 | +37 points |
| LCP (mobile) | 4.1s | 1.3s | -68% |
| CLS | 0.19 | 0.04 | -79% |
| INP | 340ms | 88ms | -74% |
| Page Load (3G) | 6.8s | 2.1s | -69% |
| Core Web Vitals | Failing all 3 | Passing all 3 | Passing all 3 |
These numbers confirmed what the engineering work predicted. A clean Next.js build with proper image optimization, deferred third-party scripts, and static generation will outperform a script-heavy Shopify theme on mobile Core Web Vitals by a significant margin. This is not a controversial outcome.
The Conversion Rate: What Nobody Predicted
Before launch, the expectation was simple: faster site, better UX, higher conversion rate. The industry data supports this assumption. Google's research on retail sites shows that improving LCP correlates with real revenue increases. Vodafone improved LCP by 31% and saw an 8% increase in sales. Rakuten optimized Core Web Vitals and saw a 33% increase in conversion rate.
So when we saw the first 30 days of post-launch data, the number was jarring.
What Was Actually Happening
We spent two weeks diagnosing this before drawing any conclusions. What we found was not a failure of the Next.js build — it was a set of friction points introduced by the migration that had nothing to do with page speed.
Problem 1: Search was broken for 12 days
Algolia integration was live, but the index had not been fully populated when we launched. Visitors who used site search — a higher-intent group — were getting incomplete results or empty states. They were leaving. This alone was suppressing conversion among the visitors most likely to buy.
Problem 2: The checkout redirect created a trust gap
Headless Shopify means the cart experience lives on the custom frontend, but checkout redirects to checkout.shopify.com. For visitors who did not recognize the domain switch, a small percentage abandoned at the checkout handoff. This is a known friction point in headless commerce — one that requires explicit trust-building on the cart page that we had not initially included.
Problem 3: The loyalty program lost its session continuity
The previous Shopify theme integration tracked loyalty points inline. The headless replacement did not surface the loyalty balance prominently during the cart flow. Returning customers who checked out partly to earn points — a segment the brand had cultivated carefully — were not seeing that incentive at the moment it mattered.
Problem 4: Mobile keyboard behavior on search
On certain Android devices, the search input was triggering the keyboard in a way that caused the page to reflow. The CLS score was near-zero on standard testing but showed degraded behavior on specific device/OS combinations. It was fixed within a week but affected a measurable portion of mobile visitors in the data window.
90 Days After Launch: The Real Picture
At the 90-day mark, with all four issues resolved, the conversion rate had recovered and then continued climbing.
| Metric | Pre-Migration | 30-Day Post | 90-Day Post |
|---|---|---|---|
| Conversion Rate | 1.6% | 1.4% | 2.3% |
| Cart Abandonment | 73% | 76% | 61% |
| Mobile Conversion | 0.9% | 0.8% | 1.7% |
| Organic Traffic | Baseline | +8% | +31% |
| Avg. Session Duration | 1:42 | 1:51 | 2:19 |
| Revenue per Visitor | Baseline | -5% | +44% |
The 90-day conversion rate of 2.3% places the store in the top 40% of fashion Shopify stores by industry benchmark. Mobile conversion nearly doubled from pre-migration levels. The 31% organic traffic increase reflects the Core Web Vitals improvement now acting as a ranking factor, plus structural SEO advantages that full Next.js control enabled — clean URL architecture, proper structured data, server-rendered metadata on every page.
The 44% increase in revenue per visitor is the number the brand tracks most closely. It accounts for both conversion rate improvement and a modest increase in average order value from a better product discovery experience.
What This Migration Actually Taught Us
There are three things we would tell any brand considering this move:
The speed gains are real and they are not the point
Yes, the Next.js build is faster. Yes, Core Web Vitals scores improve. Yes, organic rankings improve over time as a result. But these are second-order benefits. The real value of a custom Next.js storefront is control — over the checkout experience, the loyalty integration, the product discovery flow, the content strategy. Brands that migrate for speed alone and do not redesign the experience around the new capability miss most of the value.
The 30-day dip is predictable and plannable
Every headless migration we have been involved in shows a short-term conversion dip in the first 30–45 days. Integration gaps, unfamiliar flows, trust signals that did not carry over — these surface under live traffic in ways that staging environments do not reveal. Brands that plan for this window, monitor it actively, and have the engineering bandwidth to respond quickly recover faster. Brands that treat launch as the finish line lose weeks of revenue.
Shopify still runs the business. Next.js runs the experience
This distinction matters for client teams, especially non-technical stakeholders. Merchants still manage products, orders, fulfillment, and payments in Shopify. Nothing changes there. What changes is the layer their customers touch. Getting teams clear on this boundary before launch prevents a significant amount of post-launch confusion.
Who This Migration Is — and Is Not — For
A Shopify-to-Next.js migration makes sense when:
- Organic search is a primary growth channel and you are competing in keyword spaces where Core Web Vitals and SEO architecture create measurable ranking advantages.
- The store has complex content requirements that Shopify's template system cannot accommodate.
- The development team has React experience and the capacity to own a codebase long-term.
- Cart abandonment is concentrated at specific friction points that a custom frontend can address.
It does not make sense when:
- The store is under $1M in annual revenue and the engineering overhead exceeds the projected revenue gain.
- The team does not have ongoing technical resources to maintain the codebase.
- The primary issue is not the frontend — slow conversion caused by weak product-market fit or broken email flows will not be fixed by a faster website.
- The timeline is short and the migration requires replacing more than two or three third-party integrations simultaneously.
Final Note
The conversion rate change nobody expected was not the dip at 30 days. That was predictable in hindsight. The unexpected part was the 90-day number — a 44% increase in revenue per visitor on a store that was already performing at an average level before migration.
That outcome did not come from the framework. It came from the combination of performance gains, better product discovery, resolved integration issues, and a checkout flow that had been rethought rather than rebuilt identically.
Ready to evaluate a Shopify migration? At Dapp Formation, we evaluate whether the architecture matches the business case — not just the hype. See our recent work or talk to us.

