Navigation

Related Articles

3 steps to report AdBlock users visits

3 steps to report AdBlock users visits


Wojtek Andrzejczak
Wojtek Andrzejczak
3 steps to report AdBlock users visits

Learn how to track in Google Analytics a user who uses AdBlock.

AdBlock usage statistics

Depends on the country and website, users who use any kind of AdBlock software is between 10% and 48%.

How could we measure AdBlock users?

And this is a bit of a challenge. Most of the AdBlock software blocks analytics software like Google Analytics or Adobe Analytics. But also any tag managers like Google Tag Manager or Adobe Tag Manager.

So if we would like to track those users, we’d have to do this on the server-side, not on the client-side.

Google Analytics Measurement Protocol

Measurement Protocol allows sending HTTP requests directly to the Google Analytics servers without default JavaScript snippet. The downside is that we have to code everything by our selves.

Prepare a script to detect AdBlock

First of all, we need to create on all pages script which will detect if any AdBlock is available on the page. Script tries to create an element with “ad” related IDs and attributes so that any AdBlock software would block/hide it on the page. If the 1×1 element created by us does not have any height, then it is blocked.

<script>
  (function(){
      function getCookie(cname) {
        var name = cname + "=";
        var decodedCookie = decodeURIComponent(document.cookie);
        var ca = decodedCookie.split(';');
        for (var i = 0; i < ca.length; i++) {
          var c = ca[i];
          while (c.charAt(0) == ' ') {
            c = c.substring(1);
          }
          if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
          }
        }
        return "";
      }

    function AdBlockEnabled() {
      var ad = document.createElement('ins');
      ad.id = 'AdBanner';
      ad.className = 'ad adsense google ad-slot';
      ad.style.display = 'block';
      ad.style.position = 'absolute';
      ad.style.top = '-1px';
      ad.style.height = '1px';
      ad.style.width = '1px';
      document.body.appendChild(ad);

      var isAdBlockEnabled = !ad.clientHeight;
      return isAdBlockEnabled;
    }

    function adBlockCallback() {
      var params = [];
      params.push({key: 'dh', value: window.location.href});
      params.push({key: 'dp', value: window.location.pathname});
      params.push({key: 'cid', value: getCookie('adb_uuid') || new Date().getTime()});
      params.push({key: 'tid', value: 'UA-149687655-1'});
      params.push({key: 'ul', value: navigator.language});
      
      var query_params = params.reduce(function(acc, item) { 
        var chunk = item.key + '=' + encodeURIComponent(item.value);

        return acc ? acc + '&' + chunk : chunk; 
      },  null);

      var http = new XMLHttpRequest();
      const url = '/hit_adbu.php?' + query_params;
      http.open('GET', url);
      http.send();
    }

    window.onload = function() {
      if (AdBlockEnabled()) {
        adBlockCallback();
      }
    }
  })();
</script>

Create a backend piggyback script.

When the script on the page detects AdBlock, then an AJAX request is sent to the website script (in our case, PHP script) to inform Google Analytics about user visits.

Script bellow sets an adb_uuid Cookie, to identify the same user over a period of time, to avoid multiply unmatched Page View hits.

<?php

header_remove();
header("Expires: Tue, 03 Jul 2001 06:00:00 GMT", true); // *
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT", true);
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0", true);
header("Pragma: no-cache", true);


function responseWithCookie($name, $value, $ttl=31536000) {

    $domain = $_SERVER['SERVER_NAME'];
    $expires = time() + $ttl;

    if ($_SERVER['REQUEST_SCHEME'] === 'https') {
        $options = [];
        $options['expires'] = $expires;
        $options['path'] = '/';
        $options['domain'] = $domain;
        $options['secure'] = false;
        $options['httponly'] = false;

        if ((float)phpversion() >= 7.4) {
            $options['SameSite'] = 'none';
            $options['secure'] = true;
        }

        setcookie($name, $value, $options);
    } else {
        setcookie($name, $value, $expires, "/", $domain);
    }

    $_COOKIE[$name] = $value;
}


function getKey($items, $key) {
  if (!$items) return null;
  return array_key_exists($key, $items) ? $items[$key] : null;
}

$dh = getKey($_GET, 'dh'); // https://example.com/****
$dp = getKey($_GET, 'dp'); // https://example.com/****
$cid = getKey($_GET, 'cid'); // User Unique ID
$tid = getKey($_GET, 'tid'); // UA-****
$ul = getKey($_GET, 'ul'); // en-us

