Contact Form 7 Event Listener: Track Real Submissions
Contact Form 7 fires a DOM event only when the mail actually sends. Here is how to turn that into a clean conversion in GA4, Google Ads and Meta.

Contact Form 7 has one genuinely good feature for tracking: it fires a different event depending on whether the email actually sent. Most form plugins do not make that distinction, and it is the difference between counting leads and counting attempts.
This post shows you how to catch that event and turn it into a conversion in GA4, Google Ads and Meta.
Why you need a listener
Contact Form 7 submits over AJAX. No page reload, no thank you page, no URL change. Page based tracking sees nothing.
What it does do is dispatch DOM events on the document. The important one is wpcf7mailsent, which fires only when the mail was successfully sent. There is also wpcf7invalid for validation failures and wpcf7mailfailed for send failures, which you do not want to count.
The listener code
This is the Contact Form 7 listener from DumbData.
The full listener is in the copy block at the bottom of this page, with a copy button. It is reproduced exactly as DumbData publish it, so you can copy it straight from here or from their page.
It listens for wpcf7mailsent and pushes an event called cf7submission, along with the form ID and the submitted inputs.
Installing it in GTM
Create a Custom HTML tag in Google Tag Manager and paste the listener.
Trigger it on All Pages, or limit it to the pages that contain the form.
Save and open Preview.
Creating the trigger
New trigger, type Custom Event.
Event name: cf7submission
Leave it on All Custom Events unless you want to split by form.
Save it as CE CF7 Submission.
Creating Data Layer Variables
Two are worth having:
Data Layer Variable named formId. Call it DLV CF7 Form ID.
Data Layer Variable named response. Call it DLV CF7 Response.
formId is the numeric Contact Form 7 ID, which you can see in the plugin’s form list. Write down which ID is which form somewhere, because a bare number in a report tells nobody anything.
Sending it to GA4
Create a GA4 Event tag.
Event name: generate_lead
Add a form_id parameter from your Data Layer Variable.
Trigger: CE CF7 Submission.
Use one event name across every form and separate them with parameters. Six differently named events are much harder to report on than one event with a form_id.
Sending conversions to Google Ads
Create a conversion action in Google Ads and note the ID and label.
Add a Google Ads Conversion Tracking tag in GTM with those values.
Trigger: CE CF7 Submission.
Turn on Enhanced Conversions if the form collects an email: Enhanced Conversions setup
Meta and everything else
Same trigger, different tag. A Meta Pixel tag with the Lead event, a Mixpanel or Piwik PRO tag from their GTM template, a LinkedIn or Microsoft conversion tag. You write the listener once and every platform reads from the same event.
Using the response data
The response value is an array of the submitted fields. It is useful and it contains whatever people typed, so treat it as personal data.
Reasonable uses: pulling the email for Enhanced Conversions or Meta matching, or reading a non personal dropdown such as enquiry type and sending that as a GA4 parameter.
Not reasonable: pushing names, emails or message text into analytics.
Testing
Open GTM Preview on a page with the form.
Submit it properly and wait for the green success message.
Confirm cf7submission appears in the event stream.
Check the Data Layer tab for formId.
Submit an invalid form and confirm nothing fires.
That last test is the one worth doing. If a failed submission fires your conversion, you are inflating your lead count.
Common issues
Nothing fires. Check the form is really Contact Form 7 and not another plugin using similar markup.
It fires on failures. You are listening for wpcf7submit rather than wpcf7mailsent. Use the listener above.
It fires twice. The listener is installed in GTM and also hardcoded in the theme or a plugin.
formId is undefined. The variable name must be exactly formId, with that capitalisation.
Privacy considerations
Never send names, emails, phone numbers or free text into GA4. It breaches Google’s terms and it is the most common way personal data ends up where it should not be.
Hash anything you send to an ad platform for matching.
Gate the tags behind marketing consent in your consent tool: Consent Mode v2 in GTM
Final thoughts
Contact Form 7 is one of the easier platforms to track properly, because the plugin already tells you the difference between sent and failed. Use wpcf7mailsent and you get a clean conversion with no extra work.
Listener maintained by DumbData. Their full listener library covers most other tools you are likely to hit.
Need this built properly?
A conversion should mean the email arrived, not that someone pressed a button. I set up and repair tracking for ecommerce stores and lead generation businesses, so the numbers in your ad accounts match the money in your bank account.
Have a look at what I do, or book a call and we can go through your setup together.
<script>
document.addEventListener( 'wpcf7mailsent', function( event ) {
window.dataLayer.push({
"event" : "cf7submission",
"formId" : event.detail.contactFormId,
"response" : event.detail.inputs
})
});
</script>


















