Skip to content

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.

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.

Add this to your theme’s footer, or via a GTM Custom HTML tag firing on All Pages with priority 10:

dataLayer.push() form_submission

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
});
});
})();
  1. Create a Custom Event trigger

    • Trigger type: Custom Event
    • Event name: form_submission
    • This fires: Some Custom EventsEvent equals form_submission AND DLV - form_vendor equals wpforms
  2. Create Data Layer Variables

    • DLV - form_vendor → Data Layer Variable name: form_vendor
    • DLV - form_id → Data Layer Variable name: form_id
    • DLV - form_title → Data Layer Variable name: form_title
    • DLV - wpforms_submission_id → Data Layer Variable name: wpforms_submission_id
  3. 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
  4. Test in Preview mode

    Submit a WPForms form successfully. The form_submission event should appear in the Summary pane with form_vendor: wpforms, your form ID, and the form title.

Tag Configuration

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

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
42generate_lead
87newsletter_signup
Defaultform_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:

  1. Thank-you page push. Add an inline script before the GTM snippet on the confirmation page with the same form_submission event payload.
  2. Referrer-based trigger. Create a Page View trigger: Page URL contains wpforms_form_id AND Referrer contains your form page path. Less precise, avoid if option 1 is available.
  1. Open GTM in Preview mode and navigate to a page with a WPForms form.
  2. Fill out and submit the form successfully.
  3. In the Summary pane, find the form_submission event. Click it and verify the Variables tab shows form_vendor: wpforms and the correct form_id.
  4. Verify Tags Fired lists the GA4 tag.
  5. In GA4 → Admin → DebugView, confirm the generate_lead event appears within 15 seconds with all parameters.
  6. Test the failure path: trigger a validation error (leave a required field empty). Confirm no form_submission event fires.

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.