Ik ben de tel kwijtgeraakt hoeveel keer ik dit heb gehoord: "WordPress was prima toen we begonnen, maar nu..." En dan komt de lijst. De site laadt in 6 seconden. De contactformulier plugin brak na de laatste update. Er zit een kritieke beveiligingsfout in een plugin die sinds 2022 niet meer is bijgewerkt. De developer die het originele theme heeft gebouwd, is verdwenen. Herkenbaar?

Dit is het puntje ervan -- WordPress drijft meer dan 40% van het web aan, en daar is goeie reden voor. Het is toegankelijk, het heeft een massief ecosysteem, en het zette veel bedrijven snel online. Maar er is een verschil tussen een tool die je op gang helpt en een tool die met je meeschaalt. Als je dit leest, ben je waarschijnlijk tegen die muur opgelopen. Laat me je laten zien hoe een echte migratie van WordPress naar een headless Next.js + Supabase architectuur eruitziet -- niet de marketingversie, maar het echte engineering playbook.

Inhoudsopgave

Bent je WordPress ontgroeid? Een Migration Playbook voor Next.js + Supabase

Tekenen dat je WordPress echt bent ontgroeid

Niet iedereen hoeft WordPress te verlaten. Ik wil hier eerlijk over zijn. Als je een persoonlijke blog runt of een brochuresite voor een lokaal bedrijf, WordPress met een andig theme en een handvol plugins is waarschijnlijk nog steeds de juiste keuze. Maar er zijn duidelijke signalen dat je eraan bent ontgroeid:

Plugin conflicten breken maandelijks dingen

Je werkt WooCommerce bij en je page builder breekt. Je werkt je page builder bij en je SEO plugin geeft waarschuwingen. Je werkt PHP bij naar 8.2 omdat je host dat vereist en drie plugins werken helemaal niet meer. Dit is geen bug -- dit is de architectuur. WordPress plugins delen allemaal dezelfde globale scope, dezelfde hooks, dezelfde database. Elke plugin is een potentieel conflict met elke andere plugin.

Ik heb WordPress sites geaudit met 30, 40, zelfs 60+ actieve plugins. Op dat moment onderhoud je niet een website. Je onderhoudt een Jenga-toren.

Performance is een fulltime baan geworden

Je PageSpeed score is in de 30's. Je hebt een cache plugin, een afbeeldingsoptimalisatie plugin, een minificatie plugin en een CDN plugin geïnstalleerd -- allemaal om prestatiekwesties op te lossen die de andere 25 plugins hebben veroorzaakt. De ironie is dik.

WordPress genereert pagina's dynamisch bij elk request (tenzij gecached). Elke plugin kan zijn eigen CSS en JavaScript bestanden injecteren. Een typische WordPress pagina met populaire plugins laadt 15-30 aparte render-blocking resources. Google's 2024 Core Web Vitals data toont aan dat WordPress sites een 33% slagingspercentage hebben op alle drie CWV metrics, vergeleken met 52% voor sites gebouwd met moderne JavaScript frameworks.

Beveiligingskwetsbaarheden houden je wakker

WPScan's 2024 kwetsbaarheidsdatabase traceerde meer dan 7.000 nieuwe WordPress kwetsbaarheden dat jaar -- de overgrote meerderheid in plugins en themes. Als je een site runt die gebruikersgegevens, betalingen of enig soort gevoelige informatie afhandelt, is elke plugin een aanvalsoppervlak. Patchstack meldde dat 97% van WordPress beveiligingskwetsbaarheden in 2024 afkomstig waren van plugins.

Je vertrouwt eigenlijk tientallen onafhankelijke developers -- waarvan velen plugins als bijzaak onderhouden -- met je beveiligingspostuur.

Je dev team haat eraan te werken

Dit is ondergewaardeerd. Goede developers willen niet meer in WordPress werken. De PHP-template-spaghetti-met-ACF-fields workflow is pijnlijk vergeleken met moderne component-based development. Als je engineering talent wilt aantrekken en behouden, speelt je tech stack een rol.

De WordPress belasting: Wat plugin hell echt kost

