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

Architecture

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