How to track internal campaigns using Google Analytics

Let’s start with the basics …

What is an internal campaign

An internal campaign, from a business perspective, is any element on a site(s) which links to your content and its purpose is to speed up the purchase decision, highlight a product or category, give incentive in any part of the purchase funnel and more. A simple example would be a click on banner which is placed on our home page – – which links to a product page (also on our site(s)) –

Some examples / methods of internal campaigns:

  1. urgent – offer ends in 2 hours
  2. limited – only 5 left
  3. popular – top 5 products
  4. deal – buy 1 get one for free

The truth of the matter is internal campaigns are often used to push products with these common attributes – hard to sell, large stock, high margin and let’s not forget fill the gaps in design:)

A simple example ( – part of the homepage):


Why track internal campaigns

The obvious reason is – why not. Internal promotions often take a lot of screen real estate and this fact should not be taken lightly. Aside from that you need to invest time and money for campaign production – copy, images, … so in short you owe it to yourself to prove / test its (in)efficiency. From a marketeers perspective there are some quite useful goodies gained from tracking internal campaigns – what works and what does not:

  1. copy
  2. incentive type
  3. position
  4. colour
  5. season
  6. category
  7. price
  8. and so much more


Before we get to how to track these campaigns …

How NOT to track internal campaigns

Do not use UTM tagging to track internal campaigns. Never. Never ever.

There may be some cases where you feel tempted to use UTM taging such as a multisite environment where you own multiple properties – still, don’t.

A common error in web analytics is using features like UTM tagging for the wrong reasons resulting in bad data. If we opt to tag internal campaigns with UTM we actively affect Google Analytics traffic source attribution. Let’s see what happens if we do:

  1. A user clicks on our Google AdWords ad – Google Analytics will report on this session as coming from google / cpc
  2. Inside that session the same user clicks on our banner which has UTM tags (utm_source, utm_medium, …)
  3. This results in traffic being attributed to our banner and not Google Adwords (and will create a new session)
  4. If a user activates a type of conversion on our site standard report will attribute it to Internal campaign while the MCF part of reports will attribute Google AdWords as an assisting channel in the conversion path – a mess not easy to decipher

How TO track internal campaigns

You will probably encounter a few main methods of how to properly track this sales tool. The most popular ones are:

  1. Site search – this was nicely explained by none other than Justin Cutroni
  2. Enhanced ecommerce – this is probably the first Google Analytics feature which has a specific area designated for internal campaign (promotion) tracking this is also by far the most difficult method of tracking (as tracking internal promotions makes real sense only if you track all other EE activities on the site)
  3. Event tracking – a very flexible method of tracking almost anything on your site (I will describe some of the basic ways to do event tracking with Google Tag Manager)
  4. Custom dimensions – in addition to event tracking we can add a new layer of data to existing hits (events / pageviews) in order to better describe the actual internal promotion

As the methods 1 and 2 are described thoroughly let’s focus on event tracking and custom dimensions and we will do a hybrid of these 2.

Tracking Internal campaigns with Google Analytics Event tracking

First of all we need to decide the naming policy for our event / campaign tracking efforts. In short what will be the category, action and label values used throughout the site – note that if the naming is not consistent, time and site wise, it will be really hard to do meaningful reports. So lets revert to the basic questions – what would we like to know:

  1. Does the internal campaign help sell stuff? – we have that covered – create a segment using category / action / label and track conversion behaviour
  2. Which internal promotions are most likely to sell (and why – tricky but at least try)? – we need info here on:
    1. promotion placement (page, position)
    2. size, color, copy (think in terms of utm_content)
    3. incentive type (price, urgency, loyalty, package, any additional added value)
    4. some other attribute

As you can imagine it is not a small feat to push all these values into 3 event hit default dimensions so there is always the option to add a custom dimensions in the mix to help out (if you can spare the Custom dimensions slots!!! – note there is a limit of 20 CDs per property). An initial suggestion would be:

  • Event category = ‘internal_campaign’ (if we have a rollup property we can add the site the click happened on so it would be ‘internal_campaign_sitename’ (think utm_source))
  • Event action = ‘shoes_men_spring_2015’ (think utm_campaign)
  • Event label = ‘250*250|red|buy_now|a|2’ Ad / Banner / Campaign content (think utm_content) – size of the banner, color, CTA, variation, position (if a slider present)
  • CD1 = incentive type or some other attribute = hit scope dimension

Now that we solved what we wanted to report on let’s see how can we retrieve these values. this part will emphasize on the fact that GTM is not a one click install system and it often requires additional development work on site as the site itself is rarely built to provide info which marketeers need in an easy to consume / report form.

Trigger the Google Analytics Tag Event tag

