Eventbrite and Google Analytics: Setting Up Cross Domain Tracking

October 20, 2016

Eventbrite recent rolled out the ability to do true cross domain tracking with Google Analytics. What is cross-domain tracking? Read more about it here. All caught up? Okay, let’s get started.

In order to do cross-domain tracking with your Eventbrite events, you’ll need to decorate any links that point at Eventbrite with a special, dynamic query parameter. The parameter key is _eboga. Eventbrite requires that the value of the parameter be the users client ID (which is a little different than the Linker setup you might be used to).

First, the bad news

Although this attempt at a cross-domain integration is better than previous iterations, the code still has a few opportunities to grow. The current implementation lacks:

  • Checks to ensure that the client ID is inherited by the correct user

    Google’s Linker plugin checks a hash of the User Agent and a timestamp to prevent “collisions”, like when a client ID is in the URL and the user shares it with another user. Eventbrite’s custom system doesn’t, which means annoying things can happen like the page being indexed with some random users CID. Given that most clicks will be sent to expiring pages, this seems like a marginal risk, but it’s still a disappointment.

  • A mechanism to prevent collisions with other Eventbrite users

    Each vendor has their _eboga value stored in a cookie named _eboga on the Eventbrite site. This means if a user travels between multiple Eventbrite sites, they could wind up changing their Client ID several times, meaning they’ll be tracked as several different users. It would have been nice to see the code make use of namespaced `localStorage` or cookies (although both admittedly have challenges, and the structure of Eventbrite’s site doesn’t help).

  • UPDATE: This has been rectified, see UPDATE below.The ability to utilize the integration with their embedded event iframes

    The code doesn’t appear to show up in the code served in Eventbrite’s embedded iframes, at least in my own tests. To test this, I found clients who were using the integration and manually created an iframe-like URL (e.g. https://www.eventbrite.com/tickets-external?eid=XXXXXXXXXXX&ref=etckt). When I inspected the source of the page, I wasn’t able to locate the code used to extract the _eboga parameter and set the cookie.

     

TL;DR: If you’re making heavy use of the Eventbrite iframes on your site, or are very concerned about your data hygiene, you might want to skip this one out. Sorry to be the bearer of bad news.

The Code

If you’re using Google Tag Manager, we’ve got a handy container file for you to import & instructions. Feel free to read the below, regardless.

Extracting the Client ID

To get to the client ID, you’ve got two options:

  • Ask GA politely for it
  • Pull it out of the _ga cookie

Option #1: Asking Politely

This little snippet will grab the Client ID by using the tracker.get() method.

// Returns a Google Analytics Client ID from the first
// tracker it finds or from a tracker with a given Property ID.
function getClientId(targetTrackingId) {

  var trackers = window[window.GoogleAnalyticsObject].getAll();
  var len = trackers.length;
  var tracker,
    i;

  if (!targetTrackingId) return trackers[0].get('clientId');

  for (i = 0; i < len; i++) {

    tracker = trackers[i];

    if (tracker.get('trackingId') === targetTrackingId) {

      return tracker.get('clientId');

    }

  }

}

You can pass the function a UA number, e.g. 'UA-123456-6', and it will extract the client ID associated with that Property. This is only important if you're using the cookieName setting - otherwise, you can just call the function without passing anything.

Option #2: Pulling Teeth

If you can't/don't want to interact with the ga API, you can also extract a users Client ID from their _ga cookie. Here's a snippet to get that done for you:

// Returns the Google Analytics Client ID for the user
function getClientId() {

  var _gaCookie = document.cookie.match(/(^|[;,]\s?)_ga=([^;,]*)/);
  if(_gaCookie) return _gaCookie[2].match(/\d+\.\d+$/)[0];
  
}

Decorating the links & iframes

Once we've gotten our client ID, we then need to find and decorate all links and iframes pointing at Eventbrite with it (and our special parameter). Here's how to get that done:

// Adds the Eventbrite cross domain tracking parameter to any
// links pointing to www.eventbrite.com
function updateIframes() {

  var iframes = document.getElementsByTagName('iframe');
  var iframe,
      a,
      i;

  for (i = 0; i < iframes.length; i++) {

    iframe = iframes[i];

    if (iframe.src && iframe.src.indexOf('eventbrite') > -1) {

      a = document.createElement('a');
      a.href = iframe.src;

      checkAndAddEboga(a);

      if (iframe.src !== a.href) {

        iframe.src = a.href;

      }

    }

  }

}

function updateUrls() {

  var urls = document.querySelectorAll('a');
  var a,
      i;

  for (i = 0; i < urls.length; i++) {

    a = urls[i];
    checkAndAddEboga(a);

  }

}

function checkAndAddEboga(a) {

  var clientId = getClientId();
  var parameter = '_eboga=' + clientId;

  // If we're in debug mode and can't find a client 
  if (!clientId) {

    if (debugMode) {

      window.console && window.console.error('GTM Eventbrite Cross Domain: Unable to detect Client ID. Verify you are using Universal Analytics and the correct targetTrackingId is set, if any.');

    }

    return;

  }

  if (a.hostname.indexOf('eventbrite.') > -1 && a.search.indexOf('_eboga') === -1) {

    a.search = a.search ? a.search + '&' + parameter : '?' + parameter;

  }

}

Firing The Code

Now that we've got all the pieces in place, we need to determine when to fire our code. We need to make sure the `a` elements we're targeting are in place before we try and bind to them. The simplest way to do that is to fire our code on the `DOMContentLoaded` event (or `window.load` for older browsers). We also need to make sure that Google Analytics has loaded before the code fires, and that a client ID is available. To do this, we'll take advantage of the Universal Analytics command queue. Let's put it all together:

And there we have it! The script will load after both GA and the DOM are ready to go, ensuring we can tack on our client ID and _eboga parameter to all of the Eventbrite links on our page.

Have another approach? Spot a bug in my script? Sound off in the comments below.

UPDATE: Eventbrite has updated their iframes to accept the _eboga parameter. The above code and container file have been updated to append _eboga to iframe src attributes, too. Big thanks to John Dorian, Andy Rysdam, and Edward Upton for catching bugs, updating us on new features, and generally being awesome.