Why We Migrated an 80-Page WordPress Site to Next.js 16: An Unedited 14-Day Engineering Log
No marketing hype. Here is the actual step-by-step technical teardown of turning a bloated 38-plugin WordPress site into a sub-300ms Next.js web application.

Two months ago, an engineering consultancy in Austin approached us with a classic problem:
Their marketing site was built on WordPress back in 2020. Over four years, five different freelancers had worked on it. By the time we opened the wp-admin panel, the site was running:
- 38 active plugins (including 3 separate SEO plugins, WooCommerce for a 5-item digital store, and Slider Revolution).
- Elementor page builder nested inside custom shortcodes.
- A mobile Google PageSpeed score of 27 out of 100.
- A Largest Contentful Paint (LCP) of 5.1 seconds over 4G connections.
Their Google Ads agency informed them that their Google Quality Score had fallen from 8/10 to 4/10. Because Google penalizes slow landing page experiences, their Cost Per Click (CPC) had spiked by 42%.
Here is the exact 14-day protocol we followed to move the entire platform to Next.js 16 App Router on Vercel Edge—without losing a single ranking URL or dropping organic search impressions.
The Production Performance Benchmarks
Before touching code, we took baseline measurements using Google Lighthouse and WebPageTest:
| Metric | Legacy WordPress + Elementor | NovaMac Next.js 16 Build | Business Impact |
|---|---|---|---|
| Mobile PageSpeed | 27 / 100 🔴 | 99 / 100 🟢 | Google Quality Score improved to 9/10 |
| LCP (Largest Contentful Paint) | 5.1s 🔴 | 0.48s 🟢 | Bounce rate dropped from 48% to 19% |
| INP (Interaction to Next Paint) | 380ms 🔴 | 22ms 🟢 | Smooth UI response on mobile devices |
| Total Transfer Size | 4.9 MB | 320 KB | Fast rendering on weak mobile signals |
| Database Queries Per Page | 145 PHP queries | 0 (Pre-rendered Edge SSG) | Server hosting dropped from $120/mo to $0 |
The 14-Day Migration Protocol
Here is the breakdown of the exact process:
Phase 1 (Days 1–3): URL Slugs & Redirect Mapping
The single fastest way to destroy a company's organic search traffic is changing URL structures without identical redirects.
- We scraped every indexable URL using Screaming Frog.
- We mapped every permalink directly to the Next.js directory hierarchy.
- For legacy query parameters (e.g.,
?p=104), we configured edge redirects directly insidenext.config.ts:
// next.config.ts - Zero-latency CDN-level redirects
const nextConfig = {
async redirects() {
return [
{
source: "/old-services/:slug",
destination: "/services/:slug",
permanent: true, // Returns HTTP 301
},
];
},
};
Phase 2 (Days 4–7): Clean HTML Extraction
Instead of copying database garbage from WordPress wp_posts, we wrote a Node.js ingestion script that fetched content through the WordPress REST API (/wp-json/wp/v2/posts).
The script:
- Stripped inline Elementor
<style>tags and unnecessary inline font styles. - Extracted embedded images and ran them through the
sharpimage pipeline, creating WebP and AVIF formats with explicitwidthandheightparameters to eliminate Cumulative Layout Shift (CLS). - Saved the cleaned body text into structured Markdown records.
Phase 3 (Days 8–11): Zero-Client-JS Server Components
A major mistake developers make when building Next.js sites is slapping "use client" on every component. That turns Next.js into a heavy Single Page Application (SPA), dragging down performance.
We constructed all content pages as pure React 19 Server Components. The client browser receives zero megabytes of unnecessary React runtime code for marketing articles—just pure, blazing-fast HTML:
// Pure Server Component: Zero client bundle overhead
export default async function BlogPost({ params }: { params: { slug: string } }) {
const post = await getCleanPost(params.slug);
return (
<article className="max-w-3xl mx-auto py-12 px-6">
<h1 className="text-4xl font-extrabold text-[#1A1A1A]">{post.title}</h1>
<p className="text-gray-600 mt-2">{post.publishedDate}</p>
<div
className="prose mt-8 text-gray-800 leading-relaxed"
dangerouslySetInnerHTML={{ __html: post.html }}
/>
</article>
);
}
Phase 4 (Days 12–14): DNS Switchover & IndexNow Pings
We deployed the new site to Vercel and verified all 80 pages on a private staging URL.
- On launch day, we switched DNS records with a 300-second TTL. Total user-facing downtime: 0 seconds.
- Immediately after DNS propagation, we fired automated ping batches to the IndexNow API (supported by Bing, Yandex, and AI search engines) and submitted the fresh sitemap to Google Search Console.
What Happened to Organic Traffic 30 Days Later?
The results were immediate:
- Because the site went from a 5.1s loading penalty to a sub-500ms load time, Google's mobile crawler crawled 3.8x more pages per day without timeout errors.
- Organic impressions rose by 38% in the first month.
- Inbound demo requests doubled because visitors no longer bounced while waiting for hero banners to load.
If your business is currently held back by a sluggish WordPress or Elementor site, let us take a look. We will run a full audit and map out a clean migration roadmap.
Need This Architecture Implemented in Your Business?
Talk directly with NovaMac senior engineers. We will review your workflows, audit your current software costs, and deliver a zero-lock-in migration roadmap.
