These days the use of adblocking tools is growing fast. These tools aren’t always used only blocking the ads, also analytics software is blocked sometimes.
Browser extensions like Ghostery and uBlock are used to get rid of all those trackers. Why wouldn’t a non-marketer disable all the found tracking software? With a couple of clicks someone has disabled 2000 trackers.
In this case Google Analytics and Google Tag Manager are disabled on marthijnhoiting.com. All the tags that should be loaded with GTM aren’t included anymore.
A user can have multiple reasons why he would do this. The problem is that our data gets more and more inaccurate. If 20% of our visitors is blocking Google Analytics we are missing 20% of the data we would like to have. Time to measure the percentage of our visitor that we can’t track anymore.
How to measure this?
After the page is loaded we are going to check if the Google stuff is loaded. Because i would track the GTM blockers as well we can’t use Google Tag Manager for this. So, we have to put our code in the source code of our website (the old school way). If we use GTM for this, the script isn’t loaded by visitors who are blocking Google Tag Manager.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<script type="text/javascript"> window.addEventListener('load', function() { if(window.ga && ga.create) { console.log('Google Analytics is loaded'); } else { console.log('Google Analytics is not loaded'); } if(window.google_tag_manager) { console.log('Google Tag Manager is loaded'); } else { console.log('Google Tag Manager is not loaded'); } }, false); </script> |
Put the script above on your website. Clear the cache and reload the page. Now we are going to check if everything is going well. We are doing this by writing the output to the console so we can check if everything is setup right.
1 |
console.log('Message'); |
Right click on your page, click on inspect element to open the console tab. In this example I am using Ghostery to enable and disable Google Analytics and Google Tag Manager.
When you disable Google Analytics you will get the following result:
When you disable Google Tag Manager and Google Analytics should be activated by GTM you will get the following result:
If everything is detected right we could measure it with Google Analytics. This sounds strange, but we could use the Measurement protocol to send our data.
The most easy way is loading an image pixel with javascript. But there are Browser extensions that prevent the source google-analytics.com from loading.
To show what is happening you have to replace the UA-XXXXXX-X with your own UA-code. The best practice is creating a new Google Analytics property, because the method described below will create a lot of duplicate (direct) traffic.
https://www.google-analytics.com/collect?v=1&t=event&ec=Blocking&ea=Google%20Tag%20Manager&ni=1&cid=1234567890&tid=UA-XXXXXX-X
Copy this url into your browser and hit Enter.
If we load this url and you have uBlock installed you will get a notice like this.
If you have installed uBlock allow this source and reload the page again. If you don’t have, you will see a white screen. But you can watch the impact of this call in Google Analytics under Real-Time -> Events. If you don’t see anything happen make sure you do not have filtered out your own IP!
N.b. This is also the way a lot of referral spam is generated. They are generating UA codes and calling these kind of urls.
The solution is using PHP. What we are doing is loading an server side generated image with javascript if we detect someone have disabled Google Analytics or Google Tag Manager. Our uBlock software doesn’t detect it as an tracker.
Upload this script to the root of your server and name it collect.php.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php header('Content-Type: image/png'); echo base64_decode('R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs'); if(isset($_GET['tid'])) { $tid = $_GET['tid']; } else { $tid = 'UA-XXXXXX-X';} if(isset($_GET['ec'])) { $ec = $_GET['ec']; } else { $ec = 'Blocking';} if(isset($_GET['ea'])) { $ea = $_GET['ea']; } else { $ea = 'Something';} $params = array( 'v' => 1, 'tid' => $tid, 'cid' => rand(1000000,9999999), 't' => 'event', 'ec' => $ec, 'ea' => $ea, 'ni' => '0', 'z' => rand(1000000,9999999), ); $url = 'https://www.google-analytics.com/collect'; $content = utf8_encode(http_build_query($params)); $user_agent = ''; $ch = curl_init(); curl_setopt($ch,CURLOPT_USERAGENT, $user_agent); curl_setopt($ch,CURLOPT_URL, $url); 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_POST, TRUE); curl_setopt($ch,CURLOPT_POSTFIELDS, $content); curl_exec($ch); curl_close($ch); ?> |
Back to our script we are going to make some changes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<script type="text/javascript"> window.addEventListener('load', function() { if(window.ga && ga.create) { console.log('Google Analytics is loaded'); var img = document.createElement('img'); img.setAttribute('style','display:none;'); img.src = '/collect.php?tid=UA-XXXXXX-X&ec=Allowing&ea=Google%20Analytics'; document.body.appendChild(img); } else { console.log('Google Analytics is not loaded'); var img = document.createElement('img'); img.setAttribute('style','display:none;'); img.src = '/collect.php?tid=UA-XXXXXX-X&ec=Blocking&ea=Google%20Analytics'; document.body.appendChild(img); } if(window.google_tag_manager) { console.log('Google Tag Manager is loaded'); var img = document.createElement('img'); img.setAttribute('style','display:none;'); img.src = '/collect.php?tid=UA-XXXXXX-X&ec=Allowing&ea=Google%20Tag%20Manager'; document.body.appendChild(img); } else { console.log('Google Tag Manager is not loaded'); var img = document.createElement('img'); img.setAttribute('style','display:none;'); img.src = '/collect.php?tid=UA-XXXXXX-X&ec=Blocking&ea=Google%20Tag%20Manager'; document.body.appendChild(img); } }, false); </script> |
Replace the UA-XXXXXX-X everywhere in the script above with your own UA code.
Every pageview is now tracked as an event.
Go to Google Analytics and check if your events are registered as expected.
Awesome Marthijn! This is a way better method than trying to measure ad blockers through (the possibly blocked) Tag Manager.
I really like this aproach 🙂
Hi Marthin,
first of all: what a great approach, thanks for sharing!
BUT ;): I tested your setup in chrome, opera and firefox. For some reason, if I use Firefox, I sometimes get “GA is loaded” and sometimes “GA is not loaded” – GTM always gets loaded though.
Do you have any explanation for that behavior?
Cheers!
That’s just awesome mate, thanks for sharing such a qualitative tuto!
It works great right after setting it up… in no more than 10 minutes.
A custom dimension indicating blocking / allowing would be handy too.
Oh sorry, that would be a nonsense since the server’s call is not tied to a visitor ID. So with this approach, we can see the ratio of (pageviews with GAor GTM blocked) / (pageviews with GAor GTM unblocked).
Still very useful info!
Help on where/location to upload the *collect.php* if using wordpress?
You should use a FTP client or SSH (for pro’s) to upload the file. You can place it everywhere you like. The most easy way is adding it in the root.
Hi Marthijn,
Can you help me with the php code in Java as well
my website backend is in JAVA and i want to test the optout for my website.
The collect.php file is stored in the browser cache and therefore on page reload the collect.php event is not called again. Therefore I added a random string in JavaScript ,like this
old line:
img.src = ‘/collect.php?tid=UA-XXXXXX-X&ec=Allowing&ea=Google%20Tag%20Manager’;
new line:
img.src = ‘/collect.php?tid=UA-XXXXXX-X&ec=Allowing&ea=Google%20Tag%20Manager&’+ (new Date).getTime();
Excellent!
Thank you for help – you have a better solution than stackoverflow 😉
Of je zou het het gewoon kunnen respecteren dat niet iedereen gediend is van tracking cookies en al dan wat niet meer om het gedrag van mensen te volgen.
Maar dit artikel heeft werkelijk niks met tracking cookies of het volgen van het gedrag van mensen te maken.
Hi Marthijn,
GREAT attempt!!!
Would/Could you share with us your findings?
Can you tell, what is the actual ratio for your website?
Is it about the 20%, you mentioned in your post?
If anybody else uses this method, I would be glad, if somebody could share this. I suspect, that it certainly depends a little bit on the kind of website, you manage
YOU ARE THE MAN!!!
There might be a reason why the user disabled GA or GTM. I believe you are giving the user an opportunity to sue you by sending his private data out of your own domain.
Har, Not if it’s in the terms-of-use on the site — if your site explicitly states it collects this data, the user has no right to sue – just the right not to visit your site (why terms-of use exist – to protect both parties). There is nothing illegal about gathering aggregate data to better your product – plus the funny thing is, most ad-blockers and track-blockers collect/track/report activity of their users – talk about irony!!
This approach gives me headaches. Because of several reasons (mostly financial) I have 1Mbit to use, with another bundled 1Mbit that doesn’t apply to http requests. Yes. That’s 1Mbit.
The problem is that it takes too long (according to the server and the ISP) to load things, and therefore I even get on both Windows, Debian and Mac (I don’t use adblock for some pages that I need) (I don’t even use Safari more than nessecary on the Macs neither Edge, but both of them get that annoying Please remove your adblocker).
I can understand that. Even though I want to use adblocking software on several sites. And, understand, that I mostly have 1Mbit.
When I have to click on something as “Like us on Twitter, G+, Facebook”, Whatever, if it takes too long a JS activates a closing curtain to the site I’m visiting. I blame this partly on both google and their programmers. Remember, not everybody has 1Gbit connections.
Very useful. I recently noticed a drop in traffic after I implemented GTM (before we used GA directly), I was puzzled at first but then I found out that GTM is more likely to be blocked by ads blocker than GA.
We have implemented a new tracking similar to what you suggest here. I would also like to add that if your GTM has tons of tags other than the GA you will not have those tags run when GTM is blocked. This is really bad if you put the livechat script inside the GTM tag for example. Beware of this issue.
In my opinion, the decision of ad blockers to block GTM is really bad, because we could have many useful things to run in GTM, not just ads and trackers.
Ublock start blocking request to this URL as well
https://www.google-analytics.com/r/collect?v=1
Enable ublock and host the analytic js on your server and you will see your local analytic js will load successfully but the URL call from that script is blocked.
Only good way is detect the adblocker and warn user every time with alert box.
Is it still working?
Great post, I’m interested in what % of people you’ve found to be blocking GA. How has it changed over time?
Same here , I wonder what the benchmark rate is. I approximate 7%.
Very thorough approach, well done!
Hi Martijn,
I suggest you filter the $_GET for security reasons. Trusting the values as is may open your server up to security holes. And so everyone whole already has used this script.
http://php.net/manual/en/function.filter-input.php
Btw. Thank you for the script!
Greetz,
Jaime
Hi,
Great post!
I know you said this will increase the number the event hits and so I have set up another property as you suggested.
These event hits are being sent directly to the property without any filtering. So, does that mean that these hits are being triggered by Bots and other spammers visiting the website along with legitimate human users?
The site I have set up with this JS has very low traffic, is there a way to only send these event hits when real users arrive on the site instead?
Cheers
Amazing script and worked great!!!
Does this work for Google Publisher for Doubleclick with any examples?
Works great!
Do you have a solution for people who get the warning and never return to your site?
Wow really helped a lot for my daily Practice! Thanks a lot guru hoiting! Now i know this I can solve many of my problems! Big fan of your work!
Thanks for this !
I have just created an anti Adblock feature on my site 🙂
Now we will see if they will block my google analytics on santiano.io
The main problem with this approach is that you’ll end with 2 new random user for every pageview the users with the block do. Better to store in a cookie a random value and use it as a cid.
This Script is great!! But i see 2 people in Analytics
rather than 1 for each access…. and if i do refresh this number is exponential!
Hey, sounds like a nice solution. I implemented everything as described. But when I then view my Real Time stats in Analytics, I see too many “current users” (like 12 users, all from one single city). When I remove your code these users drop out of Analytics.
I have also setup a new view in Analytics to just view results from “Blocking” users, but also this looks strange. Have you tested viewing stats in Analytics after you have implemented this ^^ code?
Just a note from your basic web user worried about privacy.
We understand your need for internal analytics. Trouble is, you use google’s free stuff. They give it to you free in exchange for you leaking my privacy to google. They build up a shadow profile on me. I in turn reject any ad if i get the slightest scent of facebook or google “personalizing” ads for me. I avoid both companies due to their Nazi type behavior. So i am offended that websites hand this to them freely. Anonyimized advertisement is fine. Profiling is wrong, so don’t expect users to do anything other than block. We cannot tell the difference between good and “bad” cookies, so block everything!
Screw trackers. They are an aggregious invasion of personal privacy.
If the “Google Analytics Opt-out Add-on” chrome extension is installed, I still get “Google Analytics is loaded” and “Google Tag Manager is loaded” appearing in console.
Does the if(window.ga && ga.create) and if(window.google_tag_manager) code need updated to work properly?
Very intresting post. It can be usefull, but it is still working? Greetings.
Where do you add the first script? You state “Put the script above on your website.” – but where would this be for a WrodPress site?
Inside the
section in your WordPress templates!