How to Track AJAX Form Submissions Using GTM and Google Analytics (GA4)

How to track AJAX form submissions with Google Analytics (GA4) and Google Tag Manager (GTM)

Published by Marty Paukstys, founder of D2CEBL. 20+ years of Google PPC & Analytics experience. Google Ads Search and Google Analytics certified.
 

AJAX-based form submissions present a common challenge when implementing accurate form tracking, as they do not trigger page reloads. This detailed guide explains a robust, scalable method for tracking AJAX form submissions using a custom JavaScript listener, Google Tag Manager, and Google Analytics (GA4).

Understanding AJAX Forms and Why They Are Difficult to Track

AJAX forms submit data asynchronously without refreshing the page, making them invisible to traditional page-based tracking methods. To track these submissions effectively, we need a JavaScript listener that detects the completion of any AJAX request and pushes data into GTM's dataLayer.

 

Creating the Custom JavaScript Listener (Original Code)

To track AJAX events, we will implement a custom JavaScript snippet that listens for AJAX requests and, upon completion, pushes a custom event into the GTM dataLayer.


Create a new "Custom HTML" tag in GTM:

In your GTM container, click Tags → New → Tag Configuration → Custom HTML.

Paste the following original JavaScript snippet into the HTML box:

<script>
(function() {
 function pushAjaxEvent(url, status, response) {
   window.dataLayer = window.dataLayer || [];
   window.dataLayer.push({
     event: 'customAjaxSuccess',
     ajaxData: {
       requestUrl: url,
       responseStatus: status,
       responseText: response
     }
   });
 }

 function interceptAjax() {
   if (window.XMLHttpRequest) {
     var origOpen = XMLHttpRequest.prototype.open;
     var origSend = XMLHttpRequest.prototype.send;

     XMLHttpRequest.prototype.open = function(method, url) {
       this._url = url;
       return origOpen.apply(this, arguments);
     };

     XMLHttpRequest.prototype.send = function() {
       var xhr = this;
       var origOnReadyStateChange = xhr.onreadystatechange;

       xhr.onreadystatechange = function() {
         if (xhr.readyState === 4 && xhr.status === 200) {
           pushAjaxEvent(xhr._url, xhr.status, xhr.responseText);
         }
         if (origOnReadyStateChange) {
           origOnReadyStateChange.apply(xhr, arguments);
         }
       };

       return origSend.apply(xhr, arguments);
     };
   }
 }

 // Start intercepting immediately
 interceptAjax();
})();
</script>

 

Create a GTM Trigger Based on the Custom Event

With the listener set up, we now create a GTM trigger to respond to this custom event.

  • In GTM, go to Triggers → New → Custom Event.
  • Event Name: exactly match the event name pushed by our JavaScript snippet:
    customAjaxSuccess
  • Trigger fires on: All Custom Events.
  • Name this trigger clearly:
    Trigger - AJAX Form Submit
  • Click Save.

Setting up GA4 Event Tag in GTM

Next, we configure the GA4 event tag to send these tracked AJAX submissions to Google Analytics.

  • Create a new tag: Tags → New → Tag Configuration → Google Analytics: GA4 Event.
  • Configuration Tag: Select your GA4 configuration tag.
  • Event Name: Choose a clear name, e.g., ajax_form_submission.
  • Under Event Parameters, you can add the following for more detailed tracking:
Parameter NameValue (from Data Layer)
ajax_url{{DLV - ajaxData.requestUrl}}
ajax_status{{DLV - ajaxData.responseStatus}}
ajax_response{{DLV - ajaxData.responseText}} (Optional, ensure no sensitive data)

 

Creating Data Layer Variables:

To access these parameters, first create Data Layer variables in GTM:


Go to Variables → New → Data Layer Variable.

  • For URL:
    Name: DLV - ajaxData.requestUrl
    Data Layer Variable Name: ajaxData.requestUrl
  • For Status:
    Name: DLV - ajaxData.responseStatus
    Data Layer Variable Name: ajaxData.responseStatus
  • For Response (optional):
    Name: DLV - ajaxData.responseText
    Data Layer Variable Name: ajaxData.responseText

Save each variable individually.

 

Finalizing the Tag:

  • Triggering: Choose the previously created trigger (Trigger - AJAX Form Submit).
  • Name the Tag clearly: GA4 - AJAX Form Submission.
  • Click Save.

Preview, Debug, and Test in GTM

Always test before publishing:

  • Click Preview in GTM.
  • Submit an AJAX form on your website.
  • In GTM Preview, confirm:
    The custom event (customAjaxSuccess) triggers.
    The GA4 event tag (GA4 - AJAX Form Submission) fires properly.

Verifying Data in Google Analytics (GA4)

After successful debugging:

  • Go to your GA4 property → Reports → Engagement → Events.
  • Check for your event (ajax_form_submission).
    (Events may take up to 24 hours to appear, or use GA4’s DebugView for real-time verification.)

Advantages of This Custom Listener Approach:

  • Universal solution: Independent of third-party libraries like jQuery.
  • Highly scalable: Automatically captures all AJAX requests without needing to alter individual forms.
  • Rich detail: Provides useful context such as request URLs and statuses.

Sources

Back to How To
  • Share
  • facebook
  • icon_linkedin
  • icon_x