Laat me hier wat getallen op zetten. Voor een middelgrote WordPress site (zeg een e-commerce site of een SaaS marketing site met een blog, gebruikersaccounts en aangepaste functionaliteit), ziet de jaarlijkse "WordPress belasting" er typisch zo uit:

Kostencategorie Jaarlijkse schatting
Premium plugin licenties (15-20 plugins) €1.350 - €3.600
Beheerde WordPress hosting (WP Engine, Kinsta) €1.080 - €5.400
Beveiligingsmonitoring + opschoning (Sucuri, Wordfence) €270 - €450
Performance optimalisatietijd (developer uren) €2.700 - €7.200
Plugin conflict debugging (developer uren) €1.800 - €5.400
Noodoplossingen van updates die dingen breken €900 - €3.600
Totale jaarlijkse WordPress belasting €8.100 - €25.650

Dat is nog voordat je een enkel nieuwe feature bouwt. Dit is de kost om de lichten gewoon aan te houden.

Waarom Next.js + Supabase de stack is die zinvol is

Er zijn een dozijn manieren om headless te gaan. Je zou Gatsby kunnen gebruiken (hoewel het eigenlijk in onderhoudsmodus zit sinds Netlify het overnam). Je zou Remix, Astro of SvelteKit kunnen gebruiken. Voor de backend zou je Firebase, PlanetScale of een aangepaste API kunnen gebruiken.

Maar voor teams die van WordPress migreren in 2025, raakt Next.js + Supabase een sweet spot die moeilijk te verslaan is. Dit is waarom.

Next.js: De frontend die alles doet

Next.js 15 (stabiel sinds oktober 2024) geeft je standaard server components, wat betekent dat je de performance van statische sites krijgt met de flexibiliteit van dynamische sites. Je kunt je blogposts statisch genereren bij build time, je dynamische pagina's server-renderen en interactieve componenten client-renderen -- alles in dezelfde app.

Voor teams die van WordPress komen, zijn de voornaamste voordelen:

  • Ingebouwde afbeeldingsoptimalisatie -- vervangt 2-3 WordPress plugins
  • Automatische code splitting -- elke pagina laadt alleen de JS die het nodig heeft
  • Edge middleware -- verwerk redirects, auth en A/B tests op CDN niveau
  • Incremental Static Regeneration (ISR) -- bouw individuele pagina's opnieuw zonder volledige deployments
  • App Router met React Server Components -- verminderen client-side JavaScript dramatisch

We bouwen veel Next.js projecten bij Social Animal (bekijk onze Next.js development capabilities), en het prestatieverschil ten opzichte van WordPress is consistent dramatisch.

Supabase: De backend waar WordPress van droomde

Supabase is een open-source Firebase alternatief gebouwd op PostgreSQL. Het geeft je:

  • Een volledige Postgres database met een REST en GraphQL API die automatisch wordt gegenereerd uit je schema
  • Ingebouwde authenticatie (email, OAuth, magic links, SSO)
  • Row-level security policies voor fijne toegangscontrole
  • Real-time subscriptions via WebSockets
  • Edge Functions voor serverless backend logica
  • Opslag voor bestandsuploads met CDN delivery

Voor WordPress migraties specifiek is Supabase briljant omdat WordPress MySQL gebruikt, en je gegevensmodel wijst opmerkelijk goed toe aan PostgreSQL. Aangepaste post types worden tabellen. Post meta wordt JSONB kolommen. Gebruikersgegevens mappen bijna 1:1.

De gratis Supabase tier bevat 500MB database, 1GB opslag en 50.000 maandelijks actieve gebruikers op auth. Hun Pro plan op $25/maand dekt meeste production sites. Vergelijk dat met de $30-$100/maand die je alleen al voor beheerde WordPress hosting betaalt.

Bent je WordPress ontgroeid? Een Migration Playbook voor Next.js + Supabase - architectuur

Het Migration Playbook: Fase per fase

Hier is de aanpak die ik heb verfijnd over tientallen WordPress migraties. Dit is geen weekendproject -- reserveer 4-12 weken afhankelijk van site complexiteit -- maar het is voorspelbaar en laagrisico als je de fasen volgt.

