Universal Analytics: Send Custom Dimension With Event

To make the most of your Google Analytics tracking, you can send Custom Dimensions with non-interaction events simply to add session- and user-scoped custom dimensions to your data.

(Last updated March 2014) This post is the final chapter of a trilogy. The ultimate refinement, if you will. It all started with my foray into the murky waters of context, when I tested how weather data could be used to provide extra information about site visits. When I wrote that post, I had two trepidations: 1) does sending the API call with every single page view affect site performance negatively, and 2) does forcing the page view call to wait for the API call to complete affect the quality of visit metrics.

I fixed (1) to my satisfaction in a later post on utilizing a custom cookie to make the API call just once per session. This meant that site performance improved, since the API call (which might take up to 500ms) is done just once per visit. Also, it has a positive effect on visit calculation, since the possibility of the page view call failing to complete due to problems in the chain of events is minimized.

However, I was still not happy with having any code executed before the page view, because page views are something you don’t want to compromise due to, for example, problems with a third-party API (such as the weather API).

So I did what I should have been doing all along.

Custom dimensions can be sent with events as well

Here’s a little background. I have a script which polls a weather API, with the visitor’s location as the parameter. The script collects the weather conditions of said location, and passes them to a visit-scope custom dimension, which is then sent to Google Analytics.

A custom dimension scoped for visits (or sessions) means that you just have to send it once per visit. All subsequent and previous hits (page views, events, transactions) of the visit are annotated with the dimension as well. Naturally, it’s a no-brainer to thus send the dimension just once per session, hence the need for a custom cookie (again, see this post).

Also, since you can send the same custom dimension with an event, why even use a page view? A non-interaction event does the same thing PLUS you can compare the number of weather events and visits from the same time period to see if there are discrepancies which indicate problems with the API call.

Another perk, if using GTM, is that you don’t need separate, confusing page view tags (one with the weather dimension, one without), but rather you can have your basic page view tag for tracking and an event tag for sending the weather data (which fires only when the API call is made).


Well, I need to refer back to the code from my previous two posts. Here’s what the NEW custom HTML tag should look like (remember, you need to load jQuery and the geoPlugin service for this to work).

  if (typeof({{Session alive}}) == "undefined") {
    var lat = geoplugin_latitude();
    var lon = geoplugin_longitude();
    var weather = "";
    var weatherAPI = "http://api.openweathermap.org/data/2.5/weather?lat="+lat+"&lon="+lon;

      type : "POST",
      dataType : "jsonp",
      url : weatherAPI + "&units=metric&callback=?",
      async : true,
      success : function(data) {
        weather = data.weather[0].main ;
        dataLayer.push({"weather": weather});
      },error : function(errorData) {
        console.log("Error while getting weather data :: "+errorData.status);
        dataLayer.push({"weather": "Undefined"});       
      },complete : function() {
        dataLayer.push({"event": "weatherDone"});
  var d = new Date();
  var expires = "expires="+d.toGMTString();
  document.cookie = "session=1; "+expires+"; path=/";    

Here’s the order of events:

  1. Check if a cookie named “session” exists

  2. If cookie doesn’t exist, use the visitor’s location to query the weather conditions at said location

  3. Save weather conditions in data layer variable “weather”

  4. Push event “weatherDone” to data layer whether or not the API call is successful

  5. Finally (regardless of whether the cookie existed or not) reset the “session” cookie to expire in 30 minutes

So no need for a second event “noWeather” for the weatherless page view. You can just have the normal page view sent with every page load, and then use “weatherDone” as the trigger rule for the event (remember to make it a non-interaction hit) which sends the “weather” variable as a custom dimension. Dead simple.

Finally, you’ll need to set up your event tag. Remember, you need to create the custom dimension in Google Analytics’ admin section (see here for a guide). Make note of the index number assigned to your new, session-level custom dimension.

Next, create a new event tag. Now, you can have whatever you want as your event fields, but make sure that Non-Interaction Hit is set to True. In this example, I send my custom weather type and temperature (they’re data layer variable macros), but as you can see, Non-Interaction Hit is True. This is important, because then this weather event won’t affect bounce rate calculation (because it doesn’t tell anything about engagement now, does it?).

And here’s what the custom dimension settings look like. You set them in the end of the tag, under More settings.


I think I’ve got the whole thing pinned down now. I have come up with a method to

  1. poll external APIs for contextual information

  2. send this information just once per visit

  3. use a non-interaction event to annotate the visit hits with this dimension

Next steps would be to make sure the API is reliable and fast. Also, maybe some sort of timeout trigger for the API call should be in place, with a “weather”: “Undefined” value sent if the API call doesn’t complete.