Reporting on AdBlock usage with Google Analytics

Ad blocking is a really hot topic these days. Arguably there are two completely opposite stories to follow up on yet we are not dealing with that this time. This post explains how to report on ad blocking occurrence on the site and how it affects your ‘potential’ earnings as a publisher.

There are 3 main steps to this process:

  1. Detect ad blockers and send an event to Google Analytics (we will use it later on in a segment)
  2. Make the number of page ad slots available – ideally using dataLayer (if using GTM)
  3. Create the Custom metric(s) in Google Analytics interface and create the custom reports / dashboards

1. Detect AdBlockers

There are already numerous ways to detect clients / users with ad blocking apps activated so I will only list a few:

You will notice that almost all detection kits use a ‘dummy’ / ‘fake’ ad related file which will hopefully trigger an ad blocking app and this should fire a GA event. You can of course adapt it to detect your real ads being blocked without the need to add the fake script.

The logic

Using any of the for mentioned scripts fire a Google Analytics event e.g. in case you are using GTM push the info via dataLayer:

window.dataLayer = window.dataLayer || [];
'event' : 'trackEvent',
'eventCategory': 'Adblock',
'eventAction': 'Active'

Create a Google Analytics Event template tag using these values which is triggered on the custom event trackEvent and you’re almost done (variables and triggers should be created as well):


2. Make the number of page ad slots available

Again if using GTM just add the information to dataLayer which will represent the number of ad slots available on a single page. The idea is to simply use getElementsByClassName() which will return an object which has a property length – use this logic to obtain the number  of ad slots available on a specific page (the value which we are looking for is length +1 as the indexing starts at 0).

Easy as:

var adSlotIndex = document.getElementsByClassName('elementClassWhichContainsAnAd').length;

One thing worth noting is that you will probably want to send this info after DOM is ready so choose how to send this custom metric carefully – options are to send it with a pageview (so PV tracking should be DOM ready) or use an event for more flexibility just make sure non interaction is set to true.

In addition you can send another custom metric which will be currency type which will be calculated as total Ad Slots On Page * Average Revenue Per Impression – reporting with currency gives more weight to the whole concept.


3. GA prerequisites and building the dashboard

First take care of the segment – Session level segment which will be Event Category == AdBlock and Event Action == Active. This will allow reporting on sessions where AdBlock was active – in specific number of ad impressions or better say ads that were supposed to be delivered you could not be as they were … blocked. This segment can be applied to standard / custom reports, dashboards and used in API exports.

Secondly create the custom metric(s) on GA property level.

And now it is all up to you to show the data best way you can – the way it will make you do something to battle this revenue consuming trend.


Some reports details to consider: browser, browser version, geography based dimensions, content grouping (LP or page – to determine where this revenue source is most sensitive) – you will probably find more useful dimensions.

Hope this helps in determining how much money you loose from ad blockers:)

Happy tracking!

Development and optimization of PPC campaigns

Quite often I see various online campaigns that we should “optimize” because they do not achieve the results as they should or what they owners was hoping for. You could say that there is always the problem of maximizing the impact of the adwords campaign. In most cases the solution to this problem is, in theory, quite simple but at the same time it is quite tricky to apply in reality.

Depending on type of campaign(s), how many targeted countries there are, what is the budget for each of the markets (country) or for a particular product, if the budget is limited, do we have outlined an investment plan… – so much will be a different plan of optimization for PPC campaign. Every optimization has a few simple stages.

Optimization Stages

But first things first. Let’s say you are starting your first campaign. What’s the first thing you should do? Even before you put your first word or an ad in the AdWords system? Research and planning. This is so simple and above all a very important stage/phase which many of other agencies do not implement properly or in a correct way.


Research for PPC campaigns

Market research is the most basic stage before the “construction” of our campaign. At my lectures I always use a very simple comparison. What would you say if I asked you what is the most important “part” in the case of construction of the house? Many have responded to this question with “concrete walls”, “roof that does not leak”, “wife’s kitchen” and so on.


