Here at data·yze our sole source of income is from ad revenue. As such, we take ad blockers as a threat to our existence. We've devised a way to detect the use of add blocker, and get around them. In the first half of the tutorial, we're focused on detecting the use of an adblocker.
In this tutorial we're using JQuery as it makes the code shorter, and easier to read. Our approach can work without JQuery with some minor modifications. To further simplify things, we'll use Google Adsense as our example ad network.
Most adblocking detection scripts use a bait-and-catch type approach. A "bait" file, such as a local ads.js, is created to look like an advertising script file. In reality, all the bait file does is set some variables. If the ad blocker takes the bait and blocks the script from downloading or executing, the variables will remain unset and the site can detect the ad blocker. We don't like this approach for several reasons: (1) in our experience, not all ad blockers take the bait. In fact, some of the bigger ones seem particularly adapt and ignoring the bait. (2) Most adnetworks already require an ad script to be downloaded and executed, anyway. And (3) adding an extra file to download creates additional latency that can slow down the rendering of your website which can affect how your site ranks with major search engines, not to mention worsen the user experience.
Our approach is to create a specialized wrapper around the ad. When we detect the wrapper we know an ad was intended to be included within the wrapper. Thus in addition to detecting if the script downloaded, we can also detect whether the page has been modified by the DOM.
A Google Adsense is inserted into the DOM by inserting an INS element with class name "adsbygoogle", e.g. <ins class="adsbygoogle" ... >. With a custom wrapper the code inserted into our page might look like <div id="foo"><ins class="adsbygoogle" ... ></div>. (See advanced tips on randomizing the wrapper id.)
In our experience, 98.8% of adblockers work by preventing the adscript from downloading. This is easily checked by using jQuery to get the script, and setting a variable on success.
We're data people, here at data·yze. As such, we like to track everything. The following lines of code use Google Analytics to track adsense script load times. We first check if the adsense script has been loaded by the Window.Ready event, then the Window.Load event. If not, we check every 250 milliseconds up to a timeout. In our experience if the script isn't loaded by Window.Ready, there's only a 0.2% chance it will load by the timeout. Depending on your audience, however, a different timeout might be more appropriate. (See advanced tips below on using a subset of your user base to test load times.)
The function adblockerDetected() is a place holder. In this half of the tutorial we're just focusing on detecting the presence of an adblocker. In the next part we'll give you some ideas for adblockerDetected().
While most adblockers work by blocking the adscript from downloading, there are other ways to hide an ad. One can use CSS to render it invisible, or rip it from the DOM. Thus, once the script has downloaded we call checkAdsense.
The first step is to get the wrapper div id, and check to see if there is still an ins element with a classname of "adsbygoogle". This is done with checkAdsense(). In our experience, modifying the DOM to remove this ins element is the 3rd most common approach by adblockers. If the ad exists, we check to see if the there is content within the ad with line 18. If not, it's possible the ad script has not had a chance to complete yet. Thus we use another timeout, checkIfExecutedNextInterval() to give the script a chance to execute.
Lines 25-34 check for other forms of hiding ads though CSS tricks. Line 34 checks for an ad injection. Be sure to change the publisher id, ca-pub-XXXXXXX to your own!
Note, line 21 may be controversial. It's possible that the user was not using an adblocker, but Google was unable to identify an appropriate ad to display, and that's why the ad content is empty after the time out. If adblockerDetected() creates a pop up that blocks access to your site, it may not be appropriate to call it at line 21. If adblockerDetected() shows another ad in place of the missing adsense, then there may be no harm calling it at line 21.
Why do you want to randomize your wrapper ids? Some adblockers allow user customization that can target sections of HTML code. By randomizing the ID, no one can create an adblock scripts that removes the wrapper (and thus all it's ad contents) from the DOM ahead of time. The user will have to remove each an every ad individually, after it has been seen.
To randomize the wrapper id, start by changing line adsense_ids = ['foo']; to adsense_ids = [];
Use the PHP function randomAdsenseDivID() to generate a random id.
Using randomAdsenseDivID(), try the following line of PHP code which creates the id, and pushes it to the adsense_id javascript array.
It is very important to set your time out appropriately. If the timeout is too short, you'll over estimate the presence of adblocking. Too long, and you'll miss out on opportunities to catch adblockers.
Since your user demographics can always change, we recommend siphoning off a subset of your traffic and making them exempt from the time out. Modify checkIfLoadNextInterval(interval) as follows:
Note, we only track the event in Google Analytics if the variable exempt is set to true. Then, inside your $(window).on("load", function() { modify your call to checkIfLoadNextInterval(250); to checkIfLoadNextInterval(250, Math.random() < x); where x is the percentage of traffic you want to siphon off for testing.