How to detect Adblock on my website?

My solution is not specific to a certain ad network and is very lightweight. I've been running it in production for a few years. AdBlock blocks all URLs containing the word "ads" or "prebid". So this is what I did:

I added a small js file to my webroot with the name prebid-ads.js

This is the only line of code in that file. Update 2022-04-26 Call this variable something else, see below!

var canRunAds = true;

Then somewhere in your page:

<html>
  <head>
    <script src="/js/prebid-ads.js"></script>
  </head>
  <body>
    <script>
      if( window.canRunAds === undefined ){
        // adblocker detected, show fallback
        showFallbackImage();
      }
    </script>
  </body>
</html>

Update 2022-04-26 uBlock Origin loads their own ads-prebid.js that reverts the trick described in this answer (proud!), their file contains the following:

(function() {
    'use strict';
    window.canRunAds = true;
    window.isAdBlockActive = false;
})();

As a solution just rename your canRunAds variable to something fun, like window.adsAreWithUs or window.moneyAbovePrivacy.

Discovery and workaround by Ans de Nijs. Thanks!

Supporting extensions

Files like ads.js are blocked by at least these adblockers on Chrome:

  • AdBlock
  • Adblock Plus
  • Adblock Pro
  • Ghostery

Does not work with:

Privacy Badger


http://thepcspy.com/read/how_to_block_adblock/

With jQuery:

function blockAdblockUser() {
    if ($('.myTestAd').height() == 0) {
        window.location = 'http://example.com/AdblockNotice.html';
    }
}

$(document).ready(function(){
    blockAdblockUser();
});

Of course, you would need to have a landing page for AdblockNotice.html, and the .myTestAd class needs to reflect your actual ad containers. But this should work.

EDIT

As TD_Nijboer recommends, a better way is to use the :hidden (or :visible, as I use below) selector so that display: none is also checked:

function blockAdblockUser() {
    if ($('.myTestAd').filter(':visible').length == 0) {
        // All are hidden, or "not visible", so:
        // Redirect, show dialog, do something...
    } else if ($('.myTestAd').filter(':hidden').length > 0) {
        // Maybe a different error if only some are hidden?
        // Redirect, show dialog, do something...
    }
}

Of course, both of these could be combined into one if block if desired.

Note that visibility: hidden will not be captured by either as well (where the layout space stays, but the ad is not visible). To check that, another filter can be used:

$('.myTestAd').filter(function fi(){
    return $(this).css('visibility') == 'hidden';
})

Which will give you an array of ad elements which are "invisible" (with any being greater than 0 being a problem, in theory).


Not a direct answer, but I'd put the message behind the ad to be loaded... rather that trying to detect it, it'd just show up when the ad doesn't.


async function detectAdBlock() {
  let adBlockEnabled = false
  const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'
  try {
    await fetch(new Request(googleAdUrl)).catch(_ => adBlockEnabled = true)
  } catch (e) {
    adBlockEnabled = true
  } finally {
    console.log(`AdBlock Enabled: ${adBlockEnabled}`)
  }
}
detectAdBlock()