Although some of these parts of the house are very important (especially in the case of wife’s kitchen) many have not remembered that the most important part of the house is its foundations. The foundations are the ones to which everything else binds. If the foundations are not well-built then even if you have the best concrete walls in the world your house will look crocked. And we certainly do not wish for our wife to constantly complains about the inclined walls in her kitchen, do we?

We could say that, in the case of a online campaigns, research is of very great importance. For example, if you did not well explored all keywords that are being  searched on the search engines and that are relevant for your “offer” – you can totally miss targeting of your adwords (PPC) campaigns. And if you miss the target of your campaigns – you threw money in totally wrong direction.

Initial campaign research

Sometimes this stage can take a lot of time. The research is not just about keyword research but also about deals offered on the (client) website. Sometimes it is important to be “familiar” with the services and products offered on the website. If you know them, then you will know what kind of person would want to buy such offer/product. If you made enough effort on this stage and made research as it should be – then all the subsequent steps will be a lot easier.


Planning the online campaign

Based on the results that we get during the research phase we are making the advertising plan. This plan consists of several separate parts, where each one of them, in its own way, affects the final results of the campaign. Of course, one should be aware that sometimes we do not have enough information on which we could, with certainty, correctly predict what will happen.

In other words, sometimes the planning of advertising must be done with so-called “Best educated guess” – these are not predictions based on data that was not researched (because there are none), but based on our experience and knowledge in the field of marketing that we have collected over the past years. It should be noted that this predictions in most cases are quite accurate, but there are also times when they are not.

However, one should know that the planning phase is cyclically repeating in the process of optimization of digital campaigns – look at the last image in this post. Even in cases where our initial predictions were not entirely correct, we can use the specific data from active campaigns and use that data as basis on which we shall subsequently change plan of advertising.

Campaign planning

Planning stage may consist of planning the advertising time (day time, week, month…), what kind of campaign we shall use (search, video, mobile, display…), the structure of the campaign, projected advertising budget (taking into account competition and average price per click), provided budget for targeted markets (countries), deciding which metrics to be measured and so on…

Remember – no matter how it is made, it is still true that any plan is better than the plan that does not exist!


In the case of “wife’s kitchen” we could say that only wife knows the full plan which is changed at regular intervals (every week when she looks at the latest TV shows about house arrangement) and therefore it is the best (and easiest) to let the wife do all the planning.


Creating PPC campaign

Based on our plan we are starting with construction of the campaigns and their structures. This stage in the process is quite complicated and time consuming. However, it is time consuming only during this first set-up. If it is properly made by following some basic rules, such as the naming of campaigns, ad groups and ads, any subsequent changes are very easy and fast.

Here we can say that the basic concept is to make the best we can in the beginning only that we could later have the simpler job. Unfortunately, many at this stage “skip” those things for which they knew it would be good to do.

Campaign Creating

If the creation of campaign is not done in correct way then the whole campaign will suffer from inadequate performance but also from its subsequent optimization. Because optimization is greatly hampered if even the author of campaign can not navigate in the sea of ​​information, campaigns, ads and targeted phrases. This case is more evident if there was no plan (or proper research) during the initial setup of the campaign.

If we worked according to plan then even our wife can not say anything if we, for example, set the tiles with floral pattern in her kitchen (according to her plan) but since then she has changed that plan and now she requires the tiles with the modern pattern.


Data collection

The next stage is actually quite simple and relatively easy, provided that all the previous stages are made according to the rules. In this stage we are collecting information from active campaigns. This data is not limited only to data from campaigns but we also look at the data from statistical tools – tools with which you are monitoring your website (Google analytics).

Campaign data collection

It is very important to constant monitor how the campaigns are “acting” at this stage. Sometimes it can happen that we see totally unexpected behavior and results of the campaigns – at that moment it is important to immediately react and make changes to the campaign itself.

For example, depending on how loudly (and often) our wife complains about the tiling – we will immediately remove all the tiles with floral patterns.


Data analysis of online campaigns

Based on these data we are making conclusions as to whether the campaign was successful, what worked, what could be better and so on. At this stage, we try to pay attention to all “components” of the campaign. From targeted words & phrases through actual queries that have occurred to cost per conversion and return on investment.

