Track WPForms Submissions
WPForms submits via AJAX by default, so GTM’s native Form Submission trigger never fires on success. The reliable path is to hook WPForms’ own jQuery success event and push to the dataLayer only after the server confirms. This recipe wires that up and sends a GA4 generate_lead event.
Valid as of April 2026, WPForms 1.9.x.
The success signal
Section titled “The success signal”WPForms dispatches two relevant jQuery events:
wpformsBeforeFormSubmit— fires on submit click, before the server accepts the submission. Do not use this for conversion tracking.wpformsSubmitSuccess— fires after WPForms’ AJAX endpoint returns a success response. This is the one you want.
Non-AJAX forms (a deprecated setting in WPForms Pro) reload to a confirmation page, in which case you push from the thank-you page instead. Most installs are AJAX.
dataLayer push pattern
Section titled “dataLayer push pattern”Add this to your theme’s footer, or via a GTM Custom HTML tag firing on All Pages with priority 10:
Push only inside wpformsSubmitSuccess — never wpformsBeforeFormSubmit.
(function () { if (!window.jQuery) return;
window.jQuery(document).on('wpformsSubmitSuccess', function (event, $form, formData) { var formId = $form.data('formid') || $form.attr('id'); var formTitle = $form.find('.wpforms-form-name').text().trim() || $form.find('.wpforms-title').text().trim() || 'wpforms_' + formId;
window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'form_submission', form_vendor: 'wpforms', form_id: String(formId), form_title: formTitle, wpforms_submission_id: (formData && formData.id) || undefined }); });})();GTM setup
Section titled “GTM setup”-
Create a Custom Event trigger
- Trigger type: Custom Event
- Event name:
form_submission - This fires: Some Custom Events →
Eventequalsform_submissionANDDLV - form_vendorequalswpforms
-
Create Data Layer Variables
DLV - form_vendor→ Data Layer Variable name:form_vendorDLV - form_id→ Data Layer Variable name:form_idDLV - form_title→ Data Layer Variable name:form_titleDLV - wpforms_submission_id→ Data Layer Variable name:wpforms_submission_id
-
Create a GA4 Event Tag
- Tag type: Google Analytics: GA4 Event
- Event name:
generate_lead - Parameters:
form_vendor→{{DLV - form_vendor}}form_id→{{DLV - form_id}}form_title→{{DLV - form_title}}submission_id→{{DLV - wpforms_submission_id}}
- Trigger: the Custom Event trigger above
-
Test in Preview mode
Submit a WPForms form successfully. The
form_submissionevent should appear in the Summary pane withform_vendor: wpforms, your form ID, and the form title.
GA4 - generate_lead (WPForms)
- Type
- Google Analytics: GA4 Event
- Trigger
- Custom Event - form_submission (wpforms)
- Variables
-
DLV - form_vendorDLV - form_idDLV - form_titleDLV - wpforms_submission_id
Handling multiple forms on one page
Section titled “Handling multiple forms on one page”If the page has more than one WPForms form, wpformsSubmitSuccess fires with the specific $form reference, so form_id disambiguates automatically. You do not need separate listeners per form.
If you want different GA4 event names per form (for example generate_lead for the contact form and newsletter_signup for the newsletter form), add a Lookup Table variable:
Input ({{DLV - form_id}}) | Output |
|---|---|
42 | generate_lead |
87 | newsletter_signup |
| Default | form_submission |
Wire the Lookup Table output into the GA4 tag’s Event Name field.
Non-AJAX forms (page-reload confirmations)
Section titled “Non-AJAX forms (page-reload confirmations)”If the form setting Disable AJAX form submission is enabled, WPForms reloads the page to a confirmation URL. The jQuery event never fires on that page. Two options:
- Thank-you page push. Add an inline script before the GTM snippet on the confirmation page with the same
form_submissionevent payload. - Referrer-based trigger. Create a Page View trigger:
Page URLcontainswpforms_form_idANDReferrercontains your form page path. Less precise, avoid if option 1 is available.
Test it
Section titled “Test it”- Open GTM in Preview mode and navigate to a page with a WPForms form.
- Fill out and submit the form successfully.
- In the Summary pane, find the
form_submissionevent. Click it and verify the Variables tab showsform_vendor: wpformsand the correctform_id. - Verify Tags Fired lists the GA4 tag.
- In GA4 → Admin → DebugView, confirm the
generate_leadevent appears within 15 seconds with all parameters. - Test the failure path: trigger a validation error (leave a required field empty). Confirm no
form_submissionevent fires.
Common gotchas
Section titled “Common gotchas”Elementor-embedded WPForms init late. When a WPForms block is inside an Elementor widget, the form’s jQuery event binding may happen after DOMContentLoaded. Put your listener in a setTimeout(..., 500) wrapper or delegate from document (as shown above — jQuery(document).on(...) already delegates).
Modal lightbox re-initialises. If you use WPForms’ popup/lightbox add-on, each open binds new handlers. The delegated listener on document survives this, but if you bind directly to the form element you will see duplicate fires.
Multiple jQuery instances. Some themes load a second jQuery. WPForms uses whichever is registered under window.jQuery at init time. If your listener uses a different instance, events will not reach it. Always listen via window.jQuery, not a bundled copy.
Conversational Forms add-on. WPForms’ Conversational Forms layout fires wpformsSubmitSuccess at the end, but the form DOM is rebuilt as the user steps through. Use the delegated listener on document — not on .wpforms-form.