Contact Form 7 + Meta Ads Conversion Tracking Setup
I see broken Contact Form 7 to Meta Ads tracking in about 35% of WordPress sites I audit. The main culprit? People try to track the form submit button click instead of listening for the actual wpcf7mailsent event that Contact Form 7 fires when the email is successfully sent. This results in counting failed submissions as conversions, which completely screws up your ROAS calculations.
The setup below uses Meta’s Conversions API (CAPI) alongside the pixel for maximum data coverage and proper event deduplication.
What You’ll Have Working By The End
- Contact Form 7 submissions automatically tracked as Lead events in Meta Ads
- Server-side tracking via Meta CAPI for users who block the pixel (15-25% of traffic)
- Proper event deduplication between pixel and CAPI
- Lead event data including form ID and page URL for optimization
- Accurate conversion attribution even with iOS 14.5+ tracking limitations
Prerequisites
- Contact Form 7 plugin installed and forms created
- Meta Pixel installed (via GTM or directly in theme)
- Google Tag Manager container on your site
- Meta Business Manager access with Events Manager permissions
- Server that can make HTTP requests (for CAPI)
- Meta Conversions API access token generated
Step 1: Set Up the Contact Form 7 Event Listener
Contact Form 7 fires a wpcf7mailsent DOM event when a form is successfully submitted and the email is sent. We need to capture this and push it to the data layer.
Add this JavaScript to your theme’s functions.php file or as a custom HTML tag in GTM:
<script>
document.addEventListener('wpcf7mailsent', function(event) {
// Generate unique event ID for deduplication
var eventId = 'cf7_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
// Get form details
var formId = event.detail.contactFormId;
var formElement = event.target;
var formTitle = formElement.querySelector('.wpcf7-form').getAttribute('data-title') || 'Contact Form ' + formId;
// Push to data layer for GTM
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'cf7_form_success',
'form_id': formId,
'form_title': formTitle,
'page_url': window.location.href,
'event_id': eventId,
'conversion_value': 0 // Set your lead value here
});
console.log('CF7 form submitted:', {
formId: formId,
eventId: eventId,
formTitle: formTitle
});
}, false);
</script>
Important: Don’t use wpcf7submit or button click events. The wpcf7mailsent event only fires when the form actually processes successfully, which is what you want for conversion tracking.
Step 2: Create the GTM Trigger
In GTM, create a new trigger:
- Trigger Type: Custom Event
- Event Name:
cf7_form_success - This trigger fires on: All Custom Events
- Name: CF7 - Form Success
Save the trigger.
Step 3: Create Data Layer Variables
Create these variables in GTM to capture the form data:
Variable 1: CF7 Form ID
- Variable Type: Data Layer Variable
- Data Layer Variable Name:
form_id - Name: CF7 - Form ID
Variable 2: CF7 Event ID
- Variable Type: Data Layer Variable
- Data Layer Variable Name:
event_id - Name: CF7 - Event ID
Variable 3: CF7 Form Title
- Variable Type: Data Layer Variable
- Data Layer Variable Name:
form_title - Name: CF7 - Form Title
Step 4: Create the Meta Pixel Tag
Create a new tag in GTM:
- Tag Type: Meta Pixel
- Pixel ID: Your Meta Pixel ID
- Event Type: Standard
- Event Name: Lead
- Object Properties:
content_name: {{CF7 - Form Title}}content_category: contact_formform_id: {{CF7 - Form ID}}source: contact_form_7
- Event ID: {{CF7 - Event ID}}
- Triggering: CF7 - Form Success
Which event should you use? Use the standard “Lead” event rather than a custom conversion for better optimization. Meta’s algorithm works better with standard events, and you can create custom conversions from the Lead event data in Events Manager later.
Step 5: Set Up Meta Conversions API (CAPI)
For maximum tracking coverage, set up server-side tracking via CAPI. This requires server-side code. Here’s a PHP example:
<?php
// Add this to your theme's functions.php or a custom plugin
function send_cf7_to_meta_capi($contact_form, $abort, $submission) {
if ($abort) return;
$access_token = 'YOUR_CAPI_ACCESS_TOKEN';
$pixel_id = 'YOUR_PIXEL_ID';
// Get form data
$form_id = $contact_form->id();
$posted_data = $submission->get_posted_data();
// Generate the same event ID format as client-side
$event_id = 'cf7_' . time() . '_' . wp_generate_password(9, false);
// Get user data for better matching
$user_data = array(
'client_ip_address' => $_SERVER['REMOTE_ADDR'],
'client_user_agent' => $_SERVER['HTTP_USER_AGENT'],
'fbc' => isset($_COOKIE['_fbc']) ? $_COOKIE['_fbc'] : null,
'fbp' => isset($_COOKIE['_fbp']) ? $_COOKIE['_fbp'] : null
);
// Add email if captured in form
if (!empty($posted_data['email'])) {
$user_data['em'] = hash('sha256', strtolower(trim($posted_data['email'])));
}
// Prepare the event data
$event_data = array(
'event_name' => 'Lead',
'event_time' => time(),
'event_id' => $event_id,
'action_source' => 'website',
'event_source_url' => home_url($_SERVER['REQUEST_URI']),
'user_data' => array_filter($user_data),
'custom_data' => array(
'content_name' => get_the_title() . ' - Contact Form ' . $form_id,
'content_category' => 'contact_form',
'form_id' => $form_id,
'source' => 'contact_form_7'
)
);
// Send to Meta CAPI
$capi_data = array(
'data' => array($event_data)
);
$args = array(
'body' => json_encode($capi_data),
'headers' => array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $access_token
),
'timeout' => 15
);
wp_remote_post(
"https://graph.facebook.com/v18.0/{$pixel_id}/events",
$args
);
}
// Hook into Contact Form 7 submission
add_action('wpcf7_mail_sent', 'send_cf7_to_meta_capi', 10, 3);
?>
Event deduplication is critical. Both the client-side pixel and CAPI must use the same event_id to prevent double-counting conversions.
Step 6: Testing & Verification
Test in Meta Events Manager
- Go to Events Manager → Test Events
- Enter your website URL and click Open Website
- Submit a Contact Form 7 form
- Check the Test Events tab for:
- Lead event received via pixel
- Lead event received via CAPI (if implemented)
- Same
event_idon both events - Proper deduplication (should show as 1 event, not 2)
Verify GTM Data Layer
Open browser dev tools, submit a form, and check the console. You should see:
CF7 form submitted: {
formId: 123,
eventId: "cf7_1703123456_abc123def",
formTitle: "Contact Form"
}
Cross-Check Conversion Counts
Compare these numbers weekly:
- Contact Form 7 submission count (if using Flamingo plugin)
- Meta Ads Lead conversion count
- Acceptable variance: 5-15% difference is normal due to:
- Users with JavaScript disabled (rare but exists)
- Ad blockers preventing pixel fire
- Server-side CAPI failures
Troubleshooting
Problem: Events show in Test Events but not in Ads Manager conversions
→ Solution: Check if you’ve created a custom conversion for the Lead event or are using a custom event name that doesn’t match your campaign optimization settings.
Problem: Getting duplicate events (pixel + CAPI showing as 2 conversions)
→ Solution: Ensure both client-side and server-side code are using identical event_id values. The format and generation method must match exactly.
Problem: Form submissions not triggering the data layer push
→ Solution: Check if other plugins are interfering with the wpcf7mailsent event. Try adding the event listener with setTimeout to ensure it runs after other scripts: setTimeout(function() { /* your code here */ }, 100);
Problem: CAPI events showing “No Match” in Events Manager
→ Solution: Improve user data matching by capturing more identifiers like phone number (hashed) or ensuring the email field is properly captured and hashed with SHA256.
Problem: Events firing on form submission but before validation
→ Solution: You’re probably listening for wpcf7submit instead of wpcf7mailsent. Only wpcf7mailsent fires after successful validation and email sending.
Problem: Meta showing much lower conversion counts than form submissions
→ Solution: This usually indicates the pixel isn’t firing properly. Check for JavaScript errors, ad blocker interference, or that your Meta Pixel ID is correct in GTM.
What To Do Next
Now that your Contact Form 7 submissions are tracking properly in Meta Ads, consider these next steps:
- Set up Google Ads tracking: Contact Form 7 to Google Ads conversion tracking for cross-platform attribution
- Add GA4 tracking: Contact Form 7 to GA4 conversion tracking to analyze lead quality and user behavior
- Connect to your CRM: Contact Form 7 to HubSpot integration to close the loop on lead-to-customer attribution
- Need help with your setup? Get a free tracking audit — I’ll review your implementation and catch any issues you might have missed.
This guide is part of the Meta Ads Conversion Tracking Hub — complete guides for tracking any conversion type in Meta Ads.