How to Detect Ad-Blockers

18th February 2016 | Tags:

Source Code | Demo

There’s no doubt about it, the use of ad-​blockers is on the rise. Feel­ings run high on the issue; with web users argu­ing that adver­tise­ments are beyond con­trol, that they have become too intru­sive and that their pri­vacy is being under­mined. Internet-​based pub­lish­ers, mean­while, argue that adver­tise­ments are a cru­cial — in many cases, only — source of income online, and that ad-​blockers threaten their very existence.

That’s not to say that one must sit in either camp — those of us who are involved in pro­duc­ing con­tent still browse the ‘Web as con­sumers, and may feel with some jus­ti­fi­ca­tion that on some sites, the use of adver­tise­ments is ruin­ing the online experience.

Wher­ever you stand on the issue, it’s clear that mid­dle ground needs to be found.

Increas­ingly, online pub­lish­ers are includ­ing scripts which attempt to detect whether users have an ad-​blocker installed when they visit their site. They may then dis­play a mes­sage explain­ing the impor­tance of adver­tise­ments, politely ask­ing that users con­sider turn­ing it off. Many pub­lish­ers also use the oppor­tu­nity to sug­gest other ways peo­ple can show their sup­port. The Guardian — an on and off line news­pa­per in the UK — is one exam­ple of this; if you browse their site with an ad-​blocker enabled, they dis­play a mes­sage about their mem­ber­ship scheme. Pub­lish­ers are explor­ing other ideas; such as sell­ing PDF ver­sions of their con­tent, or accept­ing “tips” online.

The pur­pose of this post isn’t to wade into the debate; but rather, to demon­strate how site-​owners and pub­lish­ers can detect whether a user has an ad-​blocker enabled, and some approaches to dis­play­ing mes­sages or alter­na­tive content.

How do Ad-​Blockers Work?

In order to under­stand how to detect ad-​blockers, it’s use­ful to under­stand how ad-​blockers them­selves work.

A dis­claimer: I’ve had no per­sonal involve­ment in build­ing or main­tain­ing ad-​blockers, so I can’t answer this with one hun­dred per­cent cer­tainty, or describe the approach taken by all the var­i­ous ad-​blockers out there. Nor will I cover more com­plex ad-​blocking, such as pre­vent­ing online videos from show­ing adver­tise­ments. How­ever, after a lit­tle dig­ging I can describe the approach used by the hugely pop­u­lar AdBlock plugin.

One approach to ad-​blocking is to dynam­i­cally inject a CSS rule which matches ele­ments known or thought to con­tain adverts, and hides them. Sim­ple, really.

How to Ad-​Blocker Detec­tors Work?

In this arti­cle I’m going to be using a library, so let’s look at how that works — there may well be other approaches.

What this library in par­tic­u­lar does is dynam­i­cally inject a <div> into the page as “bait”. It assigns a bunch of classes designed to make ad-​blockers think that it con­tains adverts.

Once the bait is laid, so to speak, the library sim­ply waits to see what hap­pens to it. Specif­i­cally, it uses window.getComputedStyle() to deter­mine whether it’s been hid­den. If it has, then chances are an ad-​blocker is being used. Pretty sim­ple, in essence — although it’s prob­a­bly fair to say that it’s nei­ther fool-​proof nor future-​proof.

For ref­er­ence, here are the default classes for the library I’m using:

// CSS class used by the bait caught AdBlock
baitClass: 'pub_300x250 pub_300x250m pub_728x90 text-ad textAd text_ad text_ads text-ads text-ad-links'

Now that we under­stand how it works, we can start look­ing at the implementation.

Imple­ment­ing Ad-​Block Detection

Im going to demon­strate how to do this using a library named Block­Ad­Block. It’s actu­ally a clone of a library with a slightly more “colour­ful” name.

Instal­la­tion is sim­ple — if you’re using Bower:

bower install blockadblock --save

Alter­na­tively, sim­ply clone or down­load it from Github.

You’ll need to include the script in your build, or ref­er­ence it directly, for example:

<script src="/bower_components/blockadblock/blockadblock.js"></script>

The library offers a cou­ple of alter­na­tive approaches to detect­ing ad-​blockers; let’s look at the simplest.

It exposes an object which imple­ments two event han­dlers — onDetected() and onNotDetected(). Each takes a func­tion (anony­mous or oth­er­wise) as a parameter.

