We migrated a B2B company's site from a heavily-customised WordPress setup to Next.js. This is the honest account of what took longer than we expected, what went smoothly, and the performance numbers before and after.
The starting point
The site was a B2B services company — 12 pages plus a blog, about 4 years of content. The WordPress setup had accumulated the usual entropy: a page builder (Elementor), 23 active plugins, a theme that had been customised so heavily it no longer resembled the original.
The PageSpeed score on mobile was 34. The Largest Contentful Paint was 6.2 seconds. Load time on a real mid-range Android device: 9.4 seconds.
What went smoothly
The design. New visual design in Figma, reviewed in two rounds, approved before build started. No mid-build design changes because the design was done before we wrote the first line of code.
Content migration. We wrote a custom Node script to pull content from the WordPress REST API, transform it into the content schema, and import it. About 3 hours of work. 4 years of blog posts migrated cleanly.
The Next.js build. With Tailwind and a clear component library, the actual build moved fast.
What took longer than expected
URL redirect mapping. The old site had 180+ URLs, many of them in WordPress's default /?p=123 format, some with trailing slashes, some without. We had to audit all of them and build a complete redirect map. Getting this wrong would have meant losing 4 years of inbound link equity.
Third-party integrations. The WordPress site had HubSpot embedded via a plugin. The client's HubSpot setup used WordPress-specific tracking triggers that no longer existed after the migration.
Client content review. The content we migrated was accurate but outdated. The client used the redesign as an opportunity to update copy they'd been meaning to update for two years. That's scope creep that adds time.
The performance results
| Metric | Before (WordPress) | After (Next.js) |
|---|---|---|
| PageSpeed Mobile | 34 | 91 |
| LCP | 6.2s | 1.1s |
| Total Blocking Time | 2,340ms | 110ms |
| CLS | 0.24 | 0.02 |
What we'd do differently
Scope the redirect audit explicitly. Include it in every WordPress migration scope as its own line item.
Front-load the third-party integration audit. Before build starts, list every external tool that's embedded in the old site and confirm how it will be implemented in the new site.
Set copy freeze dates. Once the design is locked, the copy should be locked. Changes after build starts are always more expensive than they look.



