Client websites
Production business websites, most migrated to Next.js and shipped fast.
[ The set ]
12 sites, one playbook.
Every one live, and every one with its own write-up — sector, region, what the build involved and the URL.
[ The transformation ]
Multiple UK businesses were on older stacks — Vite/React SPAs and WordPress — that were slower, harder to maintain, and weaker on SEO.
Older SPA and WordPress sites became fast, static, SEO-clean Next.js builds — migrated with zero downtime and no visual change.
[ The hard problem ]
Migrating live production sites with zero downtime — the old site stays untouched until the new one is verified pixel-identical. One wrong redirect and the client's business goes dark.
[ How it works ]
I built a repeatable, safe migration playbook — branch-isolated, zero-downtime, verified pixel-identical before cutover. Two named examples:
Single-page apps that search engines could not read
Vite and React-Router builds served as one document with one title and no per-page metadata. Converted to Next.js App Router with file-based routing, every route pre-rendered static and addressable on its own.
SEO managed client-side
react-helmet-async replaced with the Next Metadata API, preserving page titles, descriptions and LocalBusiness structured data through a full framework change.
Browser-only libraries breaking the server render
Interactive maps and similar client-only dependencies wired through ssr:false dynamic imports, so they cannot take a server render down.
Cutover risk
Every migration branch-isolated and verified pixel-identical before the switch. The live site stayed untouched until the moment it was replaced.
[ Key features ]
Branch-isolated, zero-downtime migration playbook — repeatable across every client
react-router → next/link route conversion with file-based routing
react-helmet-async → Next.js Metadata API with preserved SEO and JSON-LD
Browser-only Leaflet maps via ssr:false dynamic imports
Per-page metadata for SEO that the SPAs never had
Page-by-page visual verification before cutover
[ The result ]
















