WordPress naar Next.js Migratie: Financial SaaS Bespaart $420K ARR
Je compliance officer stuurt om 21:47 uur een e-mail: pagina's laden in 4,2 seconden en dat is een regelgevingsrisico. Je CFO stuurt een uur later de jaarlijkse CMS-verlenging van $420K door met één woord: 'Waarom?' Beide threads wijzen naar dezelfde WordPress-monoliet — een marketingsite, klantportaal en documentatiehub bij elkaar gehouden door 19 premium plugins en een licentiestack die meer kost dan twee engineers. De Series C financial SaaS achter deze e-mails had een headless Next.js-migratie nodig die downtime elimineerde, want in fintech triggert elke offline seconde regelgevingsonderzoek en boze telefoontjes van enterprise-klanten. Ze hadden ook nodig dat de kostenstructuur zinvol was voor de volgende boardvergadering. We bouwden de migratie in 90 dagen en sneden de infrastructuurkosten met 73% terwijl we de paginasnelheid verdrievoudigden — maar het moeilijkste deel was niet de code.
Dit is het volledige verhaal van hoe we dit hebben gedaan.
Inhoudsopgave
- Het startpunt: een WordPress-monoliet onder druk
- Waarom Headless Next.js de juiste keuze was
- De migratiearchitectuur
- Zero-downtime strategie: de parallelle run
- Prestatieresultaten: 3x sneller en nog meer
- De besparing op $420K licenties uitgesplitst
- Technische diepteduik: sleutelimplementatiedetails
- Lessen op de harde manier geleerd
- Tijdlijn en teamstructuur
- Veelgestelde vragen

