I have reviewed the following documentation in the AdGuard public Knowledge Base: https://adguard.com/kb
- Types of filtering rules – How ad blocking works
- AdGuard filter policy | AdGuard Knowledge Base
- How to create your own ad filters | AdGuard Knowledge Base
I have not yet reviewed the AdGuard DNS KB. However, I previously attempted to contribute to the List-KR repository by blocking KakaoTalk in-app advertising domains:
annoyance: com.kakao.talk by mu-hun · Pull Request #1019 · List-KR
Among the Types of filtering rules, the "HTML filtering rules" section is said to be limited depending on the platform:
These rules are quite complicated and require the ad blocker to be granted certain access rights, so not all platforms support them. Currently, these rules work only in the AdGuard Firefox add-on and in the AdGuard apps for Windows, Mac, and Android.
I was curious about how these rules are used in practice, so I looked for an example from the AdGuard filters repositories:
(Reference example inspired by rules used in the AdGuard Filters repositories on GitHub.)
Example of an HTML filtering rule used in production filters:
example.com$$script[tag-content="adblock"][max-length="20000"]What this rule does
- Targets pages on
example.com. - Scans the raw HTML response before the browser parses it.
- Removes inline
<script>elements containing the textadblockwhen they match the specified conditions.
Why HTML filtering is needed here
In some cases, websites embed anti-adblock logic directly inside large inline scripts within the HTML document:
<script>
if (window.adblockDetected) {
document.body.innerHTML = 'Please disable your ad blocker'
}
</script>This script cannot be blocked with a normal network rule because it is not loaded from a separate URL. A cosmetic rule would also be unreliable, since the script executes immediately while the page is being parsed.
Using an HTML filtering rule removes the problematic script before it is parsed and executed by the browser, preventing the anti‑adblock logic from running.
This is why HTML filtering rules are generally treated as a last‑resort technique and used only when blocking requests or cosmetic filtering cannot solve the problem.
For this reason, HTML filtering rules are typically used only when the problem cannot be solved with network or cosmetic filtering.
Three main rules: Basic (network) rules, Cosmetic rules, and HTML filtering rules.
| Category | Basic rules (Network filtering) | Cosmetic rules (Element hiding) | HTML filtering rules |
|---|---|---|---|
| Primary purpose | Block requests to ads, trackers, or unwanted resources | Hide or remove visible page elements after the page loads | Remove or rewrite parts of the HTML document before it is parsed |
| Execution stage | Before resource download | After DOM is created | Before HTML is parsed and executed |
| What it operates on | Network requests (URLs) | DOM elements rendered in the page | Raw HTML response body |
| Typical syntax | /ads.js |
##.ads |
example.com#$#remove(".ads"), example.com$$script[tag-content="ad"] |
| Typical use cases | Blocking ad scripts, trackers, ad images, analytics | Hiding banners, sponsored blocks, cookie notices | Removing inline scripts, anti-adblock logic, injected paywalls |
| Performance impact | Very low (fastest method) | Low | Higher (requires HTML scanning/modification) |
| Platform support | All AdGuard products | All AdGuard products | Limited platforms only |
| Reliability | Highly reliable if the request URL is identifiable | Works well for static page elements | Useful for complex inline logic that other rules cannot stop |
| Preferred usage order | 1st choice | 2nd choice | Last resort |
This table reflects how filter maintainers typically think about them when deciding which mechanism to use.
I watched the AGLint v4 presentation at last month. It introduced Scriptlets and showed examples of the AutoFix and Suggestion features.
example.com#%$//scriptlet('abort-on-property-read' 'alert')Stops a script on example.com if it attempts to access the alert browser API.
#$#.foo { padding: 1px; padding 1px; }In this case, AGLint can automatically remove one of the duplicated declarations (AutoFix).
#$#.foo { padding: 1px; padding 1px; }If it is unclear which declaration should be kept, AGLint provides suggestions instead of applying an automatic fix.