Naar de inhoud

Gravity Forms-inzendingen meten in GA4, met Consent Mode

Elke Gravity Forms-inzending als generate_lead in GA4, met formulier-ID en titel erbij. Zonder dubbeltellingen, zonder spam, en netjes achter Consent Mode.

Gecontroleerd 18 september 2026 6 min lezen

De klassieke manier om formulieren te meten is de bedankpagina als doel instellen. Dat werkt tot het niet meer werkt. Toont je formulier een bericht in plaats van door te verwijzen, dan is er geen bedankpagina. Ververst iemand die pagina, dan heb je twee leads. En welke van je vijf formulieren het was, zie je nergens.

Het kan netter: één event per echte inzending, met het formulier erbij. Hieronder de opzet die ik zelf gebruik. Hij werkt met de gewone Google-tag, dus zonder Tag Manager, en nieuwe formulieren doen vanzelf mee.

Wat je wilt meten

Eén event: generate_lead. Dat is een van de aanbevolen events van GA4, dus Google weet wat het betekent. Daarbij twee parameters: form_id en form_title. Zo filter je later per formulier, zonder per formulier iets in te stellen.

Een inzending eindigt op drie manieren

Dit is waar de meeste oplossingen de mist in gaan. Gravity Forms kent drie routes na het versturen, en elke route vraagt iets anders.

  • Doorverwijzing naar een bedankpagina. De bevestiging wordt niet in de pagina geladen. De bedankpagina moet dus zelf weten dat er een lead is.
  • Bericht via AJAX. Gravity Forms vuurt het jQuery-event gform_confirmation_loaded af, met het formulier-ID.
  • Bericht zonder AJAX. De pagina herlaadt en toont de bevestiging in hetzelfde request. PHP weet dan welk formulier het was.

Stap 1: laat de bevestiging vertellen welk formulier het was

Het filter gform_confirmation draait voordat Gravity Forms de doorverwijzing uitvoert. De URL is daar nog aan te passen. Geef het formulier-ID mee als parameter, maar alleen naar je eigen site.

add_filter( 'gform_confirmation', function ( $confirmation, $form, $entry, $ajax ) {
	// Spam krijgt gewoon een bevestiging, maar telt niet mee.
	if ( 'spam' === ( $entry['status'] ?? '' ) ) {
		return $confirmation;
	}

	if ( is_array( $confirmation ) && ! empty( $confirmation['redirect'] ) ) {
		$confirmation['redirect'] = add_query_arg( 'lead', (int) $form['id'], $confirmation['redirect'] );
	}

	return $confirmation;
}, 20, 4 );

Op de bedankpagina staat het formulier zelf niet, dus de titel haal je daar in PHP op en geef je mee aan je script.

$form_id = isset( $_GET['lead'] ) ? absint( $_GET['lead'] ) : 0;
$form    = ( $form_id && class_exists( 'GFAPI' ) ) ? GFAPI::get_form( $form_id ) : null;
$lead    = $form ? array( 'id' => (int) $form['id'], 'title' => $form['title'] ) : null;

printf( '<script>var LEAD = %s;</script>', wp_json_encode( $lead ) );

Stap 2: verstuur het event

Eén functie die het event verstuurt, en twee plekken die hem aanroepen. Het script hoort in de footer, na jQuery.

function trackLead( formId, title ) {
	if ( typeof window.gtag !== 'function' ) {
		return;
	}
	window.gtag( 'event', 'generate_lead', {
		form_id: formId,
		form_title: title || ( 'Formulier ' + formId )
	} );
}

// Doorverwijzing: de lead hoort bij deze pagina.
if ( window.LEAD ) {
	trackLead( LEAD.id, LEAD.title );

	// Parameter weghalen, zodat een refresh niet nog een keer telt.
	var url = new URL( window.location.href );
	url.searchParams.delete( 'lead' );
	window.history.replaceState( window.history.state, '', url.toString() );
}

// Bericht via AJAX.
jQuery( document ).on( 'gform_confirmation_loaded', function ( event, formId ) {
	trackLead( formId );
} );

