WordPress verhuizen naar een nieuwe host of domein

Een volledige, neutrale verhuisgids voor WordPress: bestanden, database, URL search-replace, testen op de nieuwe host voor je DNS omzet, en een DNS-switch met minimale downtime.

Een WordPress-site verhuizen naar een nieuwe host klinkt makkelijk en verbergt ondertussen een handvol manieren om stuk te gaan. Je kopieert de bestanden, je importeert de database, je wijzigt de URL, en vervolgens zijn de helft van je menu's verdwenen, laat de page builder lege blokjes zien, wijzen afbeeldingen naar het oude domein en geeft het contactformulier een 404. Het probleem zit bijna nooit in de kopieerstap. Het zit in de stappen eromheen: geserialiseerde PHP in de database, URL-referenties die zijn ingebakken in post content en widget-configuratie, DNS die bij ISP's dagenlang in de cache blijft hangen, en bij WooCommerce-sites: bestelgegevens in custom tabellen waar een standaard search-replace niet bij komt. Dit artikel loopt de volledige verhuizing door in drie vormen (plugin, handmatig en hybride), met de faalmodes en de fixes per variant.

Het scenario in dit artikel is de meest voorkomende: een live site die naar een nieuwe host gaat, eventueel met een domeinwissel erbij. Het artikel is neutraal over welke host, omdat de verhuisstappen niet afhangen van de bestemming. Het enige host-specifieke detail is de DNS-record aan het eind, en die pas je aan bij je registrar of in het DNS-paneel van de oude host, niet bij de nieuwe.

In het kort