Het startpunt: een WordPress-monoliet onder druk
Laat me het plaatje schetsen. Dit bedrijf — we noemen ze FinEdge (NDA, je begrijpt het) — had ongeveer 12.000 pagina's content over drie verschillende webpaginasets verspreid:
- Marketingsite — Productpagina's, landingspagina's, blog met 2.400+ posts
- Klantportaal — Accountdashboards, onboarding flows, documentbeheer
- Documentatiehub — API-docs, compliance guides, integratietutorials
Alledrie draaiden op een enkele WordPress multisite-installatie gehost op WP Engine's enterprise-tier. De pluginsituatie was... iets. Ze liepen 47 actieve plugins, inclusief WPGraphQL, Advanced Custom Fields Pro, Yoast SEO Premium, WP Rocket, Gravity Forms, en een custom plugin die hun vorige agency bouwde en die SOC 2-compliance logging voor contentveranderingen afhandelde.
De echte pijnpunten:
- Gemiddelde laadtijden van 4,2 seconden op mobiel (Google CrUX-data)
- Core Web Vitals mislukt op 68% van pagina's — LCP was verpletterd op 5,1s mediaan
- $420K/jaar in licenties over WP Engine enterprise hosting, premium plugins, een WAF, CDN, en een aparte staging-omgeving
- Content editors wachten 8-12 seconden tot de WordPress admin reageert tijdens piekuren
- Beveiligingspatches vereisten dedicated DevOps-tijd elke twee weken — financial services regulators grappen niet
- Geen preview deployments — content team moest pushen naar staging en 4 minuten wachten op cache-invalidatie
Hun VP of Engineering vertelde ons tijdens de discovery call: "We geven meer uit aan onze website-infrastructuur dan aan twee senior engineers. En het is nog steeds traag."
Waarom Headless Next.js de juiste keuze was
We evalueerden verschillende opties tijdens de architectuurfase. Dit stond op tafel:
| Optie | Voordelen | Nadelen | Geschatte jaarlijkse kosten |
|---|---|---|---|
| WordPress (geoptimaliseerd) | Vertrouwd voor team, geen migratie nodig | Nog steeds traag, licenties ongewijzigd | $420K |
| Webflow Enterprise | Visueel bewerken, snelle deployment | Beperkt voor portal/app behoeften, vendor lock-in | $180K |
| Next.js + Sanity | Bliksemend snel, flexibel, real-time preview | Migratiepoging, team ramp-up | $38K |
| Next.js + Contentful | Sterke enterprise-features, goede DX | Per-user pricing schaalt slecht | $95K |
| Astro + Storyblok | Geweldig voor statische content, licht | Minder volwassen voor dynamische portal behoeften | $42K |
We gingen voor Next.js 14 (App Router) met Sanity als headless CMS. Hier is waarom:
- FinEdge's portaal had dynamische, geverifieerde routes die server-side rendering nodig hadden. Next.js handelt dit nief met React Server Components af.
- Sanity's real-time samenwerking en GROQ query language gaven content editors een dramatisch betere ervaring dan WordPress.
- Het prijsmodel (Sanity's Growth plan op $99/maand + Vercel Pro) betekende dat infrastructuurkosten daalden van $420K naar ongeveer $38K jaarlijks.
- FinEdge's engineering team kende al React. De ramp-up naar Next.js werd gemeten in dagen, niet maanden.
We hebben serieus nagedacht over Astro voor de documentatiehub omdat het grotendeels statische content is, maar de operationele eenvoud van alles in één framework te houden won. Als de docs site een zelfstandig project was geweest, zou Astro de keuze zijn geweest.
De migratiearchitectuur
Hier is de architectuur op hoog niveau die we hebben ontworpen:
┌─────────────────┐ ┌──────────────────┐
│ Sanity CMS │────▶│ Next.js on │
│ (Content) │ │ Vercel (Edge) │
└─────────────────┘ └──────────────────┘
│ │
│ ▼
│ ┌──────────────────┐
│ │ Cloudflare │
│ │ (DNS + WAF) │
│ └──────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Media Pipeline │ │ End Users │
│ (Cloudinary) │ └──────────────────┘
└─────────────────┘
De kerncomponenten:
Content-laag
- Sanity als primaire CMS voor marketingcontent, blogposts en documentatie
- Custom Sanity schemas die naar hun bestaande WordPress-inhoudstypen toegewezen
- Draagbare tekst voor rijke content (vervanging van WordPress's Gutenberg blokken)
Toepassingslaag
- Next.js 14 met App Router, geïmplementeerd op Vercel's Pro plan
- React Server Components voor de marketingsite en docs
- Client-componenten alleen waar interactiviteit echt nodig was (formulieren, dashboards, interactieve grafieken)
- Middleware voor verificatie op portal routes, geïntegreerd met hun bestaande Auth0 setup
Infrastructuurlaag
- Vercel voor hosting en edge functies
- Cloudflare voor DNS-beheer en aanvullende WAF-regels (financial services compliance vereiste)
- Cloudinary voor beeldoptimalisatie en transformatie — verving 3 WordPress afbeeldingsplugins

Zero-downtime strategie: de parallelle run
Dit was het gedeelte dat me wakker hield. FinEdge kon zich niet eens een paar minuten downtime veroorloven. Hun klantportaal verwerkt financiële transacties, en elke onderbreking triggert verplichte incident rapportering aan regelgevers.
Hier is hoe we het deden:
Fase 1: Content sync (weken 1-3)
We bouwden een custom WordPress-naar-Sanity sync pipeline die continu liep tijdens de migratieperiode:
// Vereenvoudigde versie van onze WP-naar-Sanity sync worker
import { createClient } from '@sanity/client'
import WPGraphQL from './wp-graphql-client'
const sanity = createClient({
projectId: process.env.SANITY_PROJECT_ID,
dataset: 'production',
token: process.env.SANITY_WRITE_TOKEN,
apiVersion: '2024-10-01',
useCdn: false,
})
async function syncPosts(since: string) {
const posts = await WPGraphQL.getModifiedPosts(since)
const transaction = sanity.transaction()
for (const post of posts) {
const sanityDoc = transformWPToSanity(post)
transaction.createOrReplace(sanityDoc)
}
await transaction.commit()
console.log(`Synced ${posts.length} posts`)
}
// Liep elke 5 minuten via cron
Dit betekende dat content editors in WordPress konden blijven werken tijdens de gehele migratie. Elke verandering die ze maakten werd automatisch in 5 minuten naar Sanity gesynchroniseerd.
Fase 2: Parallelle deployment (weken 4-8)
We implementeerden de Next.js site op een subdomein (next.finedge.com) en liepen beide sites gelijktijdig. Ons QA-proces vergeleek elke enkele pagina:
- Visuele regression testing met Playwright op 200+ kritieke pagina's
- SEO-pariteitscontroles (meta tags, gestructureerde data, canonieke URL's, sitemaps)
- Prestatiemarkering op elke paginasjabloon
- Toegankelijkheidsaudits (WCAG 2.1 AA — vereist voor financial services)
Fase 3: De overschakeling (week 9)
De daadwerkelijke switch was anti-climactisch — wat precies is wat je wilt. We gebruikten Cloudflare's load balancing om het verkeer geleidelijk te verschuiven:
- Uur 0: 5% verkeer naar Next.js, 95% naar WordPress
- Uur 2: 25% / 75% (monitoring foutpercentages, Core Web Vitals)
- Uur 6: 50% / 50%
- Uur 12: 90% / 10%
- Uur 24: 100% Next.js, WordPress in read-only modus
- Week 2: WordPress buiten bedrijf gesteld
Nul fouten. Nul downtime. De monitoring dashboards waren saai groen.
Prestatieresultaten: 3x sneller en nog meer
Hier zijn de echte nummers, gemeten 30 dagen na de migratie met Google CrUX data en Vercel Analytics:
| Metriek | WordPress (Voor) | Next.js (Na) | Verbetering |
|---|---|---|---|
| LCP (p75) | 5,1s | 1,2s | 4,25x sneller |
| FID / INP (p75) | 280ms | 68ms | 4,1x sneller |
| CLS (p75) | 0,18 | 0,02 | 9x beter |
| TTFB (p75) | 1,8s | 0,12s | 15x sneller |
| Lighthouse Performance | 34 | 96 | +62 punten |
| Pagina's die CWV passeren | 32% | 98% | +66% |
| Tijd tot interactief | 6,8s | 1,4s | 4,9x sneller |
De '3x sneller' kop onderdoet het eigenlijk. Op de meeste metrische waarden zagen we 4-5x verbeteringen. TTFB was de ster — van 1,8 seconden naar 120 milliseconden dankzij Vercel's Edge Network en ISR (Incremental Static Regeneration).
Organisch verkeer steeg 31% in de eerste 90 dagen na migratie. Hun SEO-team schreef dit vooral toe aan Core Web Vitals-verbeteringen en snellere crawlsnelheden van Googlebot.
De besparing op $420K licenties uitgesplitst
Laten we het over geld hebben. Hier is precies waar de $420K naartoe ging en wat het vervangen:
| Regelitem | WordPress jaarlijkse kosten | Next.js jaarlijkse kosten | Besparing |
|---|---|---|---|
| WP Engine Enterprise hosting | $150.000 | — | $150.000 |
| Vercel Pro (Team plan) | — | $2.400 | — |
| Premium plugin licenties (47 plugins) | $28.000 | — | $28.000 |
| Sanity Growth plan | — | $1.188 | — |
| Cloudinary Pro | — | $2.388 | — |
| Enterprise WAF (Sucuri) | $36.000 | — | $36.000 |
| Cloudflare Pro | — | $2.400 | — |
| Custom WordPress onderhoudscontract | $96.000 | — | $96.000 |
| CDN (apart van WP Engine) | $24.000 | — | $24.000 |
| Staging omgeving hosting | $18.000 | — | $18.000 |
| WordPress beveiligingsaudits (driemaandelijks) | $48.000 | — | $48.000 |
| DevOps teamtijd (gedeeltelijke FTE) | $120.000 | $30.000 | $90.000 |
| Totalen | $520.000 | $38.376 | $481.624 |
De werkelijke besparing bleek dichter bij $482K te liggen, niet $420K. De originele schatting van $420K uit de discovery fase was conservatief — we hielden aanvankelijk geen rekening met de verlaging van DevOps-tijd of de eliminatie van driemaandelijkse beveiligingsaudits (Vercel en Cloudflare handelen het grootste deel van wat die audits dekte af).
De ROI-wiskunde is eenvoudig. Ons migratieproject kostte FinEdge ongeveer $185K aan agencykosten over de 10-weekse engagement. Die investering betaalde zichzelf in minder dan 5 maanden terug.
Technische diepteduik: sleutelimplementatiedetails
2.400 blogposts afhandelen met ISR
We genereerden niet alle 2.400 blogposts statisch bij build time. Dat zou deployments pijnlijk traag gemaakt. In plaats daarvan gebruikten we ISR met on-demand revalidatie:
// app/blog/[slug]/page.tsx
import { sanityFetch } from '@/lib/sanity'
import { postQuery } from '@/lib/queries'
export const revalidate = 3600 // Revalideer elke uur als fallback
export async function generateStaticParams() {
// Genereer alleen vooraf de top 100 posts op verkeer
const topPosts = await sanityFetch({
query: `*[_type == "post"] | order(pageViews desc) [0...100] { "slug": slug.current }`
})
return topPosts.map((post) => ({ slug: post.slug }))
}
export default async function BlogPost({ params }) {
const post = await sanityFetch({
query: postQuery,
params: { slug: params.slug },
tags: [`post:${params.slug}`]
})
// ... render post
}
Wanneer content editors in Sanity publiceren of bijwerken, raakt een webhook onze revalidatie endpoint:
// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache'
import { NextRequest } from 'next/server'
export async function POST(req: NextRequest) {
const body = await req.json()
const secret = req.headers.get('x-sanity-webhook-secret')
if (secret !== process.env.SANITY_WEBHOOK_SECRET) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
// Revalideer specifieke content
if (body._type === 'post') {
revalidateTag(`post:${body.slug.current}`)
revalidateTag('posts-list')
}
return Response.json({ revalidated: true })
}
Content-updates verschijnen nu op de live site in minder dan 3 seconden. Vergelijk dat met de 4-minuten cache-invalidatie die ze met WordPress + WP Rocket hadden.
Verificatie voor het klantportaal
De portal routes hadden server-side verificatie nodig. We gebruikten Next.js middleware gecombineerd met hun bestaande Auth0 setup:
// middleware.ts
import { NextResponse } from 'next/server'
import { getSession } from '@auth0/nextjs-auth0/edge'
export async function middleware(req) {
if (req.nextUrl.pathname.startsWith('/portal')) {
const session = await getSession(req, NextResponse.next())
if (!session?.user) {
return NextResponse.redirect(new URL('/api/auth/login', req.url))
}
}
return NextResponse.next()
}
export const config = {
matcher: ['/portal/:path*']
}
Dit draait aan de rand, dus niet-geverifieerde verzoeken worden omgeleid voordat ze zelfs de applicationserver bereiken. Snel en veilig.
301 Redirect kaart
We hadden ongeveer 340 URL's die van structuur veranderde tijdens de migratie. Een financial services site kan absoluut geen verbroken links hebben — elke inkomende link van regelgevingsdocumenten, partnersites en historische content moet correct oplossen.
We bouwden een redirect kaart in next.config.js en vulden het aan met een dynamische redirect lookup van Sanity voor editor-beheerde redirects:
// next.config.js (gedeeltelijk)
module.exports = {
async redirects() {
return [
// Statische redirects voor bekende URL-veranderingen
...require('./redirects.json').map(r => ({
source: r.from,
destination: r.to,
permanent: true,
})),
]
},
}
Ses maanden na lancering toont Google Search Console nul 404 fouten van de migratie. Elke enkele redirect werkt.
Lessen op de harde manier geleerd
1. WordPress Gutenberg blokken zijn pijnlijk om te converteren
We onderschatten de inspanning om Gutenberg blokken naar Sanity's Portable Text te converteren. FinEdge had 23 verschillende bloktypen gebruikt, inclusief aangepaste blokken die hun vorige agency bouwde. Budget minstens 20% meer tijd dan je denkt voor content transformatie.
2. Content editor training is niet optioneel
Sanity's Studio is intuïtief, maar het is niet WordPress. We liepen drie trainingen van 90 minuten en creëerden een aangepaste Sanity Studio met begeleide workflows. Het content team ging van skeptisch naar enthousiast binnen twee weken, maar die training investering was kritisch.
3. Financial services compliance voegt complexiteit toe
Elke deployment had een audittrail nodig. Elke content verandering moest geregistreerd worden met tijdstempels en gebruikerstoekenning. We bouwden een aangepaste Sanity plugin die alle document mutaties registreert in een append-only audit tabel in hun bestaande PostgreSQL database. Dit nam een extra week die niet in de originele scope zat.
4. Vergeet niet over formulieren
Gravity Forms handelde 14 verschillende formuliertypen op de WordPress site af. We vervingen ze met React Hook Form + Zod validatie op de frontend en server actions op de backend, met indieningen gaande naar hun bestaande HubSpot CRM. Deze migratie alleen nam een volledige week.
Tijdlijn en teamstructuur
Totale projectduur: 10 weken
| Week | Focus | Team |
|---|---|---|
| 1 | Architectuur, Sanity schema ontwerp, content audit | 2 devs, 1 architect |
| 2-3 | Content sync pipeline, Sanity Studio aanpassing | 2 devs, 1 content strategist |
| 4-5 | Marketing site build (Next.js) | 3 devs |
| 6-7 | Portal migratie, verificatie, formulieren | 3 devs |
| 8 | Documentatiehub, SEO audit, redirect kaart | 2 devs, 1 SEO specialist |
| 9 | QA, visuele regression, prestatietesting | 2 devs, 1 QA |
| 10 | Geleidelijke verkeersverschuiving, monitoring, WordPress buiten bedrijf | 2 devs, 1 DevOps |
Piek teamgrootte was 4 personen. Het grootste deel van het project liep met 2-3 developers. Dit is geen 15-personen, 6-maanden engagement — het's een gefocuste, ervaren team die een goed geplande migratie uitvoert.
Als je een vergelijkbare migratie voor je organisatie overweegt, hebben we onze benadering voor headless CMS development gedocumenteerd en onze prijsstructuur is transparant. We helpen ook graag bij een gesprek over jouw specifieke situatie — bereik ons hier.
Veelgestelde vragen
Hoe lang duurt een WordPress naar Next.js migratie meestal? Voor een site van deze complexiteit (12.000 pagina's, klantportaal, documentatiehub), is 10 weken realistisch met een ervaren team. Eenvoudiger marketingsites met 100-500 pagina's kunnen in 4-6 weken gemigreerd worden. De grootste variabele is content complexiteit — hoeveel custom post types, bloktypen en plugin-afhankelijke features je draait.
Kun je WordPress naar Next.js migreren zonder enige downtime? Ja, maar het vereist planning. De sleutel is beide systemen parallel draaien met een content sync pipeline, dan DNS-level traffic shifting gebruiken om gebruikers geleidelijk naar de nieuwe site te verplaatsen. We hebben dit met succes gedaan voor meerdere klanten. De kritieke vereiste is dat je content in beide systemen gesynchroniseerd blijft tijdens de transitieperiode.
Hoeveel kost een WordPress naar headless CMS migratie? Het hangt zwaar af van scope. Een eenvoudige marketingsite migratie zou $30K-$60K kunnen zijn. Een enterprise migratie zoals FinEdge — met een klantportaal, compliance vereisten, en 12.000 pagina's — was $185K. De ROI berekening is belangrijker dan de absolute kosten. FinEdge's investering betaalde zich in minder dan 5 maanden terug door alleen al licentiebesparingen.
Is Next.js werkelijk sneller dan WordPress? In vrijwel elk geval, ja — significant sneller. WordPress genereert HTML op elk verzoek (tenzij zwaar gecached), en zelfs met caching plugins zoals WP Rocket, ben je beperkt door PHP's responstijd en het gewicht van het WordPress ecosysteem. Next.js met ISR of statische generatie serveert vooraf gebouwde pagina's van de rand. We zien gewoonlijk 3-5x verbeteringen in Core Web Vitals.
Welk headless CMS moet ik met Next.js gebruiken? Het hangt af van je team en vereisten. Sanity blinkt uit in aangepaste content modellering en real-time samenwerking. Contentful is sterk voor enterprise teams die een meer gestructureerde, opinierenichter benadering willen maar krijgt duur per-seat. Storyblok is geweldig als visueel bewerken een prioriteit is. Voor eenvoudiger sites kunnen zelfs Markdown bestanden in een Git repo werken. We evalueren dit per project — er is geen universeel antwoord.
Verlies je SEO wanneer je van WordPress naar Next.js migreert? Niet als je het goed doet. De drie dingen die tellen: uitvoerige 301 redirect mapping zodat geen bestaande URL's 404s retourneren, alle meta tags en gestructureerde data behouden, en bijgewerkte sitemaps onmiddellijk na cutover naar Google Search Console indienen. FinEdge zag een 31% stijging van organisch verkeer binnen 90 dagen, grotendeels gedreven door Core Web Vitals verbeteringen.
Wat gebeurt er met WordPress plugins na migratie? De functionaliteit van elke plugin moet gerepliceerd of vervangen worden. Sommige zijn eenvoudig — SEO plugins worden vervangen door metadata in je Next.js componenten, caching plugins worden onnodig, en form plugins worden vervangen met React form libraries. Anderen, zoals aangepaste compliance logging plugins, hebben bespoke vervangingscode nodig. Dit is waarom een grondige plugin audit tijdens discovery essentieel is.
Kunnen content editors nog steeds een visuele editor gebruiken na overgaan naar headless? Ja. Sanity Studio biedt een aanpasbare bewerkingsinterface met real-time preview. Het is anders dan WordPress's block editor, maar de meeste content teams geven het voorkeur na de initiële leercurve. Sanity's Presentation tool biedt nu waar visueel bewerken met click-to-edit functionaliteit op de live preview. We stelden ook preview deployments op Vercel in zodat editors precies kunnen zien hoe hun content eruit ziet voor publicatie.