Ad-Blocker Resistance
The gated content overlay is designed to resist removal by ad blockers like uBlock Origin and AdBlock Plus. Here's how it works and what you can do to strengthen it.
How ad blockers work
Ad blockers operate at three levels:
- CSS filter rules — Inject CSS to hide elements matching known selectors (e.g.,
.paywall-overlay { display: none }) - Element hiding — Hide entire elements by tag name or attribute
- Script blocking — Block JavaScript files by URL pattern
Built-in defenses
Randomized class names
Every page load generates a unique random prefix for all gated content CSS classes (e.g., _f3x9a_overlay,
_k7m2p_panel). Since the class names are different on every page load, ad blockers cannot add them to static filter
lists.
The styles are injected as a <style> tag in <head> with these randomized selectors. The SDK monitors the tag and
re-injects it if removed.
Non-identifiable naming
- No words like
paywall,gate,wall,overlay,modal,popup,banner,ad,subscribe, orpremiumappear in the generated class names - CSS custom properties use the
--fanid-gate-*namespace which is not in any ad-blocker filter list
Integrity verification
The SDK monitors gated elements with a MutationObserver and periodic checks. If the overlay is removed by a browser
extension, it is re-applied within 3 seconds. The injected <style> tag is also monitored and re-injected if removed.
Best practices
Self-host the script
When loaded from a third-party CDN, ad blockers can identify and block the script by URL pattern. Self-hosting eliminates this:
- Download
fan-id-widget.iife.jsandwidget.css - Rename them if desired (e.g.,
auth.js,auth.css) - Serve from your own domain alongside your other assets
<script src="/assets/js/auth.js"></script>
<link rel="stylesheet" href="/assets/css/auth.css" />
Bundle via npm
Even stronger — install via npm and bundle the widget into your application's JavaScript:
npm install @wmt-fanid/widget
import FanIDWidget from '@wmt-fanid/widget'
The widget code becomes part of your application bundle. Ad blockers cannot distinguish it from your first-party code without blocking your entire application.
Use a custom element name
If the default wmt-fanid-protected tag is ever added to a filter list:
FanIDWidget.init({
baseUrl: 'https://your-org.fanid.co',
gatedContent: {
customElementName: 'my-premium-section'
}
})
Each site can use a unique tag name that will never appear in any shared filter list.
Limitations
Gated content is a visual deterrent, not a security boundary. A determined user with browser DevTools can always inspect the DOM and read the source content. This is acceptable — the same model is used by Medium, LinkedIn, and major news paywalls.