Variables

To make sure that your data is as accessible as possible, we create variables and tags according to a particular framework. If you/your site's developers are deploying tags, we ask that you work within this framework.

Constant variables for metadata

You will often want to associate the same label with events across your website. For this reason, we recommend setting up multiple "Constant" type variables whose values are set to strings that describe events. We also recommend naming variables using camel case, as is typical for Javascript variables, to distinguish them from other assets you create in Tag Manager. Here are several examples:

Variable name

String to set it to

linkClick

Link click

buttonAsLinkClick

Button as link click

buttonTypeSubmitClick

Submit button click

buttonTypeButtonClick

Button as button click

baseApp

Variable type: Constant

Stores a value that identifies the website, and that you include in your event tags. For example, the baseApp value for DTAConnect is dtaconnect.

You should set baseApp to be a constant, and it's a good idea to use the "Format value" option to set it "Lowercase."

Task Path

Variable type: Custom Javascript

Identifies where in the app an event took place. "Where," here, is somewhat up to you. You'll want to identify the different "tasks" a user can complete on your website, along with the various steps they can take to completing the task.

Every Task Path begins this way:

function() { 
    var baseApp = {{baseApp}};
    var section = (window.location.pathname).toLowerCase(); 
    return baseApp + ' ' + section;
    }

Note that GTM Custom Javascript tags do not support Ecmascript 6 features (such as let or const). {{baseApp}}refers to your container's baseApp variable (see above): GTM tags are able to reference other GTM variables.

The example above only does part of what Task Path should do: It identifies the app and the URL. The next step is to identify which task the user is trying to complete based on the URL of the current page, such as in this example, which the URL /app/add-to-cart indicates that the user is b which is part of a license purchase, you might extend this code above like so:

function() { 
    var baseApp = {{baseApp}};
    var section = (window.location.pathname).toLowerCase();
    if (section === '/app/add-to-cart') {
        section = baseApp + ' license purchase';
    }
    return section;
}

If there are many possible tasks on your website, you may wish to set up an object that matches paths and task names to serve as a lookup table:

function() { 
    var baseApp = {{baseApp}}; // for example, uionline
    var section = (window.location.pathname).toLowerCase();
	
	var tasks = {
     '/app/add-to-cart'': 'license purchase', 
     '/app/user-profile':'update profile', 
     '/app/locations':'find a location',
     '/app/register-for-course':'register for a course'
     // etc.
    }
	
    return baseApp + ' ' + tasks[section] //e.g. massfishhunt license purchase
}

You can also do this with a series of ifstatements.

What is important is that ultimately, we're able to label data by site name and by area of the site in which an event was triggered.

Hit timestamp

Type: Custom Javascript

The date and time, down to the millisecond, a hit (pageview, click) occurred. Google Analytics also provides its own time dimensions, but we use this for convenience while we are using the free version, where we have limited access to data.

function() {
    // Get local time as ISO string with offset at the end
    var now = new Date();
    var tzo = -now.getTimezoneOffset();
    var dif = tzo >= 0 ? '+' : '-';
    var pad = function(num) {
        var norm = Math.abs(Math.floor(num));
        return (norm < 10 ? '0' : '') + norm;
    };
  return now.getFullYear() 
    + '-' + pad(now.getMonth()+1)
    + '-' + pad(now.getDate())
    + 'T' + pad(now.getHours())
    + ':' + pad(now.getMinutes()) 
    + ':' + pad(now.getSeconds())
    + '.' + pad(now.getMilliseconds())
    + dif + pad(tzo / 60) 
    + ':' + pad(tzo % 60);
}

Sequence timestamp

Provides a more human-readable timestamp. The example below is built on Mass.gov's, whose format is YYYY MM DD HH:MM:SS. You may re-order the time dimensions if you like for your use case.

function() {
 try {
  var timestamp = new Date();
  var time = timestamp.toString().split(' ');
  return time[3]+ " " +time[1]+ " " +time[2]+ " "+time[4];
 } catch(e) {
  return "unknown";
 }
}

Session ID

Type: Custom Javascript

We use Session ID in concert with Hit Timestamp to map all data points in a session in order. It should look like this:

function() {
  return new Date().getTime() + '.' + Math.random().toString(36).substring(5);
}

For context, our session identifier is built on top of Google's session identifier. Here is how they work together: We ask Google to treat Session ID as a "session-scoped" dimension. This means that at the end of each session, the last hit's session ID (per above: generated by combining a timestamp and a random number) is associated with every hit that Google recorded for the session.

