WordPress naar Next.js: Financial Services SaaS bespaart $420K jaarlijks

Eind 2024 kwam een Series C financial services SaaS-bedrijf naar ons toe met een probleem dat hen echt geld kostte. Hun marketingsite, klantportaal en documentatiehub draaiden allemaal op WordPress met een warboel van premium plugins, een $420K/jaar enterprise CMS-licentiestack, en paginalaadtijden die hun compliance-team nerveus maakten. Ze moesten naar een moderne headless-architectuur zonder zelfs maar één seconde downtime — want in financial services betekent downtime regelgevingstoezicht, verloren vertrouwen en zeer dure telefoontjes van zeer serieuze mensen.

Dit is het volledige verhaal van hoe we het voor elkaar hebben gekregen.

Inhoudsopgave

WordPress naar Next.js-migratie: Financial SaaS bespaart $420K ARR

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 verdeeld over drie verschillende webproperties:

  1. Marketingsite — Productpagina's, landingspagina's, blog met 2.400+ posts
  2. Klantportaal — Accountdashboards, onboarding flows, documentbeheer
  3. Documentatiehub — API-documentatie, compliance-gidsen, integratietutorials

Alle drie draaiden op een enkele WordPress multisite-installatie gehost op WP Engine's enterprise-tier. De pluginsituatie was... iets bijzonders. Ze draaiden 47 actieve plugins, waaronder WPGraphQL, Advanced Custom Fields Pro, Yoast SEO Premium, WP Rocket, Gravity Forms, en een custom plugin die hun vorige agency had gebouwd voor SOC 2-compliance-logging van contentwijzigingen.

De echte pijnpunten:

  • Paginalaadtijden van gemiddeld 4,2 seconden op mobiel (Google CrUX-gegevens)
  • Core Web Vitals mislukt op 68% van de pagina's — LCP was brutal op 5,1s mediaan
  • $420K/jaar in licenties voor WP Engine enterprise hosting, premium plugins, een WAF, CDN, en een aparte staging-omgeving
  • Content editors wachtend op 8-12 seconden voor het WordPress admin-dashboard reageerde tijdens piekuren
  • Security patches vereisten speciale DevOps-tijd elke twee weken — de financial services-regelgevers dollen niet
  • Geen preview deployments — content team moest naar staging pushen en 4 minuten wachten op cache-invalidatie

Hun VP of Engineering zei ons tijdens het discovery-gesprek: "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 keus was

We evalueerden verschillende opties tijdens de architectuurfase. Hier is wat ter tafel lag:

Optie Voordelen Nadelen Geschatte jaarlijkse kosten
WordPress (geoptimaliseerd) Vertrouwd voor team, geen migratie nodig Nog steeds traag, licenties ongewijzigd $420K
Webflow Enterprise Visuele bewerking, snelle deployment Beperkt voor portal/app-behoeften, vendor lock-in $180K
Next.js + Sanity Bliksemnel, flexibel, live preview Migratiebewerking, team ramp-up $38K
Next.js + Contentful Sterke enterprise-functies, goede DX Per-user pricing schaalt slecht $95K
Astro + Storyblok Geweldig voor statische content, lichtgewicht Minder volwassen voor dynamische portaalbehoeften $42K

