Formulieren in de headless rebuild (Gravity Forms REST API v2)¶
Dit hoofdstuk beschrijft hoe de Next.js-frontend de bestaande Gravity Forms-formulieren
rendert en verstuurt. Uitgangspunt: de formulierdefinities, validatie, notificaties en
add-on-gedrag (User Registration, Mailchimp/Listmonk, Mollie) blijven in WordPress;
de frontend praat met de GF REST API v2 (/wp-json/gf/v2/…).
Huidige stand¶
- Namespace
gf/v2is actief (GF 2.9 registreert de v2-routes altijd). - Web API-instellingen:
enabled=1; er bestaan al API-keys inwp_gf_rest_api_keys(3× "dynamics" read_write — in gebruik door de Dynamics 365-koppeling die entries uitleest — en 2× "gb-mail-overzicht" read). Voor de rebuild een eigen key aanmaken. GET /wp-json/gf/v2/forms→ 401 zonder authenticatie; formulierdefinities ophalen vereist een API-key.POST /wp-json/gf/v2/forms/{id}/submissionsis publiek (geverifieerd): zonder auth levert een ongeldige inzendingis_valid:falseplus veldvalidatiefouten op.
Formulierdefinitie ophalen (server-side)¶
- Alleen server-side aanroepen (Next.js server component / route handler) — nooit de key naar de browser sturen. De response bevat óók gevoelige configuratie (notificatie-adressen, confirmations); geef alleen de benodigde velden door aan de client.
- De response bevat per veld:
type,label,isRequired,choices,inputs(subvelden),conditionalLogic,visibility,pageNumber, prijsinformatie (product-velden) en prepopulate-instellingen (allowsPrepopulate+inputName). - Definities zijn cachebaar (ISR/revalidate); ze wijzigen alleen bij beheer in wp-admin.
De frontend moet zelf implementeren (gedrag dat GF nu server-side rendert):
| GF-gedrag | Rebuild-verantwoordelijkheid |
|---|---|
| Conditionele logica (SHOW/HIDE, EN/OF) | client-side evalueren; verborgen velden niet meesturen en niet valideren |
Meerstaps-formulieren (page-velden, formulieren 21 en 45) |
stappen + voortgangsindicator client-side; validatie per stap; de REST-submission is één POST met alle velden |
| Product-/totaalvelden | bedragen client-side optellen voor weergave; het server-side berekende totaal is leidend voor de betaling |
Prepopulate (queryparameters actie, adres, betalingskenmerk, email) |
query → veldwaarde mappen |
| Nederlandse sublabels (Voornaam, Plaats, …) | het thema vertaalt die bij render; de REST-definitie bevat de Engelse sublabels tenzij een customLabel is gezet — vertaling in de frontend-componentlaag |
Verborgen admin-velden (known_user, hidden radio's) |
niet renderen en niet meesturen; WordPress vult ze server-side |
Versturen¶
POST /wp-json/gf/v2/forms/{id}/submissions
Content-Type: application/json
{
"input_1": "waarde",
"input_33_3": "Voornaam", // subveld 33.3 → underscore-notatie
"input_11_1": "1" // consent-checkbox
}
- Veldsleutels:
input_{veldId}, subvelden met underscore (input_33_3voor veld 33.3). - Succesvolle response:
is_valid: true+confirmation_message(HTML) ofconfirmation_type: "redirect"metconfirmation_redirect-URL. - De server-side hooks vuren gewoon bij REST-submissions: notificaties, User
Registration-feeds (synchroon), Mailchimp/Listmonk,
known_user, Excel-bijlagen.
Validatiefout-afhandeling¶
Bij een ongeldige inzending:
{
"is_valid": false,
"validation_messages": { "2": "Dit veld is vereist.", "9": "…" },
"page_number": 1
}
validation_messagesis gekeyed op veld-ID → mappen op de betreffende formuliervelden, focus naar het eerste foutveld, ingevulde waarden behouden.- Bij meerstaps-formulieren geeft
page_numberaan op welke stap de fout zit — de frontend navigeert naar die stap. - Custom validaties draaien mee (NL-IBAN op formulier 45, Gemeenten-list op 24): de foutteksten komen uit WordPress en moeten getoond worden zoals ontvangen.
reCAPTCHA — aandachtspunt¶
De meeste publieke formulieren bevatten een captcha-veld (Google reCAPTCHA v2
checkbox, sitekey 6Lcnym8bAAAAAFAebeRVziCoEiXwR-uXRZVTLQ-L). Voor de rebuild:
- de frontend rendert zelf de reCAPTCHA-widget (of een v3/enterprise-opvolger — beslispunt)
en stuurt het token mee in de submission (
input_{captchaVeldId}/g-recaptcha-response); WordPress valideert server-side; - verifiëren dat de GF REST-submission de captcha daadwerkelijk afdwingt — in de huidige situatie is dit niet expliciet getest. Zolang dat niet vaststaat, geldt de frontend-captcha niet als spam-bescherming;
- het thema skipt captcha-validatie voor formulier 46 in development — gedrag behouden voor e2e-tests of vervangen door een test-sitekey;
- de honeypot-instelling van GF geldt ook voor REST-submissions: geen extra (honeypot-)velden meesturen die niet in de definitie staan.
Cookie- en redirect-gedrag via REST¶
Twee thema-hooks doen bij een klassieke page-submit iets wat via REST niet bij de client aankomt:
- Paywall-formulier 29:
setcookie('subscribed-to-newsletter', …)+wp_redirect— headers van een REST-response bereiken de Next.js-gebruiker niet als paginacookie/redirect. De frontend moet na een geslaagde submission zelf het cookie (of een eigen equivalent) zetten, het betreffende artikel ontgrendelen en de paywall-teksten omschakelen (zie Nieuwsbrief). - Confirmations van het type
page/redirect(formulieren 18, 20, 21, 34, 35, 37, 38, 41, 42, 45): de frontend leestconfirmation_redirectuit de response en navigeert client-side; de WP-URL's moeten daarbij naar Next.js-routes worden gemapt.
Mollie-redirect-flow — open punt¶
Nog te verifiëren vóór de bouw van de betaalformulieren
Bij de 8 Mollie-formulieren maakt de Mollie-add-on na een geldige submission een
betaling aan en redirect de gebruiker naar de Mollie-checkout; de webhook werkt daarna
de entry bij (complete_payment). Niet vastgesteld is of de REST-submission-response
de Mollie-checkout-URL bevat, en hoe het mollie-veld (Mollie
Components/methode-keuze, gekoppeld aan het Mollie-profiel) zich zonder de
GF-frontend-scripts gedraagt. Vereiste spike vóór de bouw:
- testbetaling via
POST /gf/v2/forms/34/submissionsin Mollie-testmode; - vastleggen: checkout-URL in de response? return-URL? entry-status bij
paid/canceled/failed/expired? vuurt
complete_payment(incl. de bestelbevestiging + downloadlink van formulier 40)? - zo nodig een eigen server-side endpoint bouwen dat de Mollie-betaling aanmaakt en de checkout-URL teruggeeft (de GF-entry blijft dan de bron voor BC-omschrijving en webhookverwerking).
Tot die tijd gelden de betaal-acceptatiecriteria in Donaties (Mollie) als functioneel kader, niet als bewezen technisch pad.
Accountformulieren (18/24/25)¶
De update-feeds van User Registration werken op de ingelogde gebruiker. Headless
betekent dat de submission met de identiteit van de gebruiker bij WordPress moet
aankomen (cookie-proxy of de JWT-laag gb-app/v1 + server-side submission met
user-context). De huidige site schermt alleen de pagína af, niet het formulier — de
rebuild moet dit server-side afdwingen. Zie Account.
Acceptatiecriteria (API-laag)¶
- Als Next.js-server kan ik met de nieuwe API-key
GET /wp-json/gf/v2/forms/{id}aanroepen voor elk ge-embed formulier en bevat de response velden, condities en pagina-indeling. - Als anonieme client kan ik
POST /wp-json/gf/v2/forms/2/submissionsdoen; met geldige invoer krijg ikis_valid: trueen de confirmation-tekst, met ontbrekende verplichte veldenis_valid: falsemetvalidation_messagesper veld-ID. - Als anonieme client krijg ik op
GET /wp-json/gf/v2/formszonder key een 401. - Als client die een submission doet op een formulier met redirect-confirmation (bijv. 20), dan bevat de response het redirect-doel en navigeert de frontend daarheen.
- Als systeem: een REST-submission op formulier 22 leidt tot een Mailchimp- én Listmonk-inschrijving (hooks vuren server-side).
- Als systeem: een REST-submission op formulier 17 met onbekend e-mailadres maakt een niet-geactiveerd
wv-subscriber-account aan (known_user-hook werkt via REST). - Als client zonder geldig reCAPTCHA-token op een captcha-formulier: de submission wordt geweigerd (te bevestigen in de spike; zo niet, dan is aanvullende spam-bescherming vereist vóór livegang).
- Als beheerder wijzig ik een veldlabel in wp-admin; na cache-revalidatie toont de frontend het nieuwe label zonder deploy.
Bekende afwijkingen¶
NIET nabouwen — wel vermelden in het testrapport
- De GF Web API v1 (legacy public/private key) staat nog geconfigureerd; niet overnemen — alleen v2 met keys gebruiken.
- De bestaande "dynamics"-keys (read_write) en testformulier 43 horen bij de Dynamics 365-entry-uitlezing; deze koppeling moet blijven werken en valt buiten de frontend-rebuild.