parse_str(parse_url($dh, PHP_URL_QUERY), $query_params);

$utm_campaign = getKey($query_params, 'utm_campaign');
$utm_source = getKey($query_params, 'utm_source');
$utm_medium = getKey($query_params, 'utm_medium');

if (!$dh || !$dp || !$tid) {
    exit;
}
$strCookie='';
foreach ($_COOKIE as $key => $value) {
    $strCookie .= $key . '=' . $value . '; ';
}

$fields_string='';
$fields = array (
    'v' => 1,
    'tid' => $tid,
    'cid' => $cid,
    'uip' => $_SERVER['REMOTE_ADDR'],
    'dh' => $dh,
    'dp' => $dp,
    'ul' => $ul,
    't' => 'pageview',
    'cd6' => 'true'
);

if ($utm_campaign) {
    $fields['cn'] = $utm_campaign;
}

if ($utm_source) {
    $fields['cs'] = $utm_source;
}

if ($utm_medium) {
    $fields['cm'] = $utm_medium;
}


$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, utf8_encode(http_build_query($fields)));
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, 'https://ssl.google-analytics.com/collect');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIE, $strCookie);
curl_exec($ch);

$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$header = curl_getinfo($ch);
curl_close($ch);
$header['errno'] = $err;
$header['errmsg'] = $errmsg;

responseWithCookie('adb_uuid', $cid);

header('Content-type: image/gif');
echo $content;

Create a GA Custom Dimension

To let us distinguish users with and without AdBlock, we need to create a Custom Dimension in Google Analytics.

AdBlock user visit / Google Analytics / Custom Dimension
AdBlock user visit / Google Analytics / Custom Dimension

User visit with AdBlock

To check how our solution works, with enabled AdBlock, we can find in Chrome DevTools a new request called “hit_abdu.php”, which is called by our script from the 1st step.

Google Chrome / DevTools / AdBlock user visit
Google Chrome / DevTools / AdBlock user visit

User visit without AdBlock

Without AdBlock, there would be no “hit_abdu.php” request.

Google Chrome / DevTools / Non AdBlock user visit
Google Chrome / DevTools / Non AdBlock user visit

Results

As you can see on the image bellow, reported users from the last 7 days is about 11%. We can estimate the percentage share of the AdBlock users which impacted our campaigns.

Google Analytics / AdBlock users
Google Analytics / AdBlock users

Links


  • Contact Me
    Contact me if you need advice or if you need help. Would you please choose the most suitable contact channel for you?
  • My Services
    If you need a technical specialist to technical support to fix your problems, you are in the right place.
  • Who I am
    Hello, my name is Wojtek, I’m an experienced Software Engineer, with many many years of experience in the advertising industry.

Subscribe to receive updates about new articles.

[newsletter_form button_color=”#E74C3C”]
Show Comments (2)

Comments

  • shoulderposture
    shoulderposture

    Hello I am so delighted I found your webpage, I really found you by accident,
    while I was searching on Aol for something
    else, Nonetheless I am here now and would just like to say many thanks for a remarkable
    post and a all round enjoyable blog (I also love the theme/design), I don’t have time to read through it all at the minute but I have bookmarked it and also added your RSS feeds,
    so when I have time I will be back to read a lot more, Please
    do keep up the fantastic jo.

    • Article Author
    • Reply
  • Anonymous
    Anonymous

    Hum i have to change the tid params.push({key: ‘tid’, value: ‘UA-149687655-1’}); with my analytics UA property right?

    • Article Author
    • Reply

Related Articles

9 steps on how to create a Dynamic Profile • Google Studio
Google Studio

9 steps on how to create a Dynamic Profile • Google Studio

Guide on how to create a Dynamic Profile in Google Studio. It is first to step to build Dynamic Creatives.

Posted on by Wojtek Andrzejczak
10 facts about iOS 15 Private Relay • Apple iCloud Plus Privacy
News

10 facts about iOS 15 Private Relay • Apple iCloud Plus Privacy

Apple has released a new iOS 15, and the most interesting functionality is the definite release of the iCloud Plus Private Relay as the new privacy solution. What is Apple iCloud...

Posted on by Wojtek Andrzejczak