Skip to content
Pra
All work

Global Health & Security Digital Platform · 2025–26 · Frontend developer

Rebuilding a global enterprise site on the App Router

Incremental migration of a 4,000-page Sitecore front end to Next.js, route by route, with both stacks serving live traffic throughout.

Pages migrated
4,000+
LCP, 75th pct
1.2s
Rollback events
0

Stack

  • Next.js
  • TypeScript
  • Sitecore XM Cloud
  • GraphQL
  • Tailwind CSS
  • Playwright

The problem

A large, long-lived Sitecore front end had accumulated a decade of decisions. Rendering was server-side MVC, the CSS had no clear ownership boundaries, and Core Web Vitals in the field were well outside thresholds on the highest-traffic templates. A full rebuild had been scoped twice and shelved twice — correctly, because the site could not stop shipping content for six months.

The constraint that shaped everything: the site had to stay live and editable throughout, across dozens of country sites and several content teams.

The approach

We put a routing layer in front of both applications. Every request defaulted to the legacy stack; routes were moved to Next.js one template at a time by adding them to the proxy's allow-list. That made each release small, and — more importantly — reversible by changing one line.

Sequencing was chosen for risk rather than visibility. Standard content pages first, because they were the highest page-count and lowest complexity, which let us prove out routing, content queries, the layout shell and the deploy pipeline on pages where a mistake was cheap. Forms, personalisation and third-party embeds came last, once the infrastructure had stopped moving.

Design consistency across two live stacks was handled by publishing the design tokens as a shared package. Both applications consumed the same colour, type and spacing values, so the brand stayed identical without attempting to share component code between two incompatible rendering models.

What was hard

The content layer, not the rendering. Fields were being used for two different purposes depending on template, presentation details were stored as content, and some components behaved differently based on their position in the content tree. We audited it deliberately — not to fix everything, but to decide explicitly what we were reproducing faithfully and what we were dropping.

Keeping the legacy application healthy was the other discipline. A migration that runs for a year is a system you're maintaining, not one you're abandoning.

The outcome

Migrated templates moved comfortably inside Core Web Vitals thresholds on field data, and the incremental approach meant no single high-risk cutover event ever happened. The editorial experience was unchanged for content teams, which was a hard requirement and the thing most likely to have derailed adoption.