Fase 1: Audit en architectuur (Week 1)

Voordat je een enkele regel code schrijft:

  1. Exporteer een volledige plugin lijst met wp plugin list --status=active (WP-CLI)
  2. Wijs elke plugin toe aan zijn vervanging in de nieuwe stack
  3. Exporteer je volledige URL structuur inclusief alle posts, pages, taxonomies en aangepaste post types
  4. Documenteer alle formulieren, integraties en third-party verbindingen
  5. Identificeer aangepaste functionaliteit die in je theme's functions.php leeft

De plugin mappings oefening is kritiek. Dit is hoe veelgebruikte vervangingen eruitzien:

WordPress plugin Headless vervanging
Yoast SEO Next.js ingebouwde metadata API + generateMetadata()
WP Super Cache / W3 Total Cache Niet nodig (standaard statisch)
Wordfence / Sucuri Supabase RLS + Vercel's ingebouwde DDoS bescherming
Contact Form 7 / Gravity Forms React Hook Form + Supabase Edge Function
WooCommerce Saleor, Medusa.js of Shopify Storefront API
ACF / Custom Fields Supabase tabellen met getypeerde schema's
WP Migrate DB Eenmalige Supabase migratescript
Smush / ShortPixel Next.js Image component (ingebouwd)
Elementor / WPBakery React componenten (je zult ze niet missen)

Fase 2: De nieuwe stack opzetten (Week 2)

# Maak je Next.js project
npx create-next-app@latest my-site --typescript --tailwind --app --src-dir

# Installeer Supabase
npm install @supabase/supabase-js @supabase/ssr

# Zet environment variabelen op
cp .env.example .env.local

Je .env.local:

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

Deploy naar Vercel onmiddellijk. Ja, voordat je iets betekenisvols hebt gebouwd. Het hebben van een live preview URL vanaf dag één verandert hoe je werkt -- stakeholders kunnen voortgang zien, en je vangt deployment issues vroeg op.

Data migratie: Je content uit WordPress krijgen

Dit is waar de meeste migratieguides vaag worden. Laat me specifiek zijn.

Stap 1: WordPress gegevens exporteren

Gebruik niet de ingebouwde WordPress XML export. Het is onvolledig en slecht gestructureerd. Gebruik in plaats daarvan WP-CLI en directe databasevragen:

# Exporteer posts als JSON
wp post list --post_type=post --format=json --fields=ID,post_title,post_content,post_excerpt,post_date,post_status,post_name > posts.json

# Exporteer pages
wp post list --post_type=page --format=json --fields=ID,post_title,post_content,post_excerpt,post_date,post_status,post_name > pages.json

# Exporteer aangepaste post types
wp post list --post_type=your_cpt --format=json > cpt.json

# Exporteer post meta (ACF velden, enz.)
wp eval 'global $wpdb; $results = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_key NOT LIKE \"_%\""); echo json_encode($results);' > postmeta.json

Stap 2: Transformeer en laad in Supabase

Schrijf een migratescript. Ik geef de voorkeur aan TypeScript hiervoor:

import { createClient } from '@supabase/supabase-js'
import posts from './exports/posts.json'

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
)

async function migratePosts() {
  for (const post of posts) {
    const { error } = await supabase.from('posts').insert({
      wp_id: post.ID,
      title: post.post_title,
      slug: post.post_name,
      content: convertWpContentToMdx(post.post_content),
      excerpt: post.post_excerpt,
      published_at: post.post_date,
      status: post.post_status === 'publish' ? 'published' : 'draft',
    })
    
    if (error) console.error(`Failed to migrate post ${post.ID}:`, error)
  }
}

function convertWpContentToMdx(html: string): string {
  // Gebruik turndown of rehype om WordPress HTML naar MDX te converteren
  // Verwerk shortcodes, embeds en Gutenberg blokken
  // Dit is waar 80% van migratie complexiteit zit
}