Let’s build an exam­ple page to show the plu­gin in action. We’ll incor­po­rate a cou­ple of areas designed to con­tain adver­tise­ments, and we’ll imple­ment two “responses” to dis­cov­er­ing that the vis­i­tor has an ad-​blocker:

  1. We’ll include a hid­den mes­sage at the top of the screen, which we’ll show appropriately.
  2. We’ll inject a mes­sage into one of the areas set aside for advertisements.

Here’s some sim­ple HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Ad-blocker Detection Demo</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

  </head>

  <body>

    <div class="container">

      <div class="adblock-nag alert alert-info" role="alert" style="display:none;">
        <p>It looks like you're using an ad-blocker.</p>
      </div>

      <div class="pub_728x90">
        <div class="well">
          <p>This is a banner advert.</p>
        </div>
      </div>

      <header>
        <h1>Ad-blocker Detection Demo</h1>
        <p class="lead">This simple demo demonstrates how you might detect ad-blocks, displaying a message for example.</p>
      </header>

      <div class="row">

        <main class="col-md-9">
          <p>This is the main content area. There is an area above the header for banner adverts, as well as a right-hand column (or below on small screens) also designed to display adverts.</p>
        </main>

        <aside class="col-md-3">
          <div class="ad-right">
            <div class="well">
              <p>This is an area which contains adverts.</p>
            </div>
          </div>
        </main>

      </div>

    </div><!-- /.container -->

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="/bower_components/blockadblock/blockadblock.js"></script>

    <!-- The ad-block detection code will go here -->

  </body>
</html>

There are a cou­ple of things to notice here.

The region designed to hold a “ban­ner” image has the class .pub_728x90. This is one of a num­ber of class names used by the plu­gin to iden­tify an area likely to con­tain advertisements.

Like­wise, we’ve cre­ated a region in the side­bar with the class .ad-right.

Near the top of the page, the <div> with the class .adblock-nag, explic­itly defined to be hid­den, is our “nag” mes­sage which we’ll show if an ad-​blocker is enabled.

With that in mind, let’s imple­ment the detec­tion process.

For the pur­poses of this demon­stra­tion, I’m going to put the code inline in the HTML, but nat­u­rally you can put it in an exter­nal JavaScript fie if you prefer.

Let’s start by defin­ing a func­tion for when an ad-​blocker is not detected:

// Function called if AdBlock is not detected
function adBlockNotDetected() {
  console.log( 'AdBlock is not enabled' );
}

In prac­tice, this is prob­a­bly redun­dant, although you may find a use for it — col­lect­ing met­rics, for example.

Now, a func­tion designed to be run if an ad-​blocker is detected:

// Function called if AdBlock is detected
function adBlockDetected() {

  $( '.adblock-nag' ).slideDown( 'slow' );

  $( '<div>' )
    .html(' <p>Please support us by turning off your ad blocker' )
    .addClass( 'alert' )
    .addClass( 'alert-info' )
    .insertBefore('.ad-right');

}

As you can see, the first part shows our hid­den “nag” mes­sage. The sec­ond injects con­tent dynam­i­cally into our side­bar adver­tise­ment region. It’s impor­tant to note that I’m inject­ing the mes­sage into the col­umn rather than into the area set aside for adver­tise­ments. If you try to inject con­tent into the lat­ter, chances are it’ll remain hid­den by the ad-​blocker. As such, I’m using insertBefore() to tar­get the area above the advertisements.

Finally, we need to con­fig­ure the event handlers.

The first thing to note is that accord­ing to the doc­u­men­ta­tion, it’s pos­si­ble that an ad-​blocker may block the ad-​block detec­tion library, either now or in the future. In order to get around this, we’ll first check if the exposed object is unde­fined. Oth­er­wise we sim­ply use the onDetected() and onNotDetected() meth­ods to attach our event handlers.

if ( typeof blockAdBlock === 'undefined' ) {

  adBlockDetected();

} else {

  blockAdBlock.onDetected( adBlockDetected );
  blockAdBlock.onNotDetected( adBlockNotDetected );          

}

Sim­ple as that.

Note that although we’re using JQuery in this exam­ple to manip­u­late the DOM, the library itself does not require it.

There are addi­tional options, which you can find out about by brows­ing the plu­gin doc­u­men­ta­tion.

The code from this post is avail­able on Github. There is also an online demo.

Comments

No comments yet.

Links and images are allowed, but please note that rel="nofollow" will be automactically appended to any links.