Als je maar vier dingen uit dit artikel onthoudt, onthou dan deze:

  1. Een WordPress-verhuizing is drie dingen, geen één. Het is een bestandskopie, een databasekopie en een URL-update binnen de database. Doe je alleen de eerste twee, dan breekt de site op manieren die lastig te diagnosticeren zijn.
  2. Draai nooit een kale SQL UPDATE op URL's in de database. WordPress slaat menu's, widgets en page builder-configuratie op als geserialiseerde PHP, en een rauwe SQL-replace verpest de length-prefixes. Gebruik [WP-CLI wp search-replace](https://developer.wordpress.org/cli/commands/search-replace/) (zie de gelinkte gids voor de Gutenberg-aware vergelijking) of Better Search Replace: die de-serialiseren, vervangen en herberekenen de length-prefix correct.
  3. Test op de nieuwe host voor je DNS omzet. Het hosts-bestand op je laptop laat je de nieuwe server benaderen op het echte domein, terwijl de rest van de wereld de oude site nog ziet. Sla je die stap over, dan zijn je eerste bezoekers degenen die de kapotte pagina's ontdekken.
  4. Verlaag je DNS-TTL 24 uur voor de switch. DNS-propagatie is niet instant, en ISP-resolvers kunnen records 24 tot 48 uur in de cache houden zelfs nadat de TTL verlopen is. De TTL een dag van tevoren naar 300 seconden zetten brengt het worstcase-scenario terug van twee dagen naar vijf minuten.

De rest van het artikel is de onderbouwing en de exacte commando's.

Inhoudsopgave

Verhuisoverzicht: bestanden, database en DNS

Een WordPress-site is twee dingen op twee plekken, plus een DNS-record dat browsers vertelt waar je ze vindt. Een verhuizing kopieert de eerste twee en wijzigt de derde.

De bestanden staan op schijf in de WordPress-directory en bevatten wp-content/ (uploads, thema's, plugins, mu-plugins), wp-config.php, .htaccess en de WordPress core-bestanden zelf. De core kun je opnieuw installeren, maar wp-content/ is van jou. Verlies je de uploads-map, dan verlies je elke afbeelding, PDF en bijlage die gebruikers ooit hebben geüpload.

De database is een MySQL- of MariaDB-database met een stuk of twaalf standaard WordPress-tabellen plus één of meer per geïnstalleerde plugin. Daarin staan alle posts, pagina's, reacties, gebruikers, plugin-instellingen (in wp_options), menu-structuren, widget-configuratie en bij WooCommerce-sites elke bestelling, klant en voorraadwaarde. De officiële WordPress-verhuisgids is duidelijk over de splitsing: je kunt bestanden niet verhuizen zonder de database, en je kunt de database niet verhuizen zonder de bestanden.

DNS is de wegwijzer. Het domein heeft een of meer A-records (of AAAA voor IPv6, of CNAME afhankelijk van de host) die de domeinnaam naar een IP-adres resolven. Bij het wisselen van host wijs je die records naar het nieuwe IP. Dit is de enige stap die zichtbaar is voor de buitenwereld. Tot je die aanraakt, laadt de rest van het internet nog steeds de oude site.

De juiste volgorde is: bestanden kopiëren, database kopiëren, URL's binnen de database bijwerken, testen op de nieuwe host via een lokaal hosts-bestand, en pas dán DNS omzetten. De teststap overslaan is de meest voorkomende oorzaak van paniek na de launch.

Wat je eerst nodig hebt

Je hebt dit allemaal nodig voor je begint. Halverwege weglopen vanwege een ontbrekende voorwaarde is hoe kleine verhuizingen weekendverhuizingen worden.

  • Een verse, geverifieerde backup van de live site (database plus bestanden). Niet die van gisteren uit het schema. Een verse, nu gemaakt, gedownload naar ergens waar je bij kunt ook als de site eruit ligt. Zie het artikel WordPress backup-strategie voor wat een echte backup bevat en hoe je er een maakt.
  • Toegang tot beide hosts: SFTP of SSH naar de oude en de nieuwe host, plus de database-credentials aan beide kanten (of de mogelijkheid om aan de nieuwe kant een nieuwe database aan te maken).
  • Toegang tot het DNS-beheer voor het domein, of dat nu bij de registrar is of bij de autoritatieve nameservers. Als iemand anders het DNS beheert: zorg dat diegene stand-by staat voor de switch.
  • De nieuwe host is ingericht met dezelfde of een nieuwere PHP-versie als de live site (check Gereedschappen > Site-status op de oude site). Als de nieuwe host op PHP 8.3 draait en de oude op PHP 7.4, lees dan eerst WordPress traag na een update: een PHP-sprong van twee versies legt plugin-incompatibiliteiten bloot op precies hetzelfde moment als de verhuizing.
  • WP-CLI 2.10 op de nieuwe host als je de commandline-methode wilt gebruiken, plus SSH-toegang om het te draaien. WP-CLI is de nette manier om search-replace op grote databases te draaien, omdat het streamt zonder te timeouten.
  • De nieuwe domeinnaam (als je wisselt) gericht op een parkeerpagina of ongebruikt, zodat je tegen de nieuwe host kunt testen met een lokaal hosts-bestand zonder dat je het live DNS aanraakt.
  • Een lijst met licentiesleutels van je commerciële plugins. Commerciële plugins zijn vaak gebonden aan een domein, en een verhuizing kan een licentie-reactivering op de nieuwe URL vereisen. Houd de sleutels klaar zodat je tijdens de launch niet vastloopt.

Voor je begint: verlaag de DNS-TTL

Doe deze stap 24 uur voor de verhuizing, niet op de dag zelf. DNS-TTL (Time To Live) bepaalt hoe lang downstream-resolvers een record in de cache houden. Een typische standaard is 3600 seconden (één uur) of 14400 (vier uur). Op de dag van de switch wil je de TTL zo laag mogelijk, zodat de wereld je A-record-wijziging in minuten ziet in plaats van uren.

  1. Log in waar het DNS van je domein wordt beheerd (registrar, Cloudflare of het DNS-paneel van de oude host).
  2. Zoek het A-record (of AAAA voor IPv6) voor het hoofddomein en de www-subdomein.
  3. Wijzig de TTL naar 300 seconden (5 minuten) of de laagste waarde die de interface toestaat.
  4. Sla op en wacht minstens zo lang als de vorige TTL was. Was de oude TTL 14400, wacht dan vier uur. Was het 3600, wacht een uur. Zo kunnen resolvers die de oude TTL gecached hadden hun cache laten verlopen en de nieuwe, kortere TTL oppikken.

Nadat de verhuizing klaar en stabiel is, zet je de TTL weer omhoog naar iets verstandigs (3600 of 14400), zodat resolvers je records normaal cachen.

De migratiegids van WPShout is bot over de reden: "ISPs can cache records for 24 or 48 hours or more" zelfs als de TTL al lang verlopen is, omdat sommige ISP's de TTL losjes of helemaal niet respecteren. De TTL-verlaging van tevoren is hoe je het worstcase-scenario begrenst.

Methode 1: Verhuisplugin (makkelijkst)

Voor de meeste kleine en middelgrote sites is een verhuisplugin de juiste keuze. Die bundelt de bestanden en de database in een archief op de oude host en pakt ze uit op de nieuwe, en draait daarna een search-replace-stap op de URL's. Er zijn drie plugins die het overwegen waard zijn.

All-in-One WP Migration exporteert de hele site (database, bestanden, plugins, thema's) naar één .wpress-bestand dat je op de nieuwe host importeert. De gratis versie limiteert de importgrootte op de meeste hosts tot 512 MB; de betaalde extensie haalt die limiet eraf. Het is de simpelste interface van de drie en de eerste keus voor kleine sites.

Duplicator pakt de site in twee bestanden: een .zip-archief en een installer.php-script. Die upload je allebei naar de nieuwe host, laad je installer.php in de browser, en het script bouwt de site opnieuw op uit het archief. Duplicator is specifiek gebouwd voor verhuizen en klonen (niet voor backups), dus de search-replace-stap is grondig en de UI is expliciet over wat er gebeurt. Dit is mijn standaardaanbeveling voor sites onder een paar gigabyte.

Migrate Guru is BlogVault's gratis verhuisplugin en kan hele grote sites aan (meerdere gigabytes) door het archief door hun eigen servers te streamen. De tradeoff is dat je site-inhoud tijdens de verhuizing langs een derde partij gaat; lees hun privacyverklaring en beslis of dat acceptabel is.

Stappen (met Duplicator als voorbeeld)

  1. Installeer en activeer de Duplicator-plugin op de oude site.
  2. Ga naar Duplicator > Packages > Create New en loop de wizard door. Laat op het Setup-scherm het archief op .zip en de installer op installer.php. Klik Next.
  3. Duplicator draait een scan. Fix alle rode waarschuwingen voor je verder gaat. Veelvoorkomende meldingen zijn "Site too large" (overweeg de handmatige methode) en "MySQL stored procedures detected" (zeldzaam; meestal veilig om door te gaan).
  4. Klik Build. Als de build klaar is, download je twee bestanden: installer.php en een .zip-archief met een lange unieke naam.
  5. Maak op de nieuwe host een database aan (via het controlepaneel van de host of via de mysql CLI). Noteer databasenaam, gebruikersnaam, wachtwoord en host.
  6. SFTP of upload de twee Duplicator-bestanden naar de root van de webdirectory op de nieuwe host (waar wp-config.php normaal gesproken zou staan). Zorg dat de directory verder leeg is.
  7. Open in je browser https://nieuw-server-ip/installer.php (of het nieuwe domein als dat al ergens naar wijst, of een tijdelijke URL die de nieuwe host aanbiedt). De installer verschijnt.
  8. Plak de database-credentials uit stap 5 in de installer. Klik Test Database. Ga door zodra de test slaagt.
  9. Bevestig op het volgende scherm de oude en de nieuwe URL. Duplicator gebruikt dit voor de search-replace-stap. Verandert het domein niet, dan zijn beide URL's hetzelfde.
  10. Laat de installer draaien. Die pakt het archief uit, importeert de database en draait search-replace op de URL's. Als het klaar is, vraagt hij je in te loggen en de installer-bestanden te verwijderen. Doe allebei voor je verder gaat.

Verwachte uitkomst: de nieuwe host heeft nu een werkende WordPress-installatie die overeenkomt met de oude. Je kunt hem nog niet op het echte domein bezoeken, want DNS wijst nog naar de oude host. Dat is de hosts-file-stap hieronder.

Controleer het resultaat: volg de prompts van Duplicator en verwijder installer.php, het archief en eventuele andere installer-restanten uit de webroot. Dat zijn beveiligingsrisico's als je ze laat staan. Draai daarna de tests uit Testen op de nieuwe host voordat je live gaat.

Wanneer een verhuisplugin de verkeerde keuze is

Verhuisplugins lopen vast op hele grote sites (meerdere gigabytes database, honderden gigabytes uploads), op sites achter strakke server-configuratie (lage PHP-memory, korte max_execution_time) en op sites waarbij de oude host al onbereikbaar is. In al die gevallen ga je door naar Methode 2.

Methode 2: Handmatige verhuizing (meeste controle)

De handmatige methode behandelt een verhuizing als wat het is: een bestandskopie en een database-dump. Je hebt shell-toegang tot beide hosts nodig, maar het is de meest betrouwbare route voor grote sites en de enige route als er geen plugin kan draaien.

Stap 1: Dump de database op de oude host

SSH naar de oude host en cd naar de WordPress-root (de directory waar wp-config.php staat). Exporteer de database met WP-CLI als dat beschikbaar is, of met mysqldump als dat niet zo is.

# Met WP-CLI (voorkeur): pakt de credentials automatisch uit wp-config.php.
# --add-drop-table maakt de dump herstelbaar over een bestaande database heen.
wp db export - --add-drop-table | gzip > /tmp/old-site-db-$(date +%F).sql.gz
# Met mysqldump: vul de credentials uit wp-config.php in.
# --single-transaction vermijdt locks op InnoDB, --quick streamt rijen.
mysqldump --single-transaction --quick --add-drop-table \
  -h localhost -u wp_user -p wp_database \
  | gzip > /tmp/old-site-db-$(date +%F).sql.gz

Verwachte uitkomst: een gezipt SQL-bestand in /tmp/ tussen een paar honderd KB en een paar honderd MB, afhankelijk van de site. Check dat het bestand niet leeg is met ls -lh /tmp/old-site-db-*.sql.gz en dat het met een normale SQL-header begint met zcat /tmp/old-site-db-*.sql.gz | head -5.

Stap 2: Kopieer de bestanden

Kopieer de hele WordPress-directory naar de nieuwe host. De snelste route is rsync over SSH rechtstreeks tussen de twee servers (als de oude host uitgaande SSH toestaat). Anders rsync naar je laptop en daarna omhoog naar de nieuwe host.

# Directe rsync oud-naar-nieuw, uit te voeren op de oude host.
# -a behoudt permissies, -v is verbose, -z comprimeert tijdens transport,
# -P toont voortgang en laat hervatten na onderbreking toe.
# --exclude haalt caches en de zojuist gemaakte dump eruit.
rsync -avzP \
  --exclude='wp-content/cache' \
  --exclude='wp-content/uploads/cache' \
  --exclude='.git' \
  /var/www/old-site/ \
  deploy@new-host.example.com:/var/www/new-site/
# Fallback: rsync naar je laptop, dan omhoog naar de nieuwe host.
rsync -avzP old-host.example.com:/var/www/old-site/ ./old-site/
rsync -avzP ./old-site/ new-host.example.com:/var/www/new-site/

Verwachte uitkomst: een volledige kopie van de WordPress-directory op de nieuwe host. Check met ls /var/www/new-site/ dat de top-level wp-config.php, wp-content/, wp-includes/ en wp-admin/ er allemaal staan. Draai du -sh /var/www/new-site/ en vergelijk met de oude host; de groottes moeten op een paar MB na gelijk zijn (kleine verschillen zijn cache-bestanden die je hebt uitgesloten).

Even over de -scaled-suffix op afbeeldingen. WordPress 5.3 (november 2019) introduceerde de Big Image Threshold: afbeeldingen die groter dan 2560 pixels op hun langste kant worden geüpload, krijgen een geschaalde variant op schijf met een -scaled-suffix (bijvoorbeeld foto.jpg wordt foto-scaled.jpg), en de oorspronkelijke bestandsnaam komt in de image-meta onder original_image. Beide bestanden moeten mee in de rsync. Sluit je er één uit, dan breekt wp_get_original_image_path() voor toekomstige uploads. De standaard rsync -a pakt alles mee en heeft geen bijzondere behandeling nodig; het risico zit alleen bij handmatige --include/--exclude-lijsten die per ongeluk een van de varianten eruit filteren.

Stap 3: Maak de database aan op de nieuwe host en importeer de dump

SSH naar de nieuwe host. Maak een lege database en een gebruiker aan, en importeer daarna de dump.

# Database en gebruiker aanmaken (vul echte waarden in).
# Draai dit als MySQL root of een account met CREATE-rechten.
mysql -u root -p <<'SQL'
CREATE DATABASE new_site_wp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'new_wp_user'@'localhost' IDENTIFIED BY 'een-lang-willekeurig-wachtwoord';
GRANT ALL PRIVILEGES ON new_site_wp.* TO 'new_wp_user'@'localhost';
FLUSH PRIVILEGES;
SQL
# Importeer de dump. WP-CLI-route (voorkeur, pakt credentials uit wp-config.php
# zodra je wp-config.php op de nieuwe host hebt aangepast. Pas die eerst aan.
cd /var/www/new-site
zcat /path/to/old-site-db-2026-04-08.sql.gz | wp db import -
# Fallback: importeer rechtstreeks via de mysql CLI.
zcat /path/to/old-site-db-2026-04-08.sql.gz | mysql -u new_wp_user -p new_site_wp

Voor je de WP-CLI-import draait, bewerk je /var/www/new-site/wp-config.php op de nieuwe host en update je DB_NAME, DB_USER, DB_PASSWORD en DB_HOST naar de nieuwe waarden uit het CREATE DATABASE-blok hierboven. Laat de constants AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY en NONCE_KEY met rust; die veranderen logt elke gebruiker uit, wat voor een verhuizing meestal prima is maar een bewuste keuze moet zijn en geen ongelukje.

Verwachte uitkomst: wp db import drukt niks af bij succes. mysql drukt ook niks af bij succes. Verifieer de import met wp db query 'SHOW TABLES;' (WP-CLI) of mysql -u new_wp_user -p new_site_wp -e 'SHOW TABLES;'. Je zou de volledige set WordPress-tabellen moeten zien (wp_options, wp_posts, wp_users, enzovoort) plus de tabellen van geïnstalleerde plugins.

Controleer het resultaat: draai wp core verify-checksums op de nieuwe host. Die hoort te melden Success: WordPress installation verifies against checksums. Meldt hij mismatches, dan is of de bestandskopie incompleet, of had de oude site core-bestanden die afwijken van de officiële release (check op custom patches of een gecompromitteerde oude site voor je verder gaat).

De kritieke stap: search-replace op URL's in de database

Dit is de stap die verrassend veel handleidingen overslaan of verkeerd doen. De zojuist geïmporteerde database bevat de URL van de oude site op tientallen plekken in hardcoded vorm: de siteurl- en home-rijen van wp_options, honderden wp_posts-rijen waar post content naar andere pagina's linkt of afbeeldingen inlaadt op de oude URL, wp_postmeta-rijen waar plugin-instellingen naar URL's verwijzen, widget-configuratie, menu-items en bij page builders als Elementor, Beaver Builder en Divi de hele pagina-layout als geserialiseerde PHP met URL's daarin.

Waarom een kale SQL UPDATE alles sloopt

WordPress slaat veel van zijn configuratie op als geserialiseerde PHP, het uitvoerformaat van PHP's serialize()-functie. Een geserialiseerde array ziet er zo uit:

a:2:{s:4:"home";s:22:"https://old-domain.com";s:7:"siteurl";s:22:"https://old-domain.com";}

De s:22-prefix betekent "de volgende string is 22 tekens lang". Draai je een plain SQL UPDATE om https://old-domain.com te vervangen door https://new-domain.com (24 in plaats van 22 tekens), dan verandert de stringwaarde wel maar de s:22-prefix niet. PHP's unserialize() leest de prefix, probeert 22 bytes te lezen, krijgt 24 bytes aan data die niet matchen met wat verwacht werd, en faalt stil. Resultaat: menu's verdwijnen, widgets renderen niet meer, plugin-instellingen vallen terug op default, en page builder-layouts worden lege divs.

Zowel de WP-CLI search-replace-documentatie als de Better Search Replace-plugin doen dit wel goed door te de-serialiseren, de string te vervangen en vervolgens de length-prefix opnieuw te berekenen voordat ze re-serialiseren. Draai dus nooit een rauwe SQL UPDATE over URL's in een WordPress-database. Gebruik een van de tools hieronder.

Optie A: WP-CLI (voorkeur als je SSH hebt)

# Eerst een dry run: laat zien wat er zou veranderen zonder iets te schrijven.
# --skip-columns=guid is verplicht. Nooit de GUID-kolom aanraken, ever.
wp search-replace 'https://old-domain.com' 'https://new-domain.com' \
  --skip-columns=guid \
  --dry-run
# De echte run: voert de wijzigingen door. Pas draaien nadat je de dry-run hebt gelezen.
# --all-tables-with-prefix neemt plugin-tabellen mee zoals WooCommerce HPOS.
# --precise forceert PHP-based replacement voor correcte geserialiseerde data.
wp search-replace 'https://old-domain.com' 'https://new-domain.com' \
  --skip-columns=guid \
  --all-tables-with-prefix \
  --precise

Verwachte uitkomst: een tabel met verwerkte tabellen en kolommen, eindigend met Success: Made N replacements. De dry run en de echte run moeten hetzelfde aantal replacements rapporteren; zijn ze verschillend, dan is er tussen de twee runs iets in de database veranderd en moet je uitzoeken wat voor je het resultaat vertrouwt.

Drie vlaggen doen ertoe:

  • --skip-columns=guid is niet onderhandelbaar. De WordPress-migratiedocumentatie is expliciet: "Never, ever, change the contents of the GUID column, under any circumstances." GUID's zijn bedoeld als permanente identifiers voor RSS-feedlezers zodat ze oude posts niet opnieuw als nieuw tonen. Als je ze verandert, laten alle RSS-lezers elke post weer als nieuw zien.
  • --all-tables-with-prefix neemt alle tabellen mee waarvan de naam begint met de WordPress table prefix (standaard wp_), zodat plugin-tabellen die wp search-replace anders overslaat wel worden geraakt. Gebruik voor multisite --network om per-site-tabellen te pakken.
  • --precise dwingt WP-CLI om PHP-based search-replace te gebruiken (trager maar correct) in plaats van het default SQL-pad dat alleen automatisch naar PHP overschakelt zodra het geserialiseerde data detecteert. Bij een verhuizing is --precise veiliger; de tijdstraf is verwaarloosbaar voor normale sites.

Optie B: Better Search Replace-plugin (als SSH niet kan)

Biedt de nieuwe host alleen een webbased bestandsbeheerder en geen SSH, installeer en activeer dan de Better Search Replace-plugin op de nieuwe host, en:

  1. Ga naar Gereedschappen > Better Search Replace.
  2. Vul bij Search for in: https://old-domain.com. Bij Replace with: https://new-domain.com.
  3. Selecteer in Select tables alle tabellen (Ctrl+A of Cmd+A in de multi-select).
  4. Vink Run as dry run? aan en klik Run Search/Replace. Lees de uitkomst.
  5. Als de dry run klopt, vink je Run as dry run? uit en klik je Run Search/Replace nog een keer om het door te voeren.
  6. Flush je caches (wp cache flush via CLI als dat kan, of deactiveer en heractiveer je caching-plugins via het WordPress-dashboard).

Better Search Replace draait bovenop het Search Replace DB-script van interconnect/it, met aanpassingen om WordPress' eigen database-functies te gebruiken. Het handelt geserialiseerde data correct af en is de aanbevolen browser-route.

Na de search-replace: flush caches en regenereer .htaccess

Twee nazorgstappen die makkelijk worden vergeten:

# Flush de object cache: die kan nog oude URL's bevatten.
wp cache flush

Ga daarna in het WordPress-dashboard naar Instellingen > Permalinks en klik twee keer op Wijzigingen opslaan (één keer zonder wijzigingen, en voor de zekerheid nog een keer). Dit regenereert .htaccess met rewrite-rules die kloppen met de nieuwe URL-structuur. De migratiegids van Delicious Brains noemt dit expliciet, omdat het makkelijk is over het hoofd te zien en na de verhuizing 404's veroorzaakt op pretty permalinks.

WooCommerce en HPOS: de tabellen die search-replace mist

Draait de site op WooCommerce, dan is er één extra stap die bijna elke verhuizing raakt en bijna geen tutorial noemt. WooCommerce 8.2 (oktober 2023) maakte High-Performance Order Storage (HPOS) de standaard voor nieuwe installaties. HPOS haalt bestelgegevens uit wp_postmeta en zet ze in vier custom tabellen: wp_wc_orders, wp_wc_order_addresses, wp_wc_order_operational_data en wp_wc_orders_meta.

WP-CLI's default wp search-replace zonder --all-tables-with-prefix of --all-tables raakt die HPOS-tabellen niet. Het draait over de WordPress-core-tabellen en stopt. Gevolg: een verhuisde WooCommerce-site kan aan de voorkant er prima uitzien maar in de HPOS-tabellen nog overal URL's van het oude domein bevatten, wat order confirmation-mails, orderlinks in klantaccounts en WooCommerce-rapportages met URL's erin breekt.

De fix is --all-tables-with-prefix toevoegen (dat alle wp_-prefixed tabellen pakt, inclusief HPOS) of --all-tables (die alles in de database pakt, ook tabellen zonder de standaard prefix):

# WooCommerce HPOS-aware search-replace.
# --all-tables-with-prefix raakt de vier _wc_order*-tabellen naast de standaard WP-tabellen.
wp search-replace 'https://old-domain.com' 'https://new-domain.com' \
  --skip-columns=guid \
  --all-tables-with-prefix \
  --precise \
  --dry-run

Check of HPOS aan staat met: wp option get woocommerce_custom_orders_table_enabled. Geeft dat yes terug, dan is HPOS actief en is --all-tables-with-prefix verplicht.

Nog één voorbehoud. Elementor, Beaver Builder en Divi slaan hun page layouts allemaal op in een zwaar geneste geserialiseerde vorm binnen wp_postmeta. WP-CLI's --precise pakt het meeste correct, maar Elementor slaat ook data op in een JSON-encoded formaat met eigen length-prefixes. Draai na je search-replace nog één keer een URL-replace in het WordPress-dashboard via Elementor > Gereedschappen > Replace URL. Dit is een eigenaardigheid van Elementor, geen fout van WP-CLI, en staat op de site van Elementor beschreven.

Testen op de nieuwe host

Voor een permanente staging-setup in plaats van een eenmalige migratietest, zie de WordPress-staging-omgeving gids. voordat je live gaat

Voor je DNS aanraakt, test je de verhuisde site op het echte domein via je lokale hosts-bestand. Zo resolvet je browser het domein naar het nieuwe server-IP terwijl de rest van de wereld nog het oude IP ziet. Je kunt door de hele site klikken, inloggen op wp-admin, formulieren testen en kapotte links vinden zonder dat één bezoeker ziet wat jij ziet.

Pas je hosts-bestand aan

Het hosts-bestand is een platte tekstfile die het besturingssysteem raadpleegt voordat het naar DNS gaat. Een regel toevoegen overschrijft DNS voor alleen jouw machine.

Op macOS en Linux: bewerk /etc/hosts met sudo nano /etc/hosts (of je eigen editor). Voeg toe:

123.45.67.89    yoursite.nl www.yoursite.nl

Vervang 123.45.67.89 met het IP-adres van de nieuwe host (vraag het aan de nieuwe host of zoek het op in hun paneel). Opslaan en sluiten.

Op Windows: open Notepad als Administrator en bewerk C:\Windows\System32\drivers\etc\hosts. Voeg dezelfde regel toe. Opslaan.

Flush de lokale DNS-cache zodat de wijziging meteen werkt:

  • macOS: sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
  • Linux (systemd-resolved): sudo systemd-resolve --flush-caches
  • Windows: ipconfig /flushdns in een admin cmd

Test de verhuisde site

  1. Open een nieuw browservenster (liefst privé/incognito om gecachte responses te vermijden) en ga naar https://yoursite.nl. Je hoort nu de nieuwe host te zien, niet de oude.
  2. Verifieer dat je écht de nieuwe host raakt. Een betrouwbare manier is een klein markerbestand op alleen de nieuwe host: echo 'nieuwe host' > /var/www/new-site/migration-marker.txt, en vervolgens https://yoursite.nl/migration-marker.txt openen. Krijg je nieuwe host terug, dan zit je op de nieuwe server. Krijg je een 404 of iets anders, dan werkt je hosts-edit niet (check het bestand, flush DNS-cache, probeer een andere browser).
  3. Klik door de homepage, een blogpost, een categoriearchief, een page builder-pagina, de zoekresultatenpagina en de 404-pagina. Afbeeldingen moeten laden. Menu's moeten werken. Links moeten naar andere pagina's op de site verwijzen, niet naar het oude domein.
  4. Log in op https://yoursite.nl/wp-admin/. De login hoort te werken met je bestaande credentials. Lukt dat niet, verwijder dan de cookies voor het domein (de combinatie van hosts-file en oude cookies veroorzaakt soms een redirect-loop; zie het artikel over de WordPress login redirect loop).
  5. Ga in wp-admin naar Instellingen > Algemeen en check dat WordPress-adres (URL) en Site-adres (URL) allebei het nieuwe domein tonen. Ga daarna naar Gereedschappen > Site-status en lees kritieke waarschuwingen.
  6. Test contactformulieren of WooCommerce-flows end-to-end. Plaats voor WooCommerce een test-order via de cod (rembours)-gateway of een sandbox Stripe-sleutel. Vertrouw niet op "de formulieren zien er goed uit" als bewijs; verstuur ze echt.
  7. Verwijder het markerbestand: rm /var/www/new-site/migration-marker.txt.

Controleer het resultaat: na stap 1 tot en met 6 heb je bewezen dat de nieuwe host de site correct serveert op het echte domein. Het enige wat nog naar de oude host wijst is DNS, en die ga je zo omzetten.

Test vanaf je telefoon op mobiele data (niet wifi). Je telefoon gebruikt het hosts-bestand op je laptop niet, dus die ziet nog steeds de oude site. Dat is wat de rest van de wereld nu ook ziet. Gebruik dit beeld om te besluiten of er nog content-wijzigingen op de oude site moeten (een blogpost die op het punt staat te publiceren, een prijsupdate) voordat je DNS omzet, en of je de oude site in een soort onderhoudsmodus moet zetten om hem te bevriezen.

DNS omzetten met minimale downtime

Met de TTL al verlaagd naar 300 seconden (uit de stap van tevoren) is de eigenlijke DNS-switch anticlimactisch: wijzig het A-record naar het nieuwe IP, wacht 5 tot 10 minuten, en de site is live.

  1. Zoek in je DNS-paneel het A-record voor het hoofddomein (@ of leeg) en voor de www-subdomein.
  2. Wijzig het IP-adres naar dat van de nieuwe host. Laat de TTL op 300 staan.
  3. Sla op. Sommige panels willen nog een expliciete "apply" of "publish". Zorg dat de wijziging is doorgevoerd.
  4. Wacht een paar minuten. Open in een privébrowser (niet degene met de hosts-file-edit) https://yoursite.nl. Je hoort de nieuwe site te zien. Zie je nog de oude, dan raak je waarschijnlijk een gecachte DNS-response. Probeer het vanaf een telefoon op mobiele data, of draai dig yoursite.nl @1.1.1.1 +short om de publieke resolver van Cloudflare rechtstreeks te bevragen; die hoort het nieuwe IP terug te geven.
  5. Haal de hosts-file-regel op je laptop weg nu DNS klopt. Laat je 'm staan, dan merk je het niet als DNS later weer verandert, en dat geeft de volgende keer dat je iets verhuist problemen.
  6. Kijk naar de access log van de oude host. Er blijven nog uren verzoeken binnensijpelen door gecachte DNS bij verschillende ISP's, maar het leeuwendeel van het verkeer hoort met een TTL van 300 seconden binnen 10 tot 20 minuten over te gaan.

Zet de oude site nog niet uit

Laat de oude host minstens 48 uur draaien na de DNS-switch. Sommige ISP's cachen DNS-responses veel langer dan de TTL en blijven uren of dagen het oude IP resolven. Gaat de oude host meteen donker, dan zien die gebruikers een dode site. Laat je hem draaien, dan zien ze nog de (inmiddels iets verouderde) oude site totdat hun DNS-cache verloopt, en dat is een stuk vriendelijker dan een failed connection.

Een praktische verfijning: overweeg om de oude host in die 48 uur te laten draaien met een read-only, licht aangepaste versie van de site die een "we zijn verhuisd"-banner toont. Optioneel, maar het houdt de gebruikerservaring logisch en vermijdt de situatie dat twee mensen op dezelfde URL twee verschillende sites zien.

Na 48 tot 72 uur kun je de oude host veilig opdoeken. Maak een laatste backup van de oude database en bestanden voor je iets weggooit, en bewaar die backup minstens 30 dagen op een plek die je zelf beheert, als verzekering tegen dingen die de verhuizing eventueel heeft gemist.

Checklist na de verhuizing

Loop deze lijst in het eerste uur na de DNS-switch langs. Hij vangt de dingen die in de launch-drukte makkelijk worden vergeten.

  • Search Console: voeg het nieuwe domein toe als property in Google Search Console (als het veranderd is) en dien de sitemap in. Is het domein echt veranderd, gebruik dan de Change of Address-tool om Google over de verhuizing te informeren.

  • 301-redirects: is het domein veranderd, zet dan permanente 301-redirects van het oude domein naar het nieuwe op de oude host. Elke URL op het oude domein hoort om te leiden naar de equivalent op het nieuwe domein. Dat behoudt de PageRank/SEO-waarde van bestaande inkomende links. In .htaccess op de oude host:

    # Permanent redirect alles van old-domain.com naar new-domain.com.
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(www\.)?old-domain\.com$ [NC]
    RewriteRule ^(.*)$ https://new-domain.com/$1 [R=301,L]
  • SSL/TLS-certificaat: check dat de nieuwe host een geldig certificaat voor het domein heeft. De meeste managed hosts provisionen Let's Encrypt automatisch; op een VPS draai je certbot --nginx of een equivalent. Bezoek de site en controleer of het hangslot er staat.

  • E-mail: wijzen de MX-records van het domein naar de mailserver van de oude host, dan is mail nu stuk. Pas MX-records apart aan (e-mail-DNS is los van het A-record voor web). Zit je mail bij een derde partij (Google Workspace, Fastmail), laat dan MX met rust en raak alleen het A-record aan.

  • wp-cron: check dat wp-cron.php nog draait. wp cron event list hoort aankomende events te tonen. Stond er een hostinglevel-cron op de oude host (gebruikelijk bij managed WordPress), zet die dan opnieuw op op de nieuwe host.

  • Cache en CDN: gebruik je een CDN (Cloudflare, BunnyCDN, Fastly), leeg zijn cache. Gebruik je een caching-plugin, leeg die cache. Een oude cache is een veelvoorkomende reden dat een site "kapot lijkt" na de verhuizing terwijl bestanden en database in orde zijn.

  • robots.txt: check dat https://yoursite.nl/robots.txt de verwachte inhoud teruggeeft. Had de oude host een gegenereerde robots.txt in plaats van een statisch bestand, dan kan die niet zijn meegekomen.

  • Contactformulier smoke test: verstuur een echt test-bericht via het hoofdcontactformulier en verifieer dat je de mail ontvangt. Contactformulier-plugins resetten soms hun SMTP-configuratie tijdens een verhuizing. Zie WordPress stuurt geen e-mail als mail stuk is.

  • Zoekfunctie: draai een zoekopdracht op de site. Als een plugin (Relevanssi, SearchWP) de zoekindex onderhoudt, moet die index vaak opnieuw worden gebouwd vanuit de plugin-instellingen.

  • Zet DNS-TTL terug omhoog: nu de verhuizing stabiel is, zet je de TTL weer op 3600 of 14400 zodat resolvers je records normaal cachen.

Mythes die je mag laten varen

Een kort lijstje van wijdverbreide verhuismythes die echte sites slopen:

"siteurl en home in de database wijzigen is alles wat je hoeft te doen." Nee. De WordPress-migratiedocumentatie noemt wp_options het startpunt en gaat door met updates in wp_posts, wp_postmeta en voor multisite wp_site en wp_blogs. Alleen siteurl en home updaten laat de oude URL ingebakken in duizenden posts, widgets, menu's en page builder-layouts.

"Verhuisplugins handelen geserialiseerde data automatisch af." Alleen als het een plugin is die specifiek voor verhuizen is gebouwd en geserialiseerde data ondersteunt. Better Search Replace, WP-CLI search-replace --precise en Duplicator doen dat. Een generieke backup-plugin die een SQL-dump exporteert en aan de andere kant importeert zonder PHP-aware search-replace-stap niet. De WP Engine-gids over geserialiseerde data legt uit waarom: een rauwe SQL-replace verpest de length-prefixes.

"DNS-propagatie is instant." ISP's cachen DNS-responses 24 tot 48 uur of langer, soms in weerwil van de TTL die jij hebt gezet. De enige mitigatie is de TTL 24 uur voor de verhuizing verlagen, zodat resolvers die TTL wel respecteren de korte waarde zien en hun cache snel verversen. De rest van de wereld komt erachter zodra ze erachter komen.

"Ik kan de URL gewoon in wp_options wijzigen met een SQL UPDATE." Kan, en de site boot, en de eerste keer dat je een pagina met Elementor of een widget-heavy sidebar laadt, renderen die als lege divs of throwen ze een PHP warning in de error log. Geserialiseerde data moet worden ge-deserialiseerd, vervangen en opnieuw geserialiseerd met kloppende length-prefixes. Rauwe SQL kan dat niet.

"Ik hoef geen backup, ik kopieer alleen maar bestanden." Op het moment dat er halverwege iets misgaat, is het ding dat je redt een backup van de oude site die je voor je begon hebt gemaakt. Niet de snapshot van de backupservice van de oude host (die ook nog midden in een verhuiststaat kan zitten). Een verse, door jou gemaakt, ergens opgeslagen die niet op een van beide servers staat. Het artikel WordPress backup-strategie bevat de details.

Waar je daarna naartoe kunt

Een verhuizing is een van die handvol momenten waarop de structuur van een WordPress-site open ligt, en een goed moment om dingen aan te pakken die op de oude host maar half werkten. Begin met WordPress security hardening om de nieuwe installatie te beveiligen voordat DNS omgaat, want een verse server met default-configuratie en een bekend domein is een aantrekkelijk doelwit. Is de verhuizing bedoeld om prestaties te verbeteren, lees dan hoge TTFB bij WordPress om te checken of de nieuwe host het probleem ook echt oplost voordat je definitief gaat. En als de verhuizing zelf misging en de site nu een wit scherm of een kritieke fout toont, loopt het herstelpad via there has been a critical error on this website.

WordPress onderhoud zonder omkijken?

Ik regel updates, backups en beveiliging, en houd performance strak—zodat storingen en traagheid niet terugkomen.

Bekijk WordPress onderhoud

Doorzoek deze site

Begin met typen om te zoeken, of blader door de kennisbank en blog.