De convertWpContentToMdx functie is waar je het meeste tijd in besteedt. WordPress content is een puinhoop van HTML, shortcodes, Gutenberg blok opmerkingen en ingebedde oEmbed URLs. Libraries als turndown verwerken basisconversie van HTML-naar-Markdown, maar je hebt aangepaste regels nodig voor shortcodes en blokken.

Stap 3: Migreer media

import { createClient } from '@supabase/supabase-js'
import fetch from 'node-fetch'

async function migrateMedia(mediaItems: any[]) {
  for (const item of mediaItems) {
    const response = await fetch(item.source_url)
    const buffer = await response.buffer()
    
    const { error } = await supabase.storage
      .from('media')
      .upload(`uploads/${item.slug}.${item.mime_type.split('/')[1]}`, buffer, {
        contentType: item.mime_type,
      })
    
    if (error) console.error(`Failed to upload ${item.slug}:`, error)
  }
}

De nieuwe frontend bouwen met Next.js

Met je gegevens in Supabase is het bouwen van de frontend het leuke onderdeel. Hier is een typische blogpost pagina met Next.js App Router:

// src/app/blog/[slug]/page.tsx
import { createClient } from '@/lib/supabase/server'
import { notFound } from 'next/navigation'
import { MDXRemote } from 'next-mdx-remote/rsc'

export async function generateMetadata({ params }: { params: { slug: string } }) {
  const supabase = createClient()
  const { data: post } = await supabase
    .from('posts')
    .select('title, excerpt, og_image')
    .eq('slug', params.slug)
    .single()

  if (!post) return {}

  return {
    title: post.title,
    description: post.excerpt,
    openGraph: { images: [post.og_image] },
  }
}

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const supabase = createClient()
  const { data: post } = await supabase
    .from('posts')
    .select('*')
    .eq('slug', params.slug)
    .eq('status', 'published')
    .single()

  if (!post) notFound()

  return (
    <article className="prose lg:prose-xl mx-auto">
      <h1>{post.title}</h1>
      <time dateTime={post.published_at}>
        {new Date(post.published_at).toLocaleDateString()}
      </time>
      <MDXRemote source={post.content} />
    </article>
  )
}

Let op dat er geen cache plugin is, geen performance plugin, geen SEO plugin. De metadata API verwerkt SEO. Server components verwerken performance. De CDN verwerkt caching. Het is allemaal ingebouwd.

Supabase instellen als je backend

Je Supabase schema moet worden ontworpen rond je werkelijke gegevensbehoeften, niet WordPress's generieke wp_posts / wp_postmeta structuur. Hier is een schoner schema:

-- Posts tabel
create table posts (
  id uuid default gen_random_uuid() primary key,
  title text not null,
  slug text unique not null,
  content text,
  excerpt text,
  featured_image text,
  status text default 'draft' check (status in ('draft', 'published', 'archived')),
  author_id uuid references auth.users(id),
  published_at timestamptz,
  created_at timestamptz default now(),
  updated_at timestamptz default now(),
  metadata jsonb default '{}'
);

-- Categorieën
create table categories (
  id uuid default gen_random_uuid() primary key,
  name text not null,
  slug text unique not null,
  description text
);

-- Row Level Security
alter table posts enable row level security;

create policy "Published posts zijn zichtbaar voor iedereen"
  on posts for select
  using (status = 'published');

create policy "Auteurs kunnen hun eigen posts beheren"
  on posts for all
  using (auth.uid() = author_id);

De metadata jsonb kolom is je ontsnappingsluik. Elke aangepaste veld die niet zijn eigen kolom verdient, kan daar leven. Het is geïndexeerd, opvraagbaar en oneindig flexibel -- als ACF velden maar zonder de plugin.

Authenticatie en gebruikersgegevens afhandelen

Als je WordPress site gebruikersaccounts heeft, verwerkt Supabase Auth de migratie schoon. Je kunt wachtwoord hashes niet migreren (WordPress gebruikt phpass, Supabase gebruikt bcrypt), maar je kunt:

  1. Gebruikersemails en profielen in Supabase importeren
  2. Een "zet je wachtwoord opnieuw in" flow activeren voor alle gebruikers bij eerste login
  3. Of magic link authenticatie gebruiken zodat wachtwoorden niet nodig zijn