Voor de derde route, een bericht zonder AJAX, onthoud je het formulier in hetzelfde filter uit stap 1 en print je het mee als LEAD. De rest van het script blijft gelijk. Wil je bij AJAX ook de titel meesturen, onthoud dan via gform_pre_render de titels van de formulieren op de pagina en geef die lijst mee.

Stap 3: houd spam uit je cijfers

Gravity Forms geeft spam bewust dezelfde bevestiging als een echte inzending, zodat een bot niets merkt. Via AJAX vuurt gform_confirmation_loaded dus ook bij spam. Zet in het filter een verborgen marker in de bevestiging als de inzending spam is, en laat je script die overslaan. Hoe je die spam überhaupt tegenhoudt, staat in spam via je contactformulier tegenhouden.

Daar hoeft je eventcode niets voor te doen, en dat is precies het punt. Je cookieplugin zet Consent Mode op geweigerd voordat de Google-tag laadt, en werkt dat bij zodra de bezoeker kiest. De tag laadt altijd. Geeft iemand toestemming, dan gaat het event met cookies mee. Weigert iemand, dan stuurt GA4 een ping zonder cookies en vult Google het gat met modellering.

Eén ding moet kloppen: de volgorde. De consent-standaard moet in de head staan vóór de Google-tag. Staat hij erna, dan vertrekt de eerste paginaweergave al met cookies voordat iemand iets gekozen heeft.

In GA4 afmaken

  1. Verstuur een testformulier en kijk in Beheer, DebugView of generate_lead binnenkomt met beide parameters.
  2. Maak onder Beheer, Aangepaste definities twee aangepaste dimensies met het bereik Gebeurtenis: form_id en form_title. Zonder die stap komen de parameters wel binnen, maar zie je ze in geen enkel rapport.
  3. Markeer generate_lead als belangrijke gebeurtenis, zodat hij als conversie meetelt.

Je eigen tests buiten de cijfers

Elke test die je doet is anders een lead. Stuur voor ingelogde beheerders debug_mode mee in de config van de tag, en zet in GA4 het datafilter voor ontwikkelaarsverkeer aan. Let op één gemeen detail: ook debug_mode: false zet de debugmodus aan. Stuur de parameter dus alleen mee als hij waar is.

gtag( 'config', 'G-XXXXXXX', isTest ? { debug_mode: true } : {} );

Waar het meestal misgaat

  • De parameter blijft in de URL staan. Elke refresh en elke gedeelde link is dan een nieuwe lead. Haal hem weg met replaceState zodra het event verstuurd is.
  • Iemand zet AJAX aan of uit op een formulier. Meet je maar één route, dan valt dat formulier stil uit je cijfers. Vang alle drie de routes af, dan maakt de instelling niet meer uit.
  • De aangepaste dimensies zijn vergeten. Het event telt, maar je kunt niet zien welk formulier het was. Ze werken niet met terugwerkende kracht, dus maak ze meteen aan.
  • Een paginacache die querystrings negeert. De bedankpagina komt dan uit de cache, zonder lead. Sluit de parameter uit van caching, of lees hem volledig in JavaScript uit.
  • De tag staat in de footer. Bij een snelle doorverwijzing bestaat gtag dan nog niet op het moment dat je het event verstuurt. De Google-tag hoort in de head.
  • Je gebruikt Tag Manager. Dan bestaat gtag niet. Vervang de aanroep door een dataLayer.push met dezelfde gegevens en maak de tag in GTM.

Tot slot

Eén event, drie routes, twee parameters. Daarna zie je in GA4 niet alleen dat er een aanvraag binnenkwam, maar ook via welk formulier en vanaf welke pagina. Komen de aanvragen wel in GA4 maar niet in je mailbox, dan ligt het aan iets anders. Daarover gaat WordPress mail komt niet aan.

Loop je hier alsnog op vast?

Stuur me een bericht met wat je precies ziet gebeuren. Meestal weet ik binnen een paar minuten waar het zit.

Kom in contact
Contact

Stel je technische vraag

Vertel wat er speelt op je site; ik laat weten wat er nodig is.

Dit veld is bedoeld voor validatiedoeleinden en moet niet worden gewijzigd.
Hoe concreter, hoe beter ik kan inschatten wat er nodig is.