Sending data to Google Analytics with gtag.js

This guide describes how to use gtag.js to send data from your site to Google Analytics.

Send data with the event command

After installing the global snippet to your site use the event command to send data to Google Analytics. For example, to record a user login event in Google Analytics, use the following event command:

gtag('event', 'login');

The event command has the following syntax:

gtag('event', 'event_name', {
  // Event parameters
  'parameter_1': 'value_1',
  'parameter_2': 'value_2',
  // ...
});

For a detailed description of the event command, see Send events. For a detailed description of the fields of a Google Analytics Event, see Event fields.

Know when the event has been sent

In some cases you need to know when an event is done being sent to Google Analytics, so you can take action immediately afterward. This is common when you need to record a particular interaction that would take a user away from the current page. Many browsers stop executing JavaScript as soon as the page starts unloading, which means your gtag.js commands to send events may never run.

An example of this is when you want to send an event to Google Analytics to record that a user clicked on a form's submit button. In most cases, clicking the submit button will immediately start loading the next page, and any gtag('event', eventName, eventParameters) commands will not run.

The solution to this is to intercept the event to stop the page from unloading. You can then send your event to Google Analytics as usual, and once the event is done being sent, you can resubmit the form programmatically.

Implement event callback functions

To be notified when an event is done sending, implement an event callback function that gets called as soon as the event has been successfully sent.

The following example shows how to cancel a form's default submit action, send an event to Google Analytics, and then resubmit the form using the event callback function:

// Gets a reference to the form element, assuming
// it contains the ID attribute "signup-form".
var form = document.getElementById('signup-form');

// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {

  // Prevents the browser from submitting the form
  // and thus unloading the current page.
  event.preventDefault();

  // Sends the event to Google Analytics and
  // resubmits the form once the hit is done.
  gtag('event', 'signup_form_complete', { 'event_callback': {
    function() {
      form.submit();
    }
  });
});

Handle timeouts

The above example works nicely, but it has one serious problem. If (for whatever reason) the gtag.js library fails to load, the event callback function will never run and users will never be able to submit the form.

Whenever you put critical site functionality inside the event callback function, you should always use a timeout function to handle cases where the gtag.js library fails to load.

The next example updates the above code to use a timeout. If one second passes after the user clicks the submit button and the event callback function has not run, the form is resubmitted anyway.

// Gets a reference to the form element, assuming
// it contains the ID attribute "signup-form".
var form = document.getElementById('signup-form');

// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {

  // Prevents the browser from submitting the form
  // and thus unloading the current page.
  event.preventDefault();

  // Creates a timeout to call submitForm after one second.
  setTimeout(submitForm, 1000);

  // Keeps track of whether or not the form has been submitted.
  // This prevents the form from being submitted twice in cases
  // where the event callback function fires normally.
  var formSubmitted = false;

  function submitForm() {
    if (!formSubmitted) {
      formSubmitted = true;
      form.submit();
    }
  }

  // Sends the event to Google Analytics and
  // resubmits the form once the hit is done.
  gtag('event', 'signup_form_complete', { 'event_callback': {
    submitForm();
  }});
});

If you're using the above pattern in many places throughout your site, it's probably easier to create a utility function to handle timeouts.

The following utility function accepts a function as input and returns a new function. If the returned function is called before the timeout period (the default timeout is one second), it clears the timeout and calls the input function. If the returned function isn't called before the timeout period, the input function is called regardless.

function createFunctionWithTimeout(callback, opt_timeout) {
  var called = false;
  function fn() {
    if (!called) {
      called = true;
      callback();
    }
  }
  setTimeout(fn, opt_timeout || 1000);
  return fn;
}

Now you can wrap all event callback functions with a timeout to ensure your site works as expected even in cases where your events fail to send or the gtag.js library never loads.

// Gets a reference to the form element, assuming
// it contains the ID attribute "signup-form".
var form = document.getElementById('signup-form');

// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {

  // Prevents the browser from submitting the form
  // and thus unloading the current page.
  event.preventDefault();

  // Sends the event to Google Analytics and
  // resubmits the form once the hit is done.
  gtag('event', 'signup_form', { 'event_callback': {
    createFunctionWithTimeout(function() {
      form.submit();
    })
  }});
});

Specify different transport mechanisms

By default, gtag.js picks the HTTP method and transport mechanism with which to optimally send hits. The three options are 'image' (using an Image object), 'xhr' (using an XMLHttpRequest object), or 'beacon' using the new navigator.sendBeacon method.

The former two methods share the problem described in the previous section (where hits are often not sent if the page is being unloaded). The navigator.sendBeacon method, by contrast, is a new HTML feature created to solve this problem.

If your user's browser supports the navigator.sendBeacon, you can specify 'beacon' as the transport mechanism and not have to worry about setting a hit callback.

The following code sets the transport mechanism to 'beacon' in browsers that support it.

gtag('config', 'GA_TRACKING_ID', { 'transport_type': 'beacon'});

Next steps

Learn page tracking and additional event tracking.