Supabase ondersteunt email/wachtwoord, Google, GitHub, Apple en tientallen andere OAuth providers out of the box. Geen plugin nodig.

SEO behoud: Verlies niet wat je hebt opgebouwd

Dit is niet onderhandelbaar. Een verpeste migratie kan jaren SEO equity vernietigen in een nacht. Hier is de checklist:

  1. Wijs elke oude URL toe aan de nieuwe URL. WordPress gebruikt standaard /2024/01/post-title/. Je nieuwe site zou /blog/post-title kunnen gebruiken. Elke enkele oude URL heeft een 301 redirect nodig.

  2. Implementeer redirects in Next.js:

// next.config.js
module.exports = {
  async redirects() {
    return [
      // Datumgebaseerde WordPress URLs naar schone slugs
      {
        source: '/:year(\\d{4})/:month(\\d{2})/:slug',
        destination: '/blog/:slug',
        permanent: true,
      },
      // Categorieën pagina's
      {
        source: '/category/:slug',
        destination: '/blog/category/:slug',
        permanent: true,
      },
    ]
  },
}
  1. Behoud alle meta titles, descriptions en gestructureerde gegevens. Exporteer ze van Yoast vóór migratie.
  2. Dien de nieuwe sitemap in bij Google Search Console onmiddellijk na lancering.
  3. Houd de oude site draaiend op een subdomein (old.yoursite.com) voor 30 dagen als fallback.

Performance benchmarks: Voor en na

Hier zijn echte getallen uit migraties die we hebben gedaan bij Social Animal (dit zijn gemiddelden uit 12 migratie projecten in 2024-2025):

Metrisch WordPress (voor) Next.js + Supabase (na) Verbetering
Lighthouse Performance Score 38 94 +147%
Largest Contentful Paint (LCP) 4.2s 0.9s -79%
First Input Delay (FID) 180ms 12ms -93%
Cumulative Layout Shift (CLS) 0.25 0.02 -92%
Time to First Byte (TTFB) 1.8s 0.15s -92%
Totaal pagina gewicht 3.2MB 420KB -87%
HTTP verzoeken 47 8 -83%

Dit zijn niet geplukte voorbeelden. Ze zijn consistent. Wanneer je 30+ plugins elimineert, elk injecterende hun eigen CSS en JS, en dynamische PHP rendering vervangt door static/server-rendered React componenten op een globale CDN, zijn de resultaten voorspelbaar.

Als je nieuwsgierig bent wat dit soort resultaten voor je project zouden kunnen betekenen, breekt onze pricing pagina uit wat headless migratie projecten typisch kosten.

Kostenverhouding: WordPress vs headless stack

WordPress (jaarlijks) Next.js + Supabase (jaarlijks)
Hosting €1.080 - €5.400 (WP Engine/Kinsta) €0 - €216 (Vercel Pro)
Database/Backend Inbegrepen in hosting €0 - €270 (Supabase Pro)
Plugin licenties €1.350 - €3.600 €0
Beveiligingstools €270 - €450 €0 (ingebouwd)
CDN €0 - €540 €0 (inbegrepen bij Vercel)
Maintenance dev uren €5.400 - €16.200 €900 - €3.600
Totaal €8.100 - €26.190 €900 - €4.086

De headless stack is 70-85% goedkoper om jaarlijks mee te werken. De migratie zelf heeft uiteraard een opwaartse kost -- typisch $15.000-$60.000 afhankelijk van complexiteit voor een professionele build (zie onze headless CMS development services voor specifieke informatie). Maar het betaalt zich terug in 6-18 maanden via gereduceerde operationele kosten alleen, voordat je het revenue impact van betere performance en SEO meeneemt.

Veelgestelde vragen

Moet ik React/Next.js leren om mijn content na migratie te beheren? Nee. De meeste teams combineren Next.js met een headless CMS zoals Sanity, Contentful of zelfs WordPress zelf gebruikt zuiver als headless CMS (via zijn REST API). Content editors raken geen code aan. Ze krijgen een schoon bewerkingsinterface en de frontend haalt content via API. Als je de WordPress editor die je team al kent wilt houden, kan dat absoluut -- verwijder gewoon de WordPress frontend en gebruik het als content backend.