We hebben voor Next.js 14 (App Router) met Sanity als headless CMS gekozen. Hier is waarom:

  • FinEdge's portaal had dynamische, geverifieerde routes die server-side rendering nodig hadden. Next.js handelt dit native af met React Server Components.
  • Sanity's real-time samenwerking en GROQ query-taal gaven content editors een veel betere ervaring dan WordPress.
  • Het prijsmodel (Sanity's Growth-plan op $99/maand + Vercel Pro) betekende dat infrastructuurkosten van $420K tot ongeveer $38K per jaar daalde.
  • Hun engineeringteam kende React al. De ramp-up tot Next.js was gemeten in dagen, niet maanden.

We hebben Astro serieus overwogen voor de documentatiehub omdat het vooral statische content is, maar de operationele eenvoud van alles in één framework houden won het. Als de documentatiesite een standalone project was geweest, zou Astro de keuze zijn geweest.

De migratiearchitectuur

Hier is de architecture op hoog niveau die we hebben ontworpen:

┌─────────────────┐     ┌──────────────────┐
│   Sanity CMS     │────▶│  Next.js op       │
│   (Content)      │     │  Vercel (Edge)    │
└─────────────────┘     └──────────────────┘
         │                        │
         │                        ▼
         │               ┌──────────────────┐
         │               │  Cloudflare       │
         │               │  (DNS + WAF)      │
         │               └──────────────────┘
         │                        │
         ▼                        ▼
┌─────────────────┐     ┌──────────────────┐
│  Media Pipeline  │     │  Eindgebruikers   │
│  (Cloudinary)    │     └──────────────────┘
└─────────────────┘

De sleutelcomponenten:

Inhoudslaag

  • Sanity als primaire CMS voor marketing content, blogposts en documentatie
  • Custom Sanity-schemas die mapten naar hun bestaande WordPress-content types
  • Portable Text voor rijke content (ter vervanging van WordPress's Gutenberg-blokken)

Applicatielaag

  • Next.js 14 met App Router, gedeployd op Vercel's Pro-plan
  • React Server Components voor de marketingsite en docs
  • Client components alleen waar interactiviteit echt nodig was (formulieren, dashboards, interactieve grafieken)
  • Middleware voor authenticatie op portaalroutes, 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 — vervangen 3 WordPress-beeldplug-ins

WordPress naar Next.js-migratie: Financial SaaS bespaart $420K ARR - architecture

Zero Downtime-strategie: de parallelle uitvoering

Dit was het gedeelte dat me wakker hield. FinEdge kon zich zelfs maar een paar minuten downtime niet veroorloven. Hun klantportaal verwerkt financiële transacties, en elke onderbreking triggert verplichte incidentmeldingen aan regelgevers.

Hier is hoe we het hebben gedaan:

Fase 1: Content-synchronisatie (weken 1-3)

We hebben een custom WordPress-naar-Sanity sync-pipeline gebouwd die continu draaide gedurende 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(`${posts.length} posts gesynchroniseerd`)
}

// Draaide elke 5 minuten via cron

Dit betekende dat content editors in WordPress konden blijven werken gedurende de gehele migratie. Elke wijziging die ze maakten, werd automatisch binnen 5 minuten gesynchroniseerd naar Sanity.

Fase 2: Parallelle deployment (weken 4-8)

We hebben de Next.js-site op een subdomein (next.finedge.com) gedeployd en beide sites tegelijk draaiende gehouden. Ons QA-proces vergeleek elke enkele pagina:

  • Visuele regressietesting met Playwright over 200+ kritieke pagina's
  • SEO-pariteitscontroles (meta tags, structured data, canonieke URL's, sitemaps)
  • Prestatiecontroles op elk paginatemplate
  • Toegankelijkheidsaudits (WCAG 2.1 AA — vereist voor financial services)

Fase 3: De switchover (week 9)

De daadwerkelijke switch was anticlimactisch — wat precies is wat je wilt. We hebben Cloudflare's load balancing gebruikt om verkeer geleidelijk te verplaatsen:

  • Uur 0: 5% van het verkeer naar Next.js, 95% naar WordPress
  • Uur 2: 25% / 75% (controleren 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-gegevens 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 doorstaan 32% 98% +66%
Time to Interactive 6,8s 1,4s 4,9x sneller

De "3x sneller" headline doet het eigenlijk tekort aan. Op de meeste metreken hebben we 4-5x verbeteringen gezien. 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 de migratie. Hun SEO-team schreef dit vooral toe aan Core Web Vitals-verbeteringen en snellere crawlsnelheden van Googlebot.

De $420K-licentiebesparingen analyseren

Laten we het over geld hebben. Hier is precies waar de $420K heen ging en waardoor het werd 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 plug-in licenties (47 plug-ins) $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 (partiële FTE) $120.000 $30.000 $90.000
Totalen $520.000 $38.376 $481.624

De daadwerkelijke besparing bleek dichter bij de $482K te liggen, niet $420K. De oorspronkelijke $420K-schatting uit de discovery-fase was conservatief — we rekenden aanvankelijk niet in met de vermindering van DevOps-tijd of de eliminatie van driemaandelijkse beveiligingsaudits (Vercel en Cloudflare handelen het meeste af waar die audits zich mee bezighielden).

De ROI-wiskunde is eenvoudig. Ons migratieproject kostte FinEdge ongeveer $185K aan bureau-honoraria over de 10-weekse engagement. Die investering betaalde zichzelf terug in minder dan 5 maanden.

Technische verdieping: belangrijke implementatiedetails

2.400 blogposts afhandelen met ISR

We hebben niet alle 2.400 blogposts statisch gegenereerd op buildtijd. Dat zou deployments pijnlijk traag hebben 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 elk uur als fallback

export async function generateStaticParams() {
  // Genereer alleen de top 100 posts op traffic
  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 publiceren of bijwerken in Sanity, raakt een webhook ons 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 binnen 3 seconden op de live site. Vergelijk dat met de 4-minuten cache-invalidatie die ze hadden met WordPress + WP Rocket.

Authenticatie voor het klantportaal

De portaalroutes hadden server-side authenticatie 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 edge, dus niet-geverifieerde verzoeken worden omgeleid voordat ze zelfs de applicatieserver bereiken. Snel en veilig.

301 Redirect-kaart

We hadden ongeveer 340 URL's die van structuur veranderden gedurende de migratie. Een financial services-site kan absoluut geen verbroken links hebben — elke inkomende link van regelgevingsdocumenten, partnerwebsites en historische content moet correct oplossen.

We bouwden een redirect-kaart in next.config.js en vulden die aan met een dynamische redirect-lookup van Sanity voor door redactie beheerde redirects:

// next.config.js (gedeeltelijk)
module.exports = {
  async redirects() {
    return [
      // Statische redirects voor bekende URL-wijzigingen
      ...require('./redirects.json').map(r => ({
        source: r.from,
        destination: r.to,
        permanent: true,
      })),
    ]
  },
}

Zes maanden na de lancering toont Google Search Console nul 404-fouten van de migratie. Elke redirect werkt.

Lessen die we het zware hart hebben geleerd

1. WordPress Gutenberg-blokken zijn lastig om te converteren

We hebben de inspanning onderschat om Gutenberg-blokken naar Sanity's Portable Text te converteren. FinEdge had 23 verschillende blocktypen gebruikt, inclusief custom blokken die hun vorige agency hadden gebouwd. Reserveer 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 hebben drie trainingen van 90 minuten gegeven en een custom Sanity Studio met geleide workflows gemaakt. Het content team ging van sceptisch naar enthousiast binnen twee weken, maar die trainings-investering was kritisch.

3. Financial services compliance voegt complexiteit toe

Elke deployment had een audittrail nodig. Elke content-wijziging moest worden gelogd met timestamps en gebruikersattributie. We bouwden een custom Sanity-plug-in dat alle documentmutaties logt naar een append-only audittabel in hun bestaande PostgreSQL-database. Dit nam een extra week in beslag die niet in de oorspronkelijke scope zat.

4. Vergeet niet de 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 submissions naar hun bestaande HubSpot CRM. Deze migratie alleen nam al een week in beslag.

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 Portaal migratie, authenticatie, formulieren 3 devs
8 Documentatiehub, SEO-audit, redirect-kaart 2 devs, 1 SEO-specialist
9 QA, visuele regressie, performancetesten 2 devs, 1 QA
10 Geleidelijke verkeersswitch, monitoring, WordPress-decommissioning 2 devs, 1 DevOps

Piekteamgrootte was 4 personen. Het merendeel van het project draaide met 2-3 developers. Dit is geen 15-persoons, 6-maanden engagement — het is een gericht, ervaren team dat een goed geplande migratie uitvoert.

Als je een soortgelijke migratie voor je organisatie overweegt, hebben we ons headless CMS development approach gedocumenteerd en onze prijsstructuur is transparant. We spreken ook graag met je over je specifieke situatie — neem contact op hier.

Veelgestelde vragen

Hoe lang duurt een WordPress naar Next.js migratie typisch? 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, block types en plug-in-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 draaiende houden met een content sync-pipeline, dan DNS-niveau verkeersshifting gebruiken om geleidelijk gebruikers naar de nieuwe site te verplaatsen. We hebben dit succesvol voor meerdere clients gedaan. De kritische vereiste is dat je content over beide systemen in sync blijft gedurende de transittieperiode.

Hoeveel kost een WordPress naar headless CMS-migratie? Het hangt sterk af van scope. Een rechttoe rechtaan marketingsite-migratie kan $30K-$60K bedragen. Een enterprise-migratie zoals FinEdge's — 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 zichzelf terug in minder dan 5 maanden.

Is Next.js eigenlijk sneller dan WordPress? In vrijwel elk geval, ja — aanzienlijk sneller. WordPress genereert HTML bij elk verzoek (tenzij zwaar gecacht), en zelfs met caching-plug-ins zoals WP Rocket, ben je beperkt door PHP's antwoordtijd en het gewicht van het WordPress-ecosysteem. Next.js met ISR of statische generatie serveert voorgebouwde pagina's van de edge. We zien typisch 3-5x verbeteringen in Core Web Vitals.

Welke headless CMS moet ik gebruiken met Next.js? Het hangt af van je team en vereisten. Sanity blinkt uit in custom content modeling en real-time samenwerking. Contentful is sterk voor enterprise teams die een meer gestructureerde, opinionated aanpak willen, maar wordt duur per seat. Storyblok is geweldig als visuele bewerking 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: uitgebreide 301 redirect-mapping zodat geen bestaande URL's 404's retourneren, behoud van alle meta tags en structured data, en ingediende updated sitemaps naar Google Search Console onmiddellijk na cutover. FinEdge zag een 31% stijging in organisch verkeer binnen 90 dagen, grotendeels door Core Web Vitals-verbeteringen.

Wat gebeurt er met WordPress plug-ins na migratie? De functionaliteit van elke plug-in moet worden gerepliceerd of vervangen. Sommige zijn eenvoudig — SEO-plug-ins worden vervangen door metadata in je Next.js-componenten, caching-plug-ins worden onnodig, en form-plug-ins worden vervangen door React form-bibliotheken. Anderen, zoals custom compliance logging-plug-ins, hebben bespoke vervangende code nodig. Dit is waarom een grondige plug-in audit tijdens discovery essentieel is.

Kunnen content editors nog steeds een visuele editor gebruiken na het overgaan naar headless? Ja. Sanity Studio biedt een aanpasbare bewerkingsinterface met live preview. Het is anders dan WordPress's block editor, maar de meeste content teams prefereren het na de initiële leercurve. Sanity's Presentation tool biedt nu echte visuele bewerking met click-to-edit functionaliteit op de live preview. We zetten ook preview deployments op Vercel op zodat editors precies zien hoe hun content eruit zal zien voor publicatie.