So lets first solve the triggering part where we want to send a GA event only when someone clicks on an Internal campaign ad / link. For this case we need a way to identify the click on the internal campaign.

Here are a few basic options to solve the trigger part:

  1. use the DOM event – onmousedown, onclick – <a href=”#” onclick=”dataLayer.push({‘event’ : ‘trackEvent’}];”> – use the onclick event to push a custom event via dataLayer
  2. use GTM click / linkClick triggers which track clicks on DOM elements / links – these are GTM built in events – <a href=”#” id=”intcmp” data-gtm-data=”someImportantInfo”> – use of GTMs click / linkClick trigger in combination with auto event variables (element attributes (Click ID or element attribute auto event variable – data-gtm-data))

Trigger case 1 (DOM event)


Trigger case 2 (GTM click / linkClick)


Enable when part is optional and takes care of performance issues so you do not listen the clicks on lets say all pages but only ones that contain internal promotions. When using Auto event variables make sure the ones you will use are activated in the Variables section of GTM interface:



How to set and read the data payload for GA event tag

And now we come to the tricky part. It is not hard to send basic info to Google Analytics yet it is quite hard to come by ‘ready to consume info’ from the site. Let’s look at an example – this is not a good example of how to do it properly but an example of what you can usually expect:

<div class="slide" style="width: 980px; float: left;">
<a href="/running.html">
<img src="" alt="">

As you can see here there is almost no notion of the stuff we would really like to track – position, size, CTA, copy, color and similar. In addition to that there are no clear identifiers of the element being the internal campaign link aside from the class=”slide”.  We have two main options here:

  1. Scrape whatever we can from DOM – Click URL, image name (this gives us a really limited data set in most cases)
  2. Add some code which would better describe what the user has actually clicked (better yet we usually need developer support – preferred version)

Option 1
A very simplified way of sending the info to GTM and subsequently to Google Analytics would be to use a dataLayer custom event:

<a href="#" class="someclass" id="internalcamp" onmousedown="dataLayer.push({'event' : 'trackEvent','eventCategory': 'internal_campaign','eventAction': 'shoes_men_spring_2015','eventLabel': '250*250|red|buy_now|a|2','customDimension1':'price'});">

Option 2
An option where you have lots and lots of Custom dimensions slots available:

<a href="#" class="someclass" id="internalcamp" onmousedown="dataLayer.push({'event' : 'trackEvent','eventCategory': 'internal_campaign','eventAction':'shoes_men_spring_2015','customDimension1':'250*250','customDimension2':'red','customDimension3':'buy_now','customDimension4':'a','customDimension5':'2','customDimension6':'price'});">

Option 3
Yet another option for streamlining event information to GTM is to use HTML data attributes – I personally find this approach very useful but it is usually applicable with long term relationship clients where analytics needs are both a part of the development and marketing process (additional benefit – whatever changes in terms of class or id of the element the data-gtm- logic usually stays intact). So for example:

<a href="#" class="someclass" id="internalcamp" data-gtm-event="internal_campaign" data-gtm-action="shoes_men_spring_2015" data-gtm-label="250*250|red|buy_now|a|2">

The only thing you need to do now is to ‘catch’ the data on link click in GTM and here is how you do it:

Values needed to identify the right event and to push the final payload to event.

3 variables are needed all type of Auto Event variables where you choose Element Attribute and create all 3 data-gtm- variations.


How we trigger the Google Analytics event from GTM.


Where we send the entire payload to Google Analytics with an event.


Alternative pageview tracking with custom dimensions

Let’s assume you cannot rely on data attributes and events and your only option is adding parameters to links – it is doable and here is how to do it.

Your internal campaign directs to a page on your site: (old URL) which you should change to …*250

Follow up steps …

Read Url fragment – URL type variable where we read everything after #.


Custom dimension value extract from URL fragment (you can extract the values to one dimensions or parse the values to separate dimensions) – note that we split the entire string by ‘&’ and use the index 0 which is the 1st item and will in our case return the string ‘intcmp’:

function() {
var myTempString = {{read URL fragment}};
if(myTempString && myTempString.indexOf('intcmp')>-1){
return myTempString.split('&')[0];

An All pages for the pageview tag will suffice. If the fragment values do not exist nothing will be passed as custom dimensions values – will not be processed.

Use a Google Analytics Universal template tag with the following settings:


And this is it – happy tracking!

Author bio

Zorin Radovančević

October 21, 2015 Google Analytics, Google Tag Manager

Senior Web Analytics implementation and planning specialist - all things related to Google Analytics, Google Tag Manager and Yandex Metrica.


Leave a Reply

Your email address will not be published. Required fields are marked *