Headless Starter Kit: volledige handleiding
Headless Starter Kit installeren, instellen en uitrollen: WordPress-plugin plus een kant-en-klare Next.js 15-starter om WooCommerce headless te maken.
Deze handleiding behandelt de installatie, de configuratie en het volledige gebruik van Headless Starter Kit, de WordPress-plugin die van uw WooCommerce-winkel een headless commerce-opzet maakt, samen met een kant-en-klare Next.js 15-starter.
Voor wie is deze handleiding bedoeld? Voor ontwikkelaars, bureaus en technisch onderlegde handelaars die een bestaande WooCommerce headless willen maken zonder authenticatie, winkelwagen en afrekenen opnieuw uit te vinden. U moet vertrouwd zijn met de opdrachtregel, met Node.js en met wat serverconfiguratie als u voor Hetzner kiest.
Overzicht
Headless Starter Kit bestaat uit twee onderdelen die bij dezelfde aankoop worden geleverd:
- De WordPress-plugin (een ZIP die u uploadt in
/wp-admin/plugins.php), die aan de backendzijde het volgende beschikbaar stelt: JWT-authenticatie, een winkelwagen-API, een brug naar het afrekenen, een publiek configuratie-endpoint, ISR-webhooks en strikte CORS. - De Next.js 15-starter (een ZIP die u vanuit het WordPress-beheer downloadt zodra de plugin is geactiveerd en ingesteld), met een volledig Next.js-project met pagina’s voor home, overzicht, productpagina met ISR, winkelwagen, afrekenen, inloggen, registreren en de klantomgeving, en met omgevingsvariabelen die al met uw URL’s en geheimen zijn ingevuld.
De architectuur is bewust eenvoudig: uw WooCommerce blijft de bron van waarheid (producten, bestellingen, voorraad, betalingen) en Next.js gebruikt de REST API via beveiligde proxyroutes. Er wordt geen database gedupliceerd en er is geen replicatie te beheren.
Vereisten
Aan WordPress-zijde
- WordPress 6.4 of hoger
- WooCommerce 8.0 of hoger (getest tot 9.5)
- PHP 8.1 of hoger
- Permalinks ingesteld op Berichtnaam (niet op Eenvoudig)
- HTTPS actief (onmisbaar voor httpOnly-cookies en voor authenticatie in productie)
- Een paar WooCommerce REST-sleutels met lees- en schrijfrechten (aan te maken via WooCommerce → Instellingen → Geavanceerd → REST API)
Aan Next.js-zijde
- Node.js 20 of hoger (aanbevolen: beheer de versies met
nvm) - Hosting die Node ondersteunt: Vercel, een Hetzner-VPS, Netlify, Railway of elke server die Node 20+ kan draaien
Klassieke gedeelde hosting is niet geschikt om de Next.js-frontend te draaien, want die vereist een blijvende Node-runtime. De WordPress-plugin zelf werkt op elke WordPress-hosting.
De WordPress-plugin installeren
- Ga in het WordPress-beheer naar Plugins → Nieuwe plugin → Plugin uploaden.
- Selecteer het bestand
dfheadlessstarterkit.zipen klik op Nu installeren. - Klik op Plugin activeren.
- Er verschijnt een nieuw menu Headless Kit in de linkerzijbalk, met drie tabbladen: Instellingen, Diagnose en De starter downloaden.
Bij de activering genereert de plugin automatisch een willekeurig JWT-geheim en een willekeurig revalidatietoken. U kunt ze op elk moment opnieuw genereren via de instellingen.
Configuratie
Open Headless Kit → Instellingen. Elk onderdeel staat op zichzelf en is aan te passen zonder iets te herstarten.
URL van de frontend
Vul de volledige publieke URL van uw Next.js-applicatie in, zonder afsluitende slash. Bijvoorbeeld:
https://shop.voorbeeld.nl
Die URL dient voor drie zaken: het opbouwen van de ISR-webhooks, het vullen van de variabele NEXT_PUBLIC_SITE_URL in de geleverde starter, en het valideren van de standaard CORS-oorsprong.
JWT-geheim en revalidatietoken
Er worden twee geheimen gebruikt:
- JWT-geheim: ondertekent de access- en refreshtokens. Minstens 32 tekens. Deel dit nooit.
- Revalidatietoken: gaat mee in de header
Authorization: Bearer …van de ISR-webhooks. Moet identiek zijn aan de variabeleREVALIDATE_TOKENaan Next.js-zijde.
Naast elk veld staat een knop Opnieuw genereren, die met crypto.getRandomValues een cryptografisch sterk willekeurig geheim aanmaakt.
Na het opnieuw genereren van het JWT-geheim worden alle bestaande access- en refreshtokens ongeldig. Gebruikers moeten dan opnieuw inloggen. Waarschuw hen, of doe dit buiten de drukke uren.
Winkelwagenmodus: JWT of server?
De keuze maakt u met een keuzerondje in de instellingen.
JWT-modus (standaard, aanbevolen)
De volledige winkelwagen wordt geserialiseerd in een met HS256 ondertekend token en teruggegeven via de header X-DFHSK-Cart. Er wordt niets aan WordPress-zijde opgeslagen. Ideaal voor:
- uitrol op Vercel edge, Cloudflare of meerdere instanties;
- winkels met veel verkeer, waar het vermijden van een databaseaanroep per verzoek pure winst is;
- opzetten waarin WordPress puur als API dient en geen sessies nodig heeft.
Servermodus (WC_Session)
De winkelwagen leeft in de ingebouwde WC_Session-tabel van WooCommerce. Kies hiervoor als:
- u WooCommerce-uitbreidingen gebruikt die op de winkelwagen aanhaken (WooCommerce Subscriptions, Dynamic Pricing, YITH-plugins en dergelijke);
- u de ingebouwde sessielogica van WooCommerce wilt behouden (ingebouwde herinneringen bij verlaten winkelwagens, cross-sell aan de serverzijde en zo verder).
CORS-oorsprongen
Een strikte whitelist van oorsprongen die de API mogen aanroepen. Eén oorsprong per regel, in het volledige formaat https://…. Wildcards voor subdomeinen worden ondersteund:
https://shop.voorbeeld.nl
https://preview.voorbeeld.nl
https://*.previews.voorbeeld.nl
http://localhost:3000
Voeg http://localhost:3000 toe tijdens de ontwikkeling en haal die er in productie weer uit.
ISR-gebeurtenissen
Vijf selectievakjes bepalen welke WordPress-gebeurtenissen een ISR-webhook naar Next.js sturen:
- Producten:
save_post_product,woocommerce_update_product - Categorieën: aanmaken, bijwerken en verwijderen van termen in de taxonomie
product_cat - Bestellingen: statuswijzigingen (handig om de klantaccountpagina te verversen)
- Pagina’s:
save_post_page - Coupons: aanmaken en bijwerken van kortingscodes
Met een tekstveld Te revalideren paden legt u precies vast welke Next.js-paden per gebeurtenis worden gerevalideerd (standaard leidt de plugin de betrokken paden zelf slim af).
Diagnose
Tabblad Headless Kit → Diagnose. Bij elke weergave van de pagina lopen elf automatische controles:
- WooCommerce actief: de klasse
WooCommerceis beschikbaar - Nette permalinks: de structuur staat niet op Eenvoudig
- REST API bereikbaar:
/wp-json/antwoordt met een 200 - HTTPS actief:
is_ssl()geeft true terug - WPGraphQL herkend: alleen informatief, niet blokkerend
- JWT-geheim ingesteld: minstens 32 tekens
- URL van de frontend ingesteld: niet leeg en met een geldig URL-formaat
- CORS-oorsprongen ingevuld: minstens één oorsprong
- Revalidatietoken ingesteld: minstens 24 tekens
- WooCommerce REST-sleutels: de plugin vindt een actief paar consumer_key en consumer_secret
- Winkelwagenmodus leesbaar: de gekozen opslag werkt
Elke controle toont groen (in orde), oranje (waarschuwing, niet blokkerend) of rood (blokkerend). Los alles wat rood staat op vóór u live gaat.
De Next.js-starter downloaden en starten
Zodra de instellingen zijn ingevuld en de diagnose op groen staat, opent u Headless Kit → De starter downloaden. Klik op de grote knop Next.js-starter downloaden.
De geleverde ZIP is een volledig Next.js 15-project, ter plekke gegenereerd met uw URL’s en geheimen er al in verwerkt. De plaatsaanduidingen die bij het genereren worden vervangen:
{{SITE_URL}}wordt de URL van uw WordPress{{FRONTEND_URL}}wordt de ingestelde frontend-URL{{REVALIDATE_TOKEN}}wordt uw revalidatietoken{{CURRENCY}}wordt de WooCommerce-valuta{{SITE_NAME}}wordt de titel van de site{{LOCALE}}wordt de WordPress-locale (nl, fr, en, es en zo verder)
Het bestand .envtmpl wordt bij het genereren hernoemd naar .env.example.
Omgevingsvariabelen die u zelf moet aanvullen
Sommige waarden kunnen niet automatisch worden opgehaald; die voegt u zelf toe aan het bestand .env (aan te maken vanuit .env.example):
WOO_REST_CONSUMER_KEY=ck_xxxxxxxxxxxxxx
WOO_REST_CONSUMER_SECRET=cs_xxxxxxxxxxxxxx
SESSION_PASSWORD=uw-wachtwoord-van-minstens-32-tekens
Genereer een sterk SESSION_PASSWORD:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Lokale ontwikkeling
npm install
cp .env.example .env
# Vul in .env uw ontbrekende geheimen aan
npm run dev
De frontend is bereikbaar op http://localhost:3000. Voeg die URL tijdens de ontwikkeling toe aan de CORS-oorsprongen in WordPress.
Uitrol op Vercel
npx vercel link
npx vercel env pull .env.production
npx vercel deploy --prod
Stel daarna alle omgevingsvariabelen in het Vercel-dashboard in (Project → Settings → Environment Variables). Het meegeleverde bestand vercel.json zet de regio op cdg1 (Parijs) en schakelt de cache uit op de routes /api/*.
Uitrol op Hetzner (of elke VPS met Ubuntu of Debian)
# Op de server, als root of met sudo
git clone uw-repo.git storefront && cd storefront
cp .env.example .env
nano .env # Vul alle variabelen in
bash deploy/hetzner.sh
Het script installeert zo nodig Docker, bouwt het image, start de container en stelt de dienst beschikbaar op 127.0.0.1:3000. Zet Caddy of nginx ervoor als reverse proxy voor TLS. Een minimaal Caddyfile:
shop.voorbeeld.nl {
encode zstd gzip
reverse_proxy 127.0.0.1:3000
}
Beschikbare REST-endpoints
Alle endpoints van de plugin staan onder de namespace dfhsk/v1. De volledige URL is https://voorbeeld.nl/wp-json/dfhsk/v1/…
Authenticatie
POST /auth/login: body{ username, password }, geeft{ token, refresh_token, user }terugPOST /auth/refresh: body{ refresh_token }, geeft een nieuwtokenterugGET /auth/me: headerAuthorization: Bearer …, geeft de huidige gebruiker terugPOST /auth/register: body{ email, password, first_name, last_name }POST /auth/logout: maakt het refreshtoken ongeldig
Winkelwagen
Alle aanroepen geven het winkelwagentoken mee via de header X-DFHSK-Cart. De server geeft bij elk antwoord een nieuw token terug in diezelfde header.
GET /cart: volledige momentopname (artikelen, totalen, btw, verzendkosten)POST /cart/add: body{ product_id, quantity, variation? }POST /cart/update: body{ key, quantity }POST /cart/remove: body{ key }POST /cart/coupon: body{ code }DELETE /cart/coupon/{code}POST /cart/shipping: body{ country, postcode }, geeft de toepasselijke tarieven terugPOST /cart/clear
Afrekenen
POST /checkout/create-order: body{ payment_method, billing, shipping? }, geeft{ order_id, order_key, redirect }terug. Deredirectis de URL naar de betaaldienst (Stripe, PayPal en dergelijke).GET /checkout/order/{id}: vereist de headerAuthorization: Bearer …
Publieke configuratie
GET /config: bereikbaar zonder authenticatie. Geeft{ currency, base_country, countries, payment_methods, tax_settings }terug. De Next.js-starter gebruikt dit endpoint om de afrekenformulieren te vullen.
ISR-webhooks (aan Next.js-zijde)
De plugin stuurt een POST naar {FRONTEND_URL}/api/revalidate met de header Authorization: Bearer {REVALIDATE_TOKEN}. De body is JSON:
{
"paths": ["/products/linnen-blazer", "/products"],
"tags": ["product:linnen-blazer"],
"reason": "wc_update_product"
}
De route /api/revalidate die in de starter is meegeleverd, valideert het token en roept daarna voor elk item revalidatePath en revalidateTag aan.
De starter aanpassen
De geleverde code valt onder de licentie GPL v2: u mag die zonder beperking wijzigen, uitbreiden en verspreiden. De gebruikelijke aanknopingspunten:
- Kleurenpalet:
tailwind.config.ts, paletbrand(standaard oranje) - Winkelcomponenten:
src/components/shop/(Header, Footer, ProductCard, CartProvider) - Publieke pagina’s:
src/app/(shop)/ - Pagina’s van de klantomgeving:
src/app/(auth)/ - Opmaak van prijzen en datums:
src/lib/format.ts - TypeScript-types:
src/types/woo.ts - Helper voor API-aanroepen:
src/lib/woo-rest.ts(de functieswooRestendfhskFetch)
Om bijvoorbeeld een nieuwe pagina toe te voegen die de producten van een merk toont, dupliceert u src/app/(shop)/products/page.tsx en past u de WooCommerce REST-query aan. De functie wooRest<T>() handelt de Basic-authenticatie automatisch af.
Problemen oplossen
CORS-fout in de browserconsole
De oorsprong van de frontend staat niet op de whitelist. Voeg die toe bij Instellingen → CORS-oorsprongen, één per regel en zonder afsluitende slash.
ISR-webhooks die 401 teruggeven
Het REVALIDATE_TOKEN aan Next.js-zijde komt niet overeen met het token dat in WordPress is ingesteld. Kopieer de exacte waarde uit de WordPress-instellingen naar de .env van Next.js en rol opnieuw uit.
Inloggen geeft 403 ondanks juiste gegevens
Controleer of het gebruikersaccount wel een wachtwoord heeft (en niet alleen een sociale login), of HTTPS in productie actief is, en of het JWT-geheim minstens 32 tekens telt. Raadpleeg het tabblad Diagnose.
De winkelwagen loopt leeg tussen twee pagina’s
Controleer in de JWT-modus of de starter het token wel leest en schrijft in localStorage (sleutel dfhsk_cart_token). Open de browserinspectie en ga naar Application → Local Storage.
Een in WooCommerce aangemaakte bestelling verschijnt niet aan Next.js-zijde
Controleer of de gebeurtenis Bestellingen wel is aangevinkt bij de ISR-gebeurtenissen en of de webhook zonder fout vertrekt (zet WP_DEBUG_LOG aan).
Verder gaan
De starter is een vertrekpunt, geen afgewerkt product. Afhankelijk van uw project kunt u overwegen om toe te voegen:
- een zoekmachine met directe resultaten (Algolia, Meilisearch, Typesense), gevoed door dezelfde ISR-webhooks;
- redactionele inhoud in WordPress met de plugin ACF of een vergelijkbare oplossing, plus een eigen Next.js-pagina;
- een PWA met service worker voor offlinegebruik (zie ook onze module dfpwa);
- AI-personalisatie in realtime (zie dfsmartcontent).
Neem voor technische vragen contact op met de DataFirefly-support en voeg uw logs en de resultaten van het tabblad Diagnose toe.