Hoe lang duurt een typische WordPress naar Next.js migratie? Voor een contentgerichte site met blog en standaard pages: 4-6 weken. Voor een site met e-commerce, gebruikersaccounts, aangepaste post types en complexe functionaliteit: 8-14 weken. De grootste variabele is content complexiteit -- sites met sterk shortcode-afhankelijke content of diep aangepaste Gutenberg blokken duren langer om schoon te migreren.

Verlies ik mijn Google rankings tijdens migratie? Niet als je redirects correct afhandelt. 301 redirects behouden ~90-99% van link equity. We zien typisch een kleine dip in de eerste 1-2 weken na migratie (Google moet opnieuw crawlen), gevolgd door verbeterde rankings vanwege betere Core Web Vitals scores. De sleutel is elke enkel URL mappen en niet lanceren tot je redirect map compleet is.

Is Supabase production-ready voor high-traffic sites? Ja. Supabase draait op AWS infrastructuur en is gebruikt in productie door bedrijven die miljoenen verzoeken afhandelen. Hun database is gewoon PostgreSQL -- arguably de meest battle-tested database die bestaat. Vanaf 2025 dient Supabase meer dan 1 miljoen databases en verwerkt miljarden API verzoeken dagelijks. Voor extra schaal omvatten hun Pro ($25/mnd) en Team ($599/mnd) plannen toegewezen resources en prioriteitsondersteuning.

Kan ik WooCommerce naar deze stack migreren? Je kan, maar e-commerce voegt aanzienlijke complexiteit toe. De meeste teams die van WooCommerce migreren gaan naar Shopify (met de Storefront API en Next.js frontend) of een open-source oplossing zoals Medusa.js of Saleor. Supabase kan productcatalogi en orderbeheer afhandelen, maar je zou checkout, betalingsverwerking, inventarisbeheer en belastingberekening zelf moeten bouwen. Voor de meeste bedrijven heeft het gebruik van een toegewezen e-commerce backend en verbinding ervan naar Next.js meer zin.

Wat voor WordPress multisite -- kan deze stack het vervangen? Absoluut. Next.js heeft uitstekende ondersteuning voor multi-tenant architecturen met middleware en dynamische routing. Supabase's Row Level Security maakt het ongecompliceerd om gegevens op te splitsen per tenant. We hebben WordPress multisite netwerken met 50+ sites naar één Next.js applicatie met tenant-specifieke routing gemigreerd, en de operationele vereenvoudiging was enorm.

Heb ik nog steeds een CMS nodig, of kan ik gewoon Supabase direct gebruiken? Supabase geeft je een tabel editor die voor developers werkt, maar content editors willen meestal iets meer gepolijst. De meest gebruikte benaderingen zijn: (1) gebruik een toegewijd headless CMS zoals Sanity of Storyblok voor content en Supabase voor application gegevens, (2) bouw een eenvoudige admin UI met Next.js + Supabase Auth, of (3) hou WordPress als headless CMS backend. Optie 1 is meest populair voor content-zware sites. Als je opties verkent, breken we de tradeoffs uit in onze Astro development en headless CMS pagina's.

Wat als de migratie fout gaat -- kan ik terugschakelen naar WordPress? Ja, en je moet daar voor plannen. Houd je WordPress site draaiend op een subdomein gedurende het migratieproces. Gebruik DNS-niveau switching (verander je A record of CNAME) zodat je in minuten kunt terugschakelen. We raden aan de oude WordPress instantie minstens 30 dagen post-lancering draaiend te houden. Deactiveer het alleen nadat je hebt bevestigd dat alle redirects werken, zoekrankingen stabiel zijn en alle functionaliteit is geverifieerd. Als je hulp wilt plannen bij een migratie met goede terugschakelprocedures, neem contact op met ons team -- we hebben dit genoeg gedaan om de valkuilen te kennen.