Since I primarily maintain projects with ads-related domains, I noticed that the previous methods for detecting AdBlock/AdBlock Plus activation have stopped working. I spent time researching and testing various approaches. Here's a summary of my findings.
Deprecated Legacy Method
// Define a function to detect AdBlock function checkAdBlock() { // Request a path likely to be blocked by AdBlock (contains /ad) fetch('xxxx/xxxx/ad') .then(response => { if (!response.ok) { // If the response status is not 2xx, it might be blocked console.log('AdBlock may be enabled - request intercepted'); } else { // Request succeeded, AdBlock not active console.log('AdBlock not enabled - request succeeded'); } }) .catch(error => { // Request failed, possibly blocked console.log('AdBlock may be enabled - request failed', error); }); } // Execute the detection checkAdBlock();
Attempted Method 1 (All Tested Ineffective)
Tried multiple open-source solutions from GitHub, all failed:
1,f**kAdblock
...
Attempted Method 2 (Also Ineffective)
Created a DOM element with AdBlock-targeted class names:
// Create a test element with AdBlock-sensitive classes var adTest = document.createElement('div'); adTest.className = 'ad ads ad-test1 adblock-test'; // Common blocked class names adTest.style.display = 'block'; // Explicitly set display adTest.style.position = 'absolute'; // Position outside viewport adTest.style.top = '-9999px'; adTest.style.left = '-9999px'; adTest.style.width = '1px'; adTest.style.height = '1px'; // Add to DOM document.body.appendChild(adTest); // Check if element is hidden var adblockActive = (adTest.offsetWidth <= 0 && adTest.offsetHeight <= 0) || adTest.style.display === 'none'; if (adblockActive) { console.log('AdBlock detected'); } else { console.log('AdBlock not detected'); document.body.removeChild(adTest); // Optional cleanup }
Key Insight
After reviewing AdBlock Plus documentation, I discovered they use EasyList as their default filter rules. EasyList is a community-maintained open-source filter list targeting ads and trackers.
Understanding EasyList Rules
Example rules from EasyList:
! *** easylist:easylist/easylist_general_block.txt *** -ad-manager/$~stylesheet -ad-sidebar.$image .ads.controller.js$script ...
-
-ad-manager/$~stylesheet
* Blocks resources containing -ad-manager/ in their paths, excluding stylesheets. * Example: https://example.com/ad-manager/script.js blocked, but https://example.com/ad-manager/style.css allowed.
-
-ad-sidebar.$image
* Blocks images containing -ad-sidebar in their paths.
-
.ads.controller.js$script
- Blocks scripts with .ads.controller.js in their paths.
Validation Tests
Test 1: Blocking -ad-manager/ Path (Verified ✅)
var script = document.createElement('script'); script.src = './a-ad-manager/script.js'; // Test path script.onload = () => console.log('Script loaded'); script.onerror = () => console.log('Script blocked by AdBlock'); // Successfully blocked document.head.appendChild(script);
Test 2: Blocking .ads.controller.js (Verified ✅)
var script = document.createElement('script'); script.src = './test.ads.controller.js'; // Test path script.onload = () => console.log('Script loaded'); script.onerror = () => console.log('Script blocked by AdBlock'); // Successfully blocked document.head.appendChild(script);
Conclusion
By reverse-engineering EasyList's default blocking rules, we can reliably detect AdBlock/AdBlock Plus by attempting to load resources matching these patterns. Monitoring the success/failure of these requests provides an effective detection mechanism. Future-proof implementations should periodically review EasyList updates and adapt to new patterns.
Top comments (0)