Sometimes we reach certain results that were not in line with our expectations. If we do not see a real reason for that results then it is very important to re-examine all campaign settings and the plan itself. Sometimes it happens that we failed to notice certain facts during research stage.

Campaign data analysis

Analysis, if the initial stages (research, planning, development) are made according to some basic rules, is very simple. Otherwise, our analysis can come to all the wrong conclusions. Erroneous conclusions on which we must make decisions for future advertising.

We can say that only at this stage the real optimization is starting. However, one should bear in mind that optimization simply would not be possible without all the previous stages. For example, if you just recently took over PPC campaign (which was managed by some other agency) it was very important to first go through all the previous stages in order to see if the campaign was well made (planned) from start.

Analytics dashboard


Based on data analysis we are making decisions for future advertising – and for changes that needs to be done to campaigns. For example, if wife stopped to complain about the tiles in the kitchen (which we removed the day before) but now began to complain of too high ceiling for exactly 5 inches – then we know what to do next (optimize) 🙂

The whole process is repeating. Research, provided that it was properly done at the beginning, is not part of this process in the same sense. The research is still done but we might say that it is now part of the planning and preparation/changing (of the campaigns) stage.

PPC Optimization stages

For example, it is necessary to investigate (research) all queries for which our ads have triggered and then to exclude those that are not relevant to our offer. Or, let’s say that in the case of limited budgets we need to research what keywords are bringing/leading to conversions and then separate them to specific campaigns.

After we have changed the campaign according to plan (which was based on an analysis of data) we continue to gather new data from now optimized campaigns. All stages are now cyclic continuing over time.

In short, we could say that the whole concept of PPC campaign optimization is very simple, and that it could be summed up in just a few words:


Test – Analyse – Application – Test again

Although many will recognize this concept, unfortunately, many did not even try to apply it to their campaigns. Is it due to lack of time (personnel) or simply laziness – I do not know. But I do know that often happens that our customers ask us questions on just how we were able to raise revenue for the 20, 30 or more than 100%.

The answer is simple, you just have to know how to apply in the real world.

If you are interested in additional information about optimizing your campaign – feel free to contact us.

Gmail ads are now available to everyone

GSP ads (Gmail Sponsored Promotions) are now available on all AdWords accounts. So far, this form of advertising was in Beta version and it was necessary to require Google´s permission for GSP advertising. GSP ads are somewhere between the email and display advertising because the ads are created in display campaigns and show up within the Gmail platform.

Gmail ads

GSP ads appear in email form above received emails within the Promotions tab (Collapsed ad). After clicking on the ad, the user opens an ad that looks like an email (Expanded ad). There are several types of Expanded ads.

GSP ad types

You can choose between four GSP ad types in AdWords Ad Gallery. The first ad template contains only an image ad. The second one contains a photo, title, descriptive content and call-to-action button which leads on a web page with specific offer (Destination URL). The third ad contains more than six products / services, and each of them has the ability to target specific website URLs, special call-to-action button and the title. However, there is no possibility of creating descriptive content. The fourth ad allows the possibility to create your own Expanded ads in JPEG, .JPG, .PNG, .GIF, or .ZIP .SWF format. For each template, there are various specific restrictions in the number of letters and the size of the pictures. For each template, there are distinct limitations in the number of letters and the size of pictures.

Targeting methods of GSP are similar to targeting methods of display campaign. The targeting method can be set based on age, gender, language, geo, device, topics or affinity of users, and keywords or domain targeting. Keywords targeting for GSP works like the broad match in display campaigns. Domain targeting isn’t placement targeting. Domain targeting is based on received emails in Promotions tab, which means that email should contain the target domain. Domains should be placed under the Display keywords targeting because it belongs to contextual targeting.

GSP specific metrics

GSP specific metrics in AdWords are:

  • Gmail clicks to website: Shows clicks within the Expanded ads that link to a web page (ie. Destination URL).
  • Gmail forwards: Shows sent ads as an email to another person.
  • Gmail saves: Shows the number of saved ads in the inbox as a message.

