Eventbrite & Google Analytics: Setting Up Cross Domain Tracking



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 recitified, 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.

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:

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:

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.

Dan Wilkerson is a former LunaMetrician and contributor to our blog.

  • johnDorian

    Hey, this blog post is extremely helpful. I managed to get it up and running in no time. The only thing I would suggest is changing the hostname matching part, as sometimes the event name is part of the host name (e.g. mybigevent.eventbrite.com). I managed to get it working using this (my event was in the uk): if(url.hostname.indexOf(‘eventbrite.co.uk’) !== -1)

    Thanks again for the great info.

    • Dan Wilkerson

      Updated today to check for ‘eventbrite.’ in the hostname – thank you John!


  • Andy Rysdam

    Thanks Dan, very helpful blog post.

    Update on the embedded iframe situation you mentioned:

    We make heavy use of Eventbrite embedded iframes, so passing the clientId through was critical. Eventbrite has updated the script inside the iframe (eb.analytics.js) to recognize the clientId being passed in and everything is coming through for us now. It works the same way, just append _eboga=clientId to the iframe src and you should be good to go.

    • Dan Wilkerson

      Updated today to do the same – glad to hear that they’ve made this change. Thanks Andy!


  • Edward Upton

    Thanks Dan – good work.

    One small inconsistency. If you go to the trouble of dealing with situations where sites have renamed the tracker object (does this ever happen?) then line 32 is incorrectly referring to ‘ga’ object directly.

    • Dan Wilkerson

      Great catch; someone got sloppy 😉 . I’ll put in a fix.


  • Vinnie Dauer

    Thanks for this. I’m a GA newbie, so forgive the question: do I need a goal associated with this script, or will this automatically register an event?

    • Dan Wilkerson

      Hi Vinnie,

      I think there’s some confusion here on what this is for; all this script does is transfer over client IDs, it doesn’t fire any Google Analytics Events or anything like that. Hope this helps.


      • Vinnie Dauer

        Thanks, Dan. After further research, I have a better understanding of how cross-domain tracking works, and this is exactly the missing piece I needed. Thanks very much.

        • Dan Wilkerson

          Glad to hear it!

  • David

    I’m using the Eventbrite Ticket Form widget. When I view the source I do see that the iframe src has been appended to have the _eboga parameter. However, when I select a ticket, and click on the register button the destination eventbrite URL doesn’t have the _eboga parameter appended to the URL. Is this normal? When I create a regular text link to eventbrite.com it does have the _eboga parameter.

    • Dan Wilkerson

      Hi David,

      Check your cookies and your data to verify, but everything sounds like it is working as intended – once the iframe loads and captures that parameter, you’re all set, you don’t need the parameter to appear in the destination URL.


  • chrisyakimov

    Thank you SO much for this resource, and for providing the importable JSON container. I have got it up and running, but ran into a snag. The part of the script that checks iframe SRC doesn’t account for iframes that have NO src attribute. What happens (as best as I can understand it is):

    1. Create an array of iframes.
    2. Loop through and translate “src” into an anchor element to check the URL and add eboga if necessary
    3. Append new source back to iframe (or old src, if was not eboga-ed).

    If the iframe has *no* src, it seems to be given one equal to the URL of the current page (causing the page to load itself into the iframe). Because our GTM is currently still located in the , it is getting loaded a second time per pageview and firing twice.

    My current fix has been to comment out the call to updateIFrames() and it seems to be working, but I thought I’d share in case this is happening with anyone else.

    WHY no src on the iframe? I’m working in large and complex installation of Adobe Experience Manager. One of AEM’s components is “social”, which is a ShareThis implementation. ShareThis seems to need an iFrame instantiated in the of the document, with no SRC attribute. So that’s the iframe that the CustomHTML tag picks up and gives a src. The other iframe that seems to get disgruntled is the Twitter Box (which also has no src attribute).

    Possible fix might be to omit iframes with no src attribute from the “iframes” array variable… ?

    Again thanks for this, regardless!

    • Dan Wilkerson

      Hey Chris,

      Thanks for sharing this; I’m having trouble reproducing this locally. I’m adding the following to a page and then running the snippet:

      From what I can see, the code shouldn’t be acting on those iframes that way, as this line:

      should short-circuit everything (it’s definitely not the best place to be checking this, either way).

      Can you share the setup you’re looking at so I can test a little more?


      • Dan Wilkerson

        Just an update for those reading this thread – Chris was correct, the bug was still occurring because of the assignment at the end of the loop (if a.href !== iframe.src). I’ve fixed the code to prevent that from happening and updated the container file.

  • Daniel Proczko

    This works very well! Thanks!

    Also, realized through my troubleshooting that adblockers will thwart analytics collection. That’s a shame.

  • John Peterson

    Can we do the same with Gostats too?

  • CJ

    I think you just changed my life…

  • Very helpful, huge thanks Dan!

  • Alen

    I got a small workaround for iframe part with GTM custom variable and hitCallback.


  • Chris Garcia


  • Antony McGregor Dey

    Amazing work. Love you guys so much! You should have a ‘donate’ button for your posts, I’d be more than happy to kick a few dollars your way! 😍

  • Chris Garcia

    I’m using the Ticket Listing widget and it doesn’t work. URLs get decorated with the eboga parameter, but the one triggered by the Register button doesn’t seem to be affected because when I use Google Tag Assistant it says a new session is started when I get to Eventbrite.

    • Dan Wilkerson

      Yeah, eventbrite’s implementation is wonky and Tag Assistant can’t grok it. Look for the hit in the network tab to your UA number – pipe that in the filter, then check the cid= parameter is correct. If not, let me know.

      • Chris Garcia

        I found a cid parameter sent to google-analytics.com but it didn’t match the GA client ID, if that’s what you mean. Could you please explain in a little more detail how to check this? I’m somewhat new to this. I went to chrome://net-internals/#events, hit Register on the widget, then searched for eventbrite.com/register cid. None of the cid parameters I found matched. I don’t even really know what I’m doing, but I have to get this done for my boss, so…

  • Jocelyn

    Does this solution scale for sites that have many different events? I’ve implemented this solution and am seeing discrepancies in ecommerce data between platforms.

  • Garry Viner

    Hi there

    First of all, awesome work. You guys always write such helpful code. However I can’t get it to work in this instance. Not sure if you still look at questions on this but i’ll put it up here just in case.

    So i’ve added the code to GTM and can confirm that the _eboga parameter is being passed via the iframe src. You can see in the two screenshots that the value matches the id from the source page. But despite that, the _ga parameter on eventbrite is different, and so all traffic is coming through as direct.

    Any ideas?


    https://uploads.disquscdn.com/images/7465ab228aceb549ec960e16e5de74e7228963befa18be1f9a8c689d2ab4c82e.png https://uploads.disquscdn.com/images/5aaa2e7283e660ddb3b1739a9a9297b5a28e8f7561f2700a7b18c81cc0d9ba0f.png

Contact Us.

Follow Us




We'll get back to you
in ONE business day.
Our Locations
THE FOUNDRY [map] LunaMetrics

24 S. 18th Street
Suite 100

Pittsburgh, PA 15203


4115 N. Ravenswood
Suite 101
Chicago, IL 60613


2100 Manchester Rd.
Building C, Suite 1750
Wheaton, IL 60187