Legacy CMS to Next.js2023Frontend lead4 months
Content Migration
Migrated 4,000 pages from a legacy PHP CMS to Next.js with a headless CMS, keeping every URL and improving organic traffic instead of losing it.
- Next.js
- Headless CMS
- Vercel
- Playwright
0
URLs lost
+22%
organic sessions after 3 months
98
median Lighthouse performance
The problem
The old CMS was slow, insecure and blocked the marketing team. Previous migration attempts stalled on fear of losing SEO.
Constraints
- No broken URLs
- Editors keep working during the move
- Bilingual content
Architecture
Authoring
Headless CMS
Preview
Build
Next.js ISR
Redirect map
Verify
Playwright crawl
Lighthouse CI
Key decisions
Decision 01
Crawl-based verification
A Playwright crawler compared status codes, canonicals and titles between old and new sites for every URL before each cut-over.
Trade-off: A slow nightly job, but it caught 300+ issues before users did.
In the code
scripts/verify-urls.ts
1for (const path of await sitemap(LEGACY)) {2 const [before, after] = await Promise.all([inspect(LEGACY + path), inspect(NEXT + path)]);34 if (after.status !== 200 && after.status !== 308) report.broken(path, after.status);5 if (before.canonical !== after.canonical) report.diff(path, "canonical");6 if (before.title !== after.title) report.diff(path, "title");7}What I learned
- Migrations fail on fear. Measurement removes the fear.