The system of charging per click for GSP ads differs from standard ads. System charges only first click on the ad, but not the rest of clicks, including all arrivals to the website. For instance, if you advertise 6 different products, you will only be charged for the first click on Collapsed ad. If a user decides to click on several different products (ie. Call-to-action button), all arrivals to each landing page are free.

As with all other campaigns, it is recommended that you group targeting in specific ad groups, and also create separate campaigns for GPS advertising, to ensure better control over costs and campaigns optimization.

The biggest advantage of GPS advertising is more space for creative titles, messages, descriptions and possibility of use multiple URLs, pictures, and call-to-action buttons.

If you are interested in setting up and running the GSP (Gmail Sponsored Promotion) campaign, please feel free to contact us.

Increase revenue – advertise best performing products

No matter which channel is used for advertising, everyone wants to know which products are the most profitable. Analytics gives you insight in a number of sold products and revenue, but there is one more option for increasing profit.

To access best selling-products data you need to set up proper E-commerce tracking. Product data performance is available in Analytics Conversions report – E-commerce – Product Performance as can be seen in the image below. For a larger amount of data select websites best-performing products for a longer time period (at least 6 months).

analytics - product performance

To find out for ourselves how profitable is to advertise specific products, we decided to advertise 100 best selling product in the last 6 months. Products were divided in separate ad groups with specific features of each product ads. Ads performance analysis showed which features create the greatest response. During the first month of advertising, campaign indicated extremely positive results.

adwords - campaigns

With 16.58% CTR (click through rate) campaign was on the second place. For only €0.22 CPC (cost per click), ads were at great 1.3 position. There is a pretty big chance that competition will also advertise for some of best selling products which could result in higher CPC. We strongly recommend to control your ads performance on a daily basis and raise bids to keep ads positioned higher. The campaign had 5 conversions and 808% ROI in the first month of advertising from €52 investment and €10 cost per conversion. The campaign had € 471 revenue of total € 7 700 revenue.

analytics - revenue

 Return on advertising spend (ROAS) was 1 389.51%.

analytics - roas

Products advertising example:

Product advertising

The above image shows the perfect example of specific product advertising and which ads are optimized for that type of advertising.

Customers search products by name if they want to know more about the product, or if they already decided to buy a specific product. Customers don’t always see the difference between organic search results and paid ads so it is important to have your ads above organic search results.

Campaign performance showed that customers search for products by their name. For that reason it is necessary to advertise for the specific product and not only for general terms. Don’t forget to advertise for misspellings and typos. Familiarize yourself with product features and highlight them in your ads. Create different ads for one ad group and test their performance. That is the only way to find out which product feature result in sales.


Time to complete a goal or transaction using GTM and Google Analytics

Here is a quick overview of how to track the time needed for a user to finalize a desired activity inside a session using Google Tag Manager and Google Analytics. The example in this article is a simplified overview of various hits and methods on how we can achieve process tracking inside Google Analytics. By default Analytics measures Session length / duration and time on page which is quite challenging in this cases and rarely applicable thus one may be forced to use features like custom metrics and / or user timing hits.

Case – time from session start to lead generation form submit

A user starts a session and is expected to fill and submit a lead generation form. We would really like to know how long this process usually takes (not the entire multichannel / multi device experience in this case but just the in session experience).  The experience will be highly affected by previous experience with the site – so using some segments while analysing would come in quite handy.

The idea on how to fetch these values is quite simple. Drop a cookie once a session starts, or in some specific cases when an on site process starts (e.g. checkout) – where the cookie value will be the session / process start time. After the user has completed the process – successfully completed the desired action (we basically mimic Analytics goal behaviour – so it is either a destination or an event based trigger in GTM) we send a User timing hit or an event hit with a time type custom metric.


The procedure

What is needed:

1. Cookie tag – Custom HTML
On session start we set a session level cookie.

var d = new Date().getTime();
document.cookie = "sessionStart=" + d + "; path=/;";

Trigger – Pageview using a 1st party cookie variable sessionStart (so fire only if sessionStart is undefined).
Variable – 1st party cookie – sessionsStart ({{gtm sessionStart}}).

trigger first page in a session

 2. Google Analytics pageview tag – Template tag – Universal Analytics