This can be confusing if you are following along in preview, as you will see a new session ID generated on each new hit -- each new pageview, click, etc. The way to interpret this, each new Session ID overwrites the previous one. The only one recorded in Google Analytics for each hit in the session is the last one generated by Google Tag Manager. [Mass Digital's note: We know this explanation is confusing, and we're working on it. Please get in touch if you want to talk through this!]

Client ID

Type: Custom Javascript

Client ID is an identifier Google assigns to each user (or, at least, what it thinks amounts to a user based on device, IP address, and other characteristics).

function() {
  // Change customDimensionIndex if you want to change the dimension Client ID gets sent to
  var customDimensionIndex = 3;
  return function(model) {
    model.set('dimension' + customDimensionIndex, model.get('clientId'));
  }
}

Type: Custom Javascript

GA Property X-Domain

Type: Constant

The Google Analytics property to which Google Tag Manager will send data. This will be associated with every tag you make.

Type: Custom Javascript

function(){
  return function(){
      if (document.location.search.match(/_ga=([^&]*)/)) {
          var new_url;
          var rebuilt_querystring;
          // A small function to check if an object is empty
          var isEmptyObject = function(obj) {
              var name;
              for (name in obj) {
                  return false;
              }
              return true;
          }
          // Let's build an object with a key-value pairs from the current URL
          var qsobject = document.location.search.replace(/(^\?)/, '').split("&").map(function(n) {
              return n = n.split("="),
              this[n[0]] = n[1],
              this
          }
          .bind({}))[0];
          // Remove the _ga parameter
          delete qsobject['_ga'];
          // Let's rebuild the querysting from the previous object with the _ga parameter removed
          var rebuilt_querystring = Object.keys(qsobject).map(function(k) {
              if (!qsobject[k]) {
                  return encodeURIComponent(k);
              } else {
                  return encodeURIComponent(k) + '=' + (encodeURIComponent(qsobject[k] || ""));
              }
          }).join('&');
          // We want to if the current querystring was null
          if (isEmptyObject(qsobject)) {
              new_url = location.pathname + location.hash;
          } else {
              new_url = location.pathname + '?' + rebuilt_querystring + location.hash;
          }
          // Use replaceState to update how the URL appears in the browser
          window.history.replaceState({}, document.title, new_url);
      }
    }
}

For context: We link analytics across domains by passing a cookie through URLs. To make sure that cookie doesn't appear in a URL and confuse site visitors, we use the above code to remove it. We also remove it from clicked URLs that we track that become part of our data (see below).

Type: Custom Javascript

Note: You need to enable the built-in variable Click URL to deploy this variable.

Use this to remove the Google Analytics cookie from the ends of clicked URLs.

function(){
  var new_url = {{Click URL}} // Click URL is a built in GA variable
  if ({{Click URL}}.match(/_ga=([^&]*)/)) {
    var querystring = {{Click URL}}.split("?")[1];
    var rebuilt_querystring;
    
    // A small function to check if an object is empty
    var isEmptyObject = function(obj) {
      var name;
      for (name in obj) {
        return false;
      }
      return true;
    }
    
    // Let's build an object with a key-value pairs from the current URL
    var qsobject = querystring.replace(/(^\?)/, '').split("&").map(function(n) {
      return n = n.split("="),
        this[n[0]] = n[1],
        this
    }.bind({}))[0];

    // Remove the _ga parameter
    delete qsobject['_ga'];

    // Rebuild the querysting from the previous object with the _ga parameter removed
    var rebuilt_querystring = Object.keys(qsobject).map(function(k) {
      if (!qsobject[k]) {
        return encodeURIComponent(k);
      } else {
        return encodeURIComponent(k) + '=' + (encodeURIComponent(qsobject[k] || ""));
      }
    }).join('&');

    // We want to if the current querystring was null
    if (isEmptyObject(qsobject)) {
      new_url = {{Click URL}}.split("?")[0];
    } else {
      new_url = {{Click URL}}.split("?")[0] + '?' + rebuilt_querystring;
    }
  }
  return new_url;
}

For context: We link analytics across domains by passing a cookie through URLs. To make sure that URLs that become part of our datasets don't include that the cookie -- a long, ugly text string -- we use the above code to remove it.

Constants for all common actions

You should create variables that hold the values you want to assign to all actions you will need to tag. This will make it much easier to change these later if you need to, and it will make the data itself much cleaner. Example values you should consider making variables for include:

  • Link click

  • Button as link click

  • Submit button click

  • Error message appears

Last updated