This is a basic GA universal pageview tag yet I added a hitCallback inside ‘Fields to set’ to safely set a clientId as a custom dimension (user level – do not forget to dreate the custom dimension inside GA admin) in an additional event tag (ty Simo!) – this will fire a Google Analytics event tag only when the Pageview tag has fired successfully. so the setup looks like this:

universal analytics main pageview tag

Trigger – All pages (default trigger).
Variable – custom js variable which send a custom event via dataLayer push – this event is used for the Utility Event responsible for adding a custom dimension with clientId value.

check if ua pageview fired

function() {
return function(){dataLayer.push({'event': 'pageViewFired'});}

3. Google Analytics Event tag – Template tag – Universal Analytics

A simple event tag which only purpose is to set the Custom Dimension value of the users clientId (this is used to further analyse time for each process based on the client Id – some randomization could be utilized if a user is expected to have multiple conversions or even add a process end time as a custom dimension or use time dimensions in GA).

event tag set cid

Trigger – event equals pageViewFired.
Variable – use a custom JS variable which will fetch the clientId value.

function() {
return ga.getAll()[0].get('clientId');

4. Google Analytics User timing tag – Template tag – Universal Analytics

This is where we send info to GA that the process has successfully ended and pass the time value. So the setup looks like this:

user timing hit

Trigger – any which identifies the session has resulted in a goal completion. For this case I used a simple custom event – trackConversion – dataLayer.push({‘event’:’trackConversion’});

Calculation and variables – as you noticed a different variable is used for the custom metric and user timing value. The reason for this is that user timing hit requires a value in milliseconds and custom metrics in seconds. The calculation is pretty simple.  You need 2 variables:

User timing value

function (){
var endTime = new Date().getTime(); // this could easily be a separate variable
return endTime - {{gtm sessionStart}};

and Custom metric value

function (){
var endTime = new Date().getTime(); // this could easily be a separate variable
return (endTime - {{gtm sessionStart}})/1000;

And that’s basically it – one word of caution though user timing hits are prone to sampling so consider sending the timing info through events with CD and CM defined.

When you are done setting this up the example report could be something like this:

report example


Hope the article was useful and of course happy tracking!


iFrame Google Tag Manager Cross domain tracking alternative

Hi to all who have dealt with the cross domain issue when working with iFrames – it can be a tedious endeavour yet using Google Tag Manager and Universal Analytics the process is somewhat simplified. This is also an updated version of a similar method yet this one uses the Google Analytics Template tag inside GTM.

There already are some great articles which offer a complete set up workflow such as a great Article by Claudia Kosny found on – – yet we found it to be a bit too complex when working without a decent developer support and the main issues were:

  • iFrame will not show if Google servers do not respond and
  • iFrame will not show if the GTM setup was misconfigured

If the iFrame was on the site to render some critical information such as Booking engine or any kind of Payment service it was just too big of a risk.
Fortunately Google updated the iFrame section of cross domain tracking with a new method which does not have this kind of problem – Tracking Cross Domain iFrames using postMessage –

Downside to this method is:

  • users with IE7 and earlier will be tracked as different clientIDs (cross domain tracking will not be in effect yet tracking will still occur)

To be clear the end goal of this implementation is to preserve the session and have accurate attribution reporting inside Google Analytics – this of course includes the ability to set up funnels and any additional hits within the existing session (without messing up traffic sources and session inflation when using Universal Analytics).

How to set up iFrame cross domain tracking for Universal Analytics via GTM

1. Referral exclusion

The first step is to always prepare the referral exclusion list. Our example will use the domains (parent domain) and (child domain – page on domain inside iFrame).

2. GTM container

Place the GTM container snippet on both domains! More info can be found in Google Help center

3. GTM settings (GTM Tags, triggers, variables and more)


Triggers help you define when a tag should be activated using various conditions.

1. all pages parent (parent domain)
A tag using this trigger will activate only on pages with hostname (our parent page). You can opt to change the trigger type to either DOM or Page View just make sure you test the setup.
{{Page Hostname}} > match case (can be any which defines the situation) >

all pages parent trigger

2. all pages child (child domain – inside iFrame)
A tag using this trigger will activate only on pages with hostname (our iFrame page).
{{Page Hostname}} > match case (can be any which defines the situation) >

all pages child trigger

3. event on child trackPage (fires the page on child domain after it has dealt with the cid retrieval)
A tag using this trigger will activate only on pages with hostname (optional) and only when the custom event trackPage has been pushed to dataLayer.
Event name: trackPage
{{Page Hostname}} > match case (can be any which defines the situation) > (optional)

event child domain trigger


The following examples are basically utility Variables with which you can easily reuse the entire setup in just a few edits – in short you do not need to mess with the code just edit everything with variables.

1. dl cid (Data Layer)
A Data Layer type variable which returns value of cid once it is pushed to dataLayer.

2. dl virtualPagePath and dl virtualPageTitle (Data Layer)
Just an example of what you can additionally define for tags e.g. booking steps or similar.

3. gtm allowedOrigins (Constant)
Used to set the whitelisted sites (i.e. your booking engine, payment system, CRM) which can communicate to our parent Domain.
Value:, (a list of comma separated domains where our page inside iFrame is placed)

4. gtm topOrigin (Constant)
Used to define the domain which holds our parent Page – parent domain.
Value: (our main domain)

5. gtm uaTrackingId (Constant)
We will store the UA tracking ID (property ID) in a Macro so we can reuse it all of our GA tags with less chance of human error:) (you can of course change it to lookup, dl or custom JS)


We will need 3 separate tags – 2 Custom HTML and one plain Universal Pageview tag for the complete setup to work. Custom HTML Tags are used to retrieve the cid parameter (code is provided in the full container download). Do not forget to add the clientId under fields to set!

Custom HTML #1 (on child domain only (inside iFrame)):

// Add the expected origin domain inside gtm topOrigin variable
// Must use the following format
var topOrigin = {{gtm topOrigin}}; 
function xDomainHandler(event) {
  event = event || window.event;
  var origin = event.origin;
  if (topOrigin != '*' && topOrigin != event.origin) {
  try {
    var data = JSON.parse(;
  } catch (e) {
    // SyntaxError or JSON is undefined.
  if (data.cid) {

if (window.addEventListener) {
  window.addEventListener('message', xDomainHandler, false);
} else if (window.attachEvent) {
  window.attachEvent('onmessage', xDomainHandler);

var alreadySent = false;
function sendHit(cid) {
  if (alreadySent) return;
  alreadySent = true;
  // If cid exists, it will overwrite any existing values
  var params = {};
  if (cid) params['clientId'] = cid;
  dataLayer.push({'event':'trackPage','cid': cid});
if (!window.postMessage) {
  // If no postMessage Support.
} else {
  // Tell top that we are ready.
  top.postMessage('send_client_id', topOrigin);
  // Set a timeout in case top doesn't respond.
  setTimeout(sendHit, 100);


Custom HTML #2 (on parent domain only ):

// Edit the gtm allowedOrigins variable and add your domains to the whitelist
var allowedOrigins = {{gtm allowedOrigins}}.split(',');
function xDomainHandler(event) {
  event = event || window.event;
  var origin = event.origin;
// Check for the whitelist.
  var found = false;
  for (var i = 0; i < allowedOrigins.length; i++) {
    if (allowedOrigins[i] == origin) {

      found = true;
  if (!found) return;
  if ( != 'send_client_id') return;

// Get the clientId and send the message.
  var tracker = ga.getAll()[0];
    var data = {cid: tracker.get('clientId')};
    event.source.postMessage(JSON.stringify(data), origin);
if (window.addEventListener) {
  window.addEventListener('message', xDomainHandler, false);
} else if (window.attachEvent) {
  window.attachEvent('onmessage', xDomainHandler);


The final tag setup will look like this:

cross domain tags




ua pv main tag



You can download the full container version here – please be careful when you import the  container you do not: overwrite your existing container or even import into a production container rather test it first in a new account / container and migrate settings after a successful testing process.

4. Publish

After you finish all of the setup please do not forget to debug, preview and create a version and publish in the end.
Happy (cross domain) tracking!