A filter is a set of filtering rules applied to specific content, such as banners or pop-ups. Our standard filters are created by our team; we constantly improve and update them, and we hope that our filters meet the needs of most of our users.
At the same time, AdGuard allows you to create your own custom filters using the same types of rules that we have in our filters.
To describe the syntax of our filtering rules, we use Augmented BNF for Syntax Specifications, but we do not always strictly follow this specification.
Originally, the AdGuard's syntax was based on the syntax of Adblock Plus rules. Later, we extended it with new types of rules for better ad filtering. Some parts of this article about the rules common to both AdGuard and ABP were taken from this article.
Any line that starts with an exclamation mark is a comment. In the list of rules it is displayed in gray color. AdGuard will ignore this line, so you can write anything you want. Comments are usually placed above the rules and used to describe what a rule does.
For example:
! This is the comment. Under this line there is an actual filtering rule.
||example.org^
This rule blocks:
http://example.org/ad1.gifhttp://subdomain.example.org/ad1.gifhttps://ads.example.org:8000/This rule does not block:
http://ads.example.org.us/ad1.gifhttp://example.com/redirect/http://ads.example.org/This rule blocks:
http://example.org/This rule does not block:
https://example.org/banner/imgFiltering rules support numerous modifiers that allow you to fine-tune the rule behavior. Here is an example of a rule with some simple modifiers.
This rule blocks:
http://example.org/script.js if this script is loaded from example.com.This rule does not block:
https://example.org/script.js if this script is loaded from example.org.https://example.org/banner.png because it is not a script.This rule unblocks:
http://example.org/banner.png even if there is a blocking rule for this address.Blocking rules with
$importantmodifier can override exceptions.
This rule unblocks
example.com.Cosmetic rules are based on using a special language named CSS, which every browser understands. Basically, it adds a new CSS style to the website which purpose is to hide particular elements. You can learn more about CSS in general here.
AdGuard extends CSS and lets filters developers handle much more complicated cases. However, to use these extended rules, you need to be fluent in regular CSS.
| Name | CSS selector | Description |
|---|---|---|
| ID selector | #banners |
Matches all elements with id attribute equal to banners.![]() |
| Class selector | .banners |
Matches all elements with class attribute containing banners.![]() |
| Attribute selector | div[class="banners"] |
Matches all div elements with class attribute exactly equal to banners.![]() |
| Attribute substring selector | div[class^="advert1"] |
Matches all div elements which class attribute starts with the advert1 string.![]() |
| Attribute substring selector | div[class$="banners_ads"] |
Matches all div elements which class attribute ends with the banners_ads string.![]() |
| Attribute substring selector | a[href^="http://example.com/"] |
Matches all links that are loaded from http://example.com/ domain.![]() |
| Attribute selector | a[href="http://example.com/"] |
Matches all links to exactly the http://example.com/ address.![]() |
The most simple rules are so-called "Basic rules". They are used to block requests to specific URLs. Or to unblock it, if there is a special marker "@@" at the beginning of the rule. The basic principle for this type of rules is quite simple: you have to specify the address and additional parameters that limit or expand the scope of the rule.
Sub-requests
Basic rules for blocking requests are applied only to sub-requests. That means they will not block the loading of the page.
Response status
Browser detects a blocked request as completed with an error.
rule = ["@@"] pattern [ "$" modifiers ]
modifiers = [modifier0, modifier1[, ...[, modifierN]]]
pattern — address mask. Every request's URL is collated to this mask. You can also use special characters in the template, their description is below. Note that AdGuard trims URLs to a length of 4096 characters in order to speed up matching and avoid issues with ridiculously long URLs.@@ — A marker that is used in rules of exception. To turn off filtering for a request, start your rule with this marker.modifiers — Parameters that "clarify" the basic rule. Some of them limit the scope of the rule and some can completely change they way it works.* — Wildcard character. It is used to represent "any set of characters". This can also be an empty string or a string of any length.|| — Matching the beginning of an address. With this character you don't have to specify a particular protocol and subdomain in address mask. It means, || stands for http://*., https://*., ws://*., wss://*. at once.^ — Separator character mark. Separator character is any character, but a letter, a digit, or one of the following: _ - . %. In this example separator characters are shown in bold: http://example.com/?t=1&t2=t3. The end of the address is also accepted as separator.| — A pointer to the beginning or the end of address. The value depends on the character placement in the mask. For example, a rule swf| corresponds to http://example.com/annoyingflash.swf , but not to http://example.com/swf/index.html. |http://example.org corresponds to http://example.org, but not to http://domain.com?url=http://example.org.Visual representation. We also recommend to get acquainted with this article, for better understanding of how such rules should be made.
If you want even more flexibility in making rules, you can use Regular expressions instead of a default simplified mask with special characters.
Performance. Rules with regular expressions work more slowly, therefore it is recommended to avoid them or to limit their scope to specific domains.
If you want a blocker to determine a regular expression, the pattern has to look like this:
pattern = "/" regexp "/"
For example, /banner\d+/$third-party this rule will apply the regular expression banner\d+ to all third-party requests. Exclusion rule with regular expression looks like this: @@/banner\d+/.
Compatibility with different versions of AdGuard. AdGuard browser extension for Safari and AdGuard for iOS do not fully support regular expressions because of Content Blocking API restrictions (look for "The Regular expression format" section).
Wildcard characters are supported for TLDs of the domains in patterns of cosmetic, html and javascript rules.
For example, the cosmetic rule example.*##.banner will match any example.TLD request (example.ru, example.com, example.net, example.org, etc.).
For the basic rules the described logic will be applicable only for the domains specified in $domain modifier (for example, ||*/banners/*$image,domain=example.*).
Compatibility with different versions of AdGuard. Supported by: AdGuard for Windows/macOS/Android/Safari/iOS and browser extensions for Chrome/Firefox/Edge.
||example.com/ads/* — a simple rule, which corresponds to addresses like http://example.com/ads/banner.jpg and even http://subdomain.example.com/ads/otherbanner.jpg.
||example.org^$third-party — this rule blocks third-party requests to example.org and its subdomains.
@@||example.com$document — general exception rule. It completely disables filtering for example.com and all subdomains. There is a number of modifiers which can be used in exception rules. For more details, please follow the link below.
Attention! The features described in this section are intended for experienced users. They extend capabilities of "Basic rules", but in order to use them you need to have a basic understanding of the way your browser works.
You can change the behavior of a "basic rule" by using additional modifiers. Modifiers should be located in the end of the rule after a $ sign and be separated by commas.
Example:
||domain.com^$popup,third-party
The following modifiers are the most simple and frequently used.
domaindomain limits the rule application area to a list of domains (and their subdomains). To add multiple domains to one rule, use the | character as a separator.
domain examples||baddomain.com^$domain=example.org — a rule to block requests that match the specified mask, and are sent from domain example.org or its subdomains.||baddomain.com^$domain=example.org|example.com — the same rule, but it works for both example.org and example.com.If you want the rule not to be applied to certain domains, start a domain name with ~ sign.
domain and ~ examples||baddomain.com^$domain=~example.org — this rule blocks requests matching the pattern sent from any domain except example.org and its subdomains.||baddomain.com^$domain=example.org|~foo.example.org — this rule blocks requests sent from example.org and its subdomains, except the subdomain foo.example.org.domain modifier matching target domainIn some cases the $domain modifier can match not only the referrer domain, but also the target domain. This happens when all of the following is true:
1) The request has document type
2) The rule's pattern doesn't match any particular domain(s)
3) The rule's pattern doesn't contain regular expressions
4) The $domain modifier contains only excluded domains (e.g., $domain=~example.org|~example.com)
The following predicate should be satisfied to perform a target domain matching: 1 AND ((2 AND 3) OR 4). That is, if the modifier $domain contains only excluded domains, then the rule does not need to meet the second and third conditions to match the target domain against the modifier $domain.
If some of the conditions above aren't met but the rule contains modifiers cookie or csp, the target domain will still be matched.
If the referrer matches a rule with domain that explicitly excludes the referrer domain, then the rule won't be applied even if the target domain also matches the rule. This affects rules with cookie and csp modifiers, too.
Examples:
*$cookie,domain=example.org|example.com will block cookies for all requests to and from example.org and example.com.*$document,domain=example.org|example.com will block all requests to and from example.org and example.com.In the following examples it's implied that requests are sent from http://example.org/page(the referrer) and the target URL is http://targetdomain.com/page.
page$domain=example.org will be matched, as it matches the referrer domain.page$domain=targetdomain.com will be matched, as it matches the target domain but satisfies all requirements mentioned above.||*page$domain=targetdomain.com will not be matched, as the pattern ||*page matches specific domains.||*page$domain=targetdomain.com,cookie will be matched despite the pattern ||*page matches specific domains because it contains $cookie modifier./banner\d+/$domain=targetdomain.com will not be matched as it contains a regular expression.page$domain=targetdomain.com|~example.org will not be matched because the referrer domain is explicitly excluded.Important! Safari doesn't support the simultaneous use of allowed and disallowed domains, so rules like
||baddomain.com^$domain=example.org|~foo.example.orgwill not work in AdGuard for Safari.
third-partyA restriction of third-party and own requests. A third-party request is a request from a different domain. For example, a request to example.org, from domain.com is a third-party request.
To be considered as such, a third-party request should meet one of the following conditions:
1) Its referrer is not a subdomain of the target domain or the other way round. For example, a request tosubdomain.example.orgfromexample.orgis not a third-party request.
2) ItsSec-Fetch-Siteheader is set tocross-site.
If there is a third-party modifier, the rule is only applied to third-party requests.
third-party examples||domain.com^$third-party — this rule applies to all domains, except domain.com and its subdomains. A third-party request example: http://example.org/banner.jpg.If there is a ~third-party modifier, the rule is only applied to the requests that are not from third-party. Which means, they have to be sent from the same domain.
~third-party examples||domain.com$~third-party — this rule is applied to domain.com, but not to the other domains. Example of a request that is not a third-party request: http://domain.com/icon.ico.popupAdGuard will try to close the browser tab with any address that matches a blocking rule with this modifier. Please note that not all the tabs can be closed.
popupexamples||domain.com^$popup — if you try to go to http://domain.com/ from any page in the browser, a new tab in which specified site has to be opened will be closed by this rule.It may not work if the popped up page is cached by the browser. It also will not work with some tricky popup methods. In such cases, it is better to use AdGuard Popup Blocker extension.
Important! Unlike with browser extensions,
$popupmodifier is very unreliable when used with AdGuard apps for Windows, Mac and Android. In AdGuard for Safari and iOS,$popuprules will simply block the page right away.
match-caseThis modifier defines a rule which applies only to addresses that match the case. Default rules are case-insensitive.
match-case examples*/BannerAd.gif$match-case — this rule will block http://example.com/BannerAd.gif, but not http://example.com/bannerad.gif.There is a set of modifiers, which can be used to limit the rule's application area to certain type of content. These modifiers can also be combined to cover, for example, both images and scripts.
Compatibility with different versions of AdGuard. Please note that there is a big difference in how AdGuard determines the content type on different platforms. For browser extensions, content type for every request is provided by browser. AdGuard for Windows, Mac and Android use following method: first we try to determine the type of the request by the
Sec-Fetch-Destrequest header or by the filename extension. If the request is not blocked at this stage, the type will be determined using theContent-Typeheader at the beginning of the server response.
||example.org^$image — corresponds to all images from example.org.||example.org^$script,stylesheet — corresponds to all the scripts and styles from example.org.||example.org^$~image,~script,~stylesheet — corresponds to all requests to example.org except for the images, scripts and styles.documentThe rule corresponds to the main frame document requests, i.e. HTML documents that are loaded in the browser tab. It does not match iframes (there's a $subdocument modifier for these).
By default, AdGuard won't block the requests that are loaded in the browser tab (e.g. "main frame bypass"). The idea is not to prevent pages from loading as the user clearly indicated that they want this page to be loaded. However, if the $document modifier is specified explicitly, AdGuard does not use that logic and prevents the page load. Instead, it responds with a "blocking page".
If this modifier is used with an exclusion rule (@@), it completely disables blocking on corresponding pages. It is equivalent to using $elemhide, $content, $urlblock, $jsinject, and $extension modifiers simultaneously.
Compatibility with different versions of AdGuard. Blocking request type logic now only supported by dev-build of AdGuard.
document example@@||example.com^$document — completely disables filtering on all pages at example.com and all subdomains.
@@||example.com^$document,~extension — completely disables blocking on any pages at example.com and all subdomains, but continues to run userscripts there.
||example.com^$document — blocks HTML document request to example.com with a blocking page.
||example.com^$document,redirect=noopframe — redirects HTML document request to example.com to an empty html document.
||example.com^$document,removeparam=test — removes test query parameter from HTML document request to example.com.
||example.com^$document,replace=/test1/test2/ — replaces test1 with test2 in HTML document request to example.com.
imageThe rule corresponds to images requests.
stylesheetThe rule corresponds to CSS files requests.
scriptThe rule corresponds to script requests (e.g. javascript, vbscript).
objectThe rule corresponds to browser plugins resources. (e.g. Java or Flash).
object-subrequestThe rule corresponds to requests by browser plugins (it's usually Flash).
Compatibility with different versions of AdGuard. AdGuard for Windows, macOS and Android often can't accurately detect this type and defines it as
other.
fontThe rule corresponds to requests for fonts (e.g. .woff filename extension).
mediaThe rule corresponds to requests for media files (music and video, e.g. .mp4 files).
subdocumentThe rule corresponds to requests for built-in pages (HTML tags frame and iframe).
pingThe rule corresponds to requests caused by either navigator.sendBeacon() or the ping attribute on links.
Compatibility with different versions of AdGuard. AdGuard for Windows, macOS and Android often can't accurately detect
navigator.sendBeacon(). For reliable detection, use AdGuard browser extensions.
xmlhttprequestThe rule applies only to ajax requests (requests sent via javascript object XMLHttpRequest).
Compatibility with different versions of AdGuard. AdGuard for Windows, macOS and Android often can't accurately detect this type and sometimes detects it as
otherorscript.
websocketThe rule applies only to WebSocket connections.
Compatibility with different versions of AdGuard. AdGuard for Safari and iOS cannot properly apply this modifier due to Safari limitations.
webrtcThe rule applies only to WebRTC connections.
Please note that blocking WebRTC can interfere with the work of some browser applications, such as messengers, chats, cinemas, or games.
webrtc example||example.com^$webrtc,domain=example.org - this rule blocks webRTC connections to example.com for example.org.@@*$webrtc,domain=example.org - this rule disables the RTC wrapper for example.org.Deprecation notice. This modifier is deprecated and will be removed in the future. If you need to suppress WebRTC, consider using the
$nowebrtcscriptlet.
otherThe rule applies to requests for which the type has not been determined or doesn't match the types listed above.
Exception rules disable the other basic rules for the addresses to which they correspond. They begin with a @@ mark. All the basic modifiers listed above can be applied to them and they also have a few special modifiers.
Visual representation. We recommend to get acquainted with this article, for better understanding of how exception rules should be made.
elemhideDisables any cosmetic rules on the pages matching the rule. You will find the information about cosmetic rules further.
elemhide example@@||example.com^$elemhide — disables all cosmetic rules on pages at example.com and all subdomains.contentDisables HTML filtering rules and replace rules on the pages that match the rule. You will find the information about HTML filtering rules here and about replace rules here.
content example@@||example.com^$content — disables all HTML filtering rules on pages at example.com and all subdomains.jsinjectForbids adding of javascript code to the page. You can read about javascript rules further.
jsinject example@@||example.com^$jsinject — disables javascript on pages at example.com and all subdomains.urlblockDisables blocking of all requests sent from the pages matching the rule.
urlblock example@@||example.com^$urlblock — any requests sent from the pages at example.com and all subdomains are not going to be blocked.extensionDisables all userscripts on the pages matching this rule. Note, that this modifier only makes sense in AdGuard products that can work as userscript hosts (AdGuard for Windows/macOS/Android).
extension example@@||example.com^$extension — userscripts won't work on all pages of the example.com website.stealthDisables the Stealth Mode module for all corresponding pages and requests.
stealth examples@@||example.com^$stealth — disables Stealth Mode for example.com (and subdomains) requests, except for blocking cookies and hiding tracking parameters (see below).@@||domain.com^$script,stealth,domain=example.com — disables Stealth Mode only for script requests to domain.com (and its subdomains) on example.com and all its subdomains.$cookie and $removeparam modifiers. Exceptions with only $stealth modifier won't do those things. If you want to completely disable all Stealth Mode features for a given URL, you need to include all three modifiers: @@||example.org^$stealth,removeparam,cookieCompatibility with different versions of AdGuard. Stealth Mode is currently available in AdGuard for Windows, Mac, Android and AdGuard browser extensions for Chrome, Firefox, Edge. For now, the products that do not support Stealth Mode will ignore the rules with this modifier.
Before we can proceed to the next modifiers, we have to make a definition of generic rules. The rule is generic if it is not limited to specific domains.
Wildcard character * is supported as well.
For example, these rules are generic:
###banner
*###banner
#@#.adsblock
*#@#.adsblock
~domain.com###banner
||domain.com^
||domain.com^$domain=~example.com
And these are not:
domain.com###banner
||domain.com^$domain=example.com
generichideDisables all generic cosmetic rules on pages that correspond to exception rule.
@@||example.com^generichide — disables generic cosmetic rules on any pages at example.com and all subdomains.genericblockDisables generic basic rules on pages that correspond to exception rule.
@@||example.com^$genericblock — disables generic basic rules on any pages at example.com and all subdomains.specifichideHas an opposite effect to generichide. Disables all specific element hiding and CSS rules, but not general ones.
@@||example.org^$specifichide — will disable example.org##.banner but not ##.banner.Please note that
$elemhidemodifier can disable all cosmetic rules at once.Compatibility with different versions of AdGuard. Rules with this modifier are supported by AdGuard for Windows, Mac, Android, and AdGuard browser extensions for Chrome, Firefox, Edge. Developer builds only at this moment.
These modifiers are able to completely change the behaviour of basic rules.
removeparam
$querypruneis an alias of$removeparam. Since$querypruneis deprecated, avoid using it and use$removeparaminstead.
Rules with $removeparam modifier are intended to to strip query parameters from requests' URLs. Please note that such rules are only applied to GET, HEAD, and OPTIONS requests.
$removeparamrules that do not have any content-type modifiers will match only requests where content type isdocument.
$removeparam=param -- removes query parameter with the name param from URLs of any request, e.g. a request to http://example.com/page?param=1&another=2 will be transformed to http://example.com/page?another=2.
$removeparambasic syntax is supported starting with v1.7 of CoreLibs and v3.6 of AdGuard Browser Extension.
You can also use regular expressions to match query parameters and/or their values:
$removeparam=/regex/[options] -- removes query parameters matching the regex regular expression from URLs of any request. Unlike basic syntax, it means "remove query parameters normalized to a name=value string which match the regex regular expression". [options] here is the list of regular expression options. At the moment, the only supported option is i which makes matching case-insensitive.
$removeparamsyntax for regular expressions will be supported starting with v1.8 of CoreLibs and v4.0 of AdGuard Browser Extension. For now, use the simplified version:$removeparam=param.Escaping special characters: don't forget to escape special characters like
,,/and$in the regular expressions. Use\character for that purpose. For example, an escaped comma should look like this:\,.Important: note that regex-type rules target both parameter's name and value. In order to minimize the chance of mistakes, it is safer to start every regex with
/^unless you specifically target parameter values.We will try to detect and ignore unescaped
$automatically using a simple rule of thumb:
It is not an options delimiter if all three are true:
- It looks like
$/,- There's another slash character (
/) to the left of it,- There's another unescaped
$character to the left of that slash character.
Specify naked $removeparam to remove all query parameters:
||example.org^$removeparam -- removes all query parameters from URLs matching ||example.org^.Use ~ to apply inversion:
$removeparam=~param -- removes all query parameters with the name different from param.$removeparam=~/regex/ -- removes all query parameters that do not match the regex regular expression.$removeparamThis sort of rules work pretty much the same way it works with $csp and $redirect modifiers.
Use @@ to negate $removeparam:
@@||example.org^$removeparam -- negates all $removeparam rules for URLs that match ||example.org^.@@||example.org^$removeparam=param -- negates the rule with $removeparam=param for any request matching ||example.org^.@@||example.org^$removeparam=/regex/ -- negates the rule with $removeparam=/regex/ for any request matching ||example.org^.Multiple rules matching a single request
In the case when multiple$removeparamrules match a single request, each of them will be applied one by one.
$removeparam=utm_source|utm_medium|utm_term
$removeparam=utm_content|utm_campaign|utm_referrer
@@||example.com^$removeparam
With these rules some UTM parameters will be stripped out from any request, except that requests to example.com won't be stripped at all, e.g. http://google.com/page?utm_source=s&utm_referrer=fb.com&utm_content=img will be transformed to http://google.com/page, but http://example.com/page?utm_source=s&utm_referrer=fb.com&utm_content=img won't be affected by the blocking rule.
$removeparam=utm_source -- removes utm_source query parameter from all requests.
$removeparam=/utm_.*/ -- removes all utm_* query parameters from URL queries of any request, e.g. a request to http://example.com/page?utm_source=test will be transformed to http://example.com/page.
$removeparam=/^utm_source=campaign$/ -- removes utm_source query parameter with the value equal to campaign. It does not touch other utm_source parameters.
Negating one $removeparam rule and replacing it with a different rule:
$removeparam=/^(gclid|yclid|fbclid)=/
@@||example.com^$removeparam=/^(gclid|yclid|fbclid)=/
||example.com^$removeparam=/^(yclid|fbclid)=/
With these rules, Google, Yandex, and Facebook Click IDs will be removed from all requests. There's one exception: Google Click ID (gclid) will not be removed from requests to example.com.
Negating $removeparam for all parameters:
$removeparam=/^(utm_source|utm_medium|utm_term)=/
$removeparam=/^(utm_content|utm_campaign|utm_referrer)=/
@@||example.com^$removeparam
With these rules, specified UTM parameters will be removed from any request save for requests to example.org.
Compatibility with other modifiers
$removeparamrules are compatible with basic modifiers, content-type modifiers, and with$importantand$appmodifiers. The rules which have any other modifiers are considered invalid and will be discarded.Please note that
$removeparamrules can also be disabled by$documentand$urlblockexception rules. But basic exception rules without modifiers don't do that. For example,@@||example.com^will not disable$removeparam=pfor requests to example.com, but@@||example.com^$urlblockwill.Compatibility with different versions of AdGuard. Rules with this modifier are supported by AdGuard for Windows, Mac, Android, and AdGuard browser extensions for Chrome, Firefox, Edge. Developer builds only at this moment.
Restrictions. Please note that this type of rules can be used only in trusted filters. This category includes your own User filter and all the filters created by AdGuard Team.
importantThe $important modifier applied to a rule increases its priority over any other rule without $important modifier. Even over basic exception rules.
||example.org^$important
@@||example.org^
||example.org^$important will block all requests despite of the exception rule.
||example.org^$important
@@||example.org^$important
Now the exception rule also has $important modifier so it will prevail.
The $important modifier will be ignored if a document-level exception rule is applied to the document.
||example.org^$important
@@||test.org^$document
If a request to example.org is sent from the test.org domain, the rule won't be applied despite it has the $important modifier.
badfilterThe rules with the badfilter modifier disable other basic rules to which they refer. It means that the text of the disabled rule should match the text of the badfilter rule (without the badfilter modifier).
Examples:
||example.com$badfilter disables ||example.com||example.com$image,badfilter disables ||example.com,image@@||example.com$badfilter disables @@||example.com||example.com$domain=domain.com,badfilter disables ||example.com$domain=domain.comRules with $badfilter modifier can disable other basic rules for specific domains if they fulfil the following conditions:
$domain modifier~ in $domain modifier's value.In that case, the $badfilter rule will disable the corresponding rule for domains specified in both the $badfilter and basic rules. Please note, that wildcard-TLD logic works here as well.
Examples:
/some$domain=example.com|example.org|example.io is disabled for example.com by /some$domain=example.com,badfilter/some$domain=example.com|example.org|example.io is disabled for example.com and example.org by /some$domain=example.com|example.org,badfilter/some$domain=example.com|example.org and /some$domain=example.io are disabled completely by /some$domain=example.com|example.org|example.io,badfilter/some$domain=example.com|example.org|example.io is disabled completely by /some$domain=example.*,badfilter/some$domain=example.* is disabled for example.com and example.org by /some$domain=example.com|example.org,badfilter/some$domain=example.com|example.org|example.io is NOT disabled for example.com by /some$domain=example.com|~example.org,badfilter because the value of domain modifier contains a negated domainemptyUsually, blocked requests look like a server error to browser. If you use empty modifier, AdGuard will emulate a blank response from the server with200 OK status.
empty example||example.org^$empty — returns an empty response to all requests to example.org and all subdomains.Deprecation notice. Rules with this modifier are deprecated in favor of the
$redirectmodifier. Please note that it will be removed in the future.Compatibility with different versions of AdGuard. Rules with this modifier are not supported by AdGuard for Safari and iOS.
mp4As a response to blocked request AdGuard returns a short video placeholder.
mp4 example||example.com/videos/$mp4 — block a video downloads from ||example.com/videos/* and changes the response to a video placeholder.Deprecation notice. Rules with this modifier are deprecated in favor of the
$redirectmodifier. Please note that it will be removed in the future.Compatibility with different versions of AdGuard. Rules with this modifier are not supported by AdGuard for Safari and iOS.
replaceThis modifier completely changes the rule behavior. If it is applied, the rule will not block the request. The response is going to be modified instead.
Please note
You will need some knowledge of regular expressions to use this modifier.
$replace rules features$replace rules apply to any text response, but will not apply to binary (media, image, object, etc).$replace rules do not apply if the size of the original response is more than 3MB.$replace rules have a higher priority than other basic rules (including exception rules). So if a request corresponds to two different rules one of which has the $replace modifier, this rule will be applied.$content or $document modifiers do disable $replace rules for requests matching them.$generichide, $elemhide or $jsinject modifiers) are applied alongside $replace rules. It means that you can modify the page's content with a $replace rule and disable cosmetic rules there at the same time.
$replacevalue can be empty in the case of exception rules. See examples section for further information.Multiple rules matching a single request. In case if multiple
$replacerules match a single request, we will apply each of them. The order is defined alphabetically.
In general, replace syntax is similar to replacement with regular expressions in Perl.
replace = "/" regex "/" replacement "/" modifiers
regex — regular expression.replacement — a string that will be used to replace the string corresponding to regex.modifiers — regular expression flags. For example, i - insensitive search, or s - single-line mode.In the $replace value, two characters must be escaped: comma (,) and ($). Use (\) for it. For example, an escaped comma looks like this: \,.
$replace example||example.org^$replace=/(<VAST[\s\S]*?>)[\s\S]*<\/VAST>/\$1<\/VAST>/
There are three parts in this rule:
(<VAST(.|\s)*?>)(.|\s)*<\/VAST>\$1<\/VAST> (please note that $ is escaped)i (insensitive search)You can see how this rule works here:
http://regexr.com/3cesk
$replace rules example||example.org^$replace=/X/Y/||example.org^$replace=/Z/Y/@@||example.org/page/*$replace=/Z/Y/example.org.||example.org/page/, but rule 1 still works!.$replace rules@@||example.org^$replace will disable all $replace rules matching ||example.org^.@@||example.org^$document or @@||example.org^$content will disable all $replace rules originated from pages of example.org including the page itself.Compatibility with different versions of AdGuard. These rules are supported by AdGuard for Windows, Mac, Android and by the AdGuard's Firefox add-on. This type of rules don't work in extensions for other browsers because they are unable to modify content on the network level.
Restrictions. Please note that this type of rules can be used only in trusted filters. This category includes your own User filter and all the filters created by AdGuard Team.
cspThis modifier completely changes the rule behavior. If it is applied to a rule, it will not block the matching request. The response headers are going to be modified instead.
In order to use this type of rules, it is required to have the basic understanding of the Content Security Policy security layer.
For the requests matching a $csp rule, we will strengthen response's security policy by adding additional content security policy equal to the $csp modifier contents. $csp rules are applied independently from any other rule type. Other basic rules have no influence on it save for document-level exceptions (see the examples section).
Multiple rules matching a single request. In case if multiple
$csprules match a single request, we will apply each of them.
csp syntax$csp value syntax is similar to the Content Security Policy header syntax.
$csp value can be empty in the case of exception rules. See examples section for further information.
Limitations
- Please note that there're a few characters forbidden in the
$cspvalue: (,), ($)csprules support limited list of modifiers:domain,important,subdocument- Rules with
report-*directives are considered invalid.
csp examples||example.org^$csp=frame-src 'none' — this rule blocks all frames on example.org and its subdomains.@@||example.org/page/*$csp=frame-src 'none' — disables all rules with the $csp modifier exactly matching frame-src 'none' on all the pages matching the rule pattern. For instance, the rule above.@@||example.org/page/*$csp — disables all the $csp rules on all the pages matching the rule pattern.||example.org^$csp=script-src 'self' 'unsafe-eval' http: https: — disables inline scripts on all the pages matching the rule pattern.@@||example.org^$document or @@||example.org^$urlblock — disables all the $csp rules on all the pages matching the rule pattern.cookieThe $cookie modifier completely changes rule behavior. Instead of blocking a request, this modifier makes us suppress or modify the Cookie and Set-Cookie headers.
Multiple rules matching a single request. In case if multiple
$cookierules match a single request, we will apply each of them one by one.
$cookie syntaxThe rule syntax depends on whether we are going to block all cookies or to remove a single cookie. The rule behavior can be changed with maxAge and sameSite modifiers.
||example.org^$cookie=NAME;maxAge=3600;sameSite=lax -- every time AdGuard encounters a cookie called NAME in a request to example.org, it will do the following:
3600 seconds||example.org^$cookie -- blocks ALL cookies set by example.org. This is an equivalent to setting maxAge to zero.||example.org^$cookie=NAME -- blocks a single cookie named NAME||example.org^$cookie=/regular_expression/ -- blocks every cookie that matches a given regular expressionImportant: in the case of a regular expression matching, two characters must be escaped: comma (
,) and ($). Use (\) for it. For example, escaped comma looks like this:\,.
$cookie rules are not affected by regular exception rules (@@) unless it's a $document exception. In order to disable a $cookie rule, the exception rule should also have a $cookie modifier. Here's how it works:
@@||example.org^$cookie -- unblocks all cookies set by example.org@@||example.org^$cookie=NAME -- unblocks a single cookie named NAME@@||example.org^$cookie=/regular_expression/ -- unblocks every cookie matching a given regular expressionLimitations:
$cookierules support a limited list of modifiers:domain,~domain,important,third-party,~third-party.
$cookie=__cfduid -- blocks CloudFlare cookie everywhere$cookie=/__utm[a-z]/ -- blocks Google Analytics cookies everywhere||facebook.com^$third-party,cookie=c_user -- prevents Facebook from tracking you even if you are logged inCompatibility with different versions of AdGuard. This type of rules is not supported by AdGuard for iOS and Safari.
networkThis is basically a Firewall-kind of rules allowing to fully block or unblock access to a specified remote address.
$network rules match IP addresses only! You cannot use it to block or unblock access to a domain.[2001:4860:4860::8888]$network instead of [2001:4860:4860:0:0:0:0:8888]$network.$network rule makes AdGuard bypass data to the matching endpoint, e.g. there will be no further filtering at all.network examples174.129.166.49:3478^$network - blocks access to 174.129.166.49:3478 (but not to 174.129.166.49:34788).[2001:4860:4860::8888]:443^$network - blocks access to [2001:4860:4860::8888]:443.174.129.166.49$network - blocks access to 174.129.166.49:*.@@174.129.166.49$network - makes AdGuard bypass data to the endpoint. No other rules will be applied.Compatibility with different versions of AdGuard. Only AdGuard for Windows, Mac, Android are technically capable of using this type of rules.
appThis modifier lets you narrow the rule coverage down to a specific application (or a list of applications). This might be not too important on Windows and Mac, but this is very important on Mobile where some of the filtering rules must be application-specific.
org.example.app).chrome.exe).com.google.Chrome).For Mac, you can find out the bundle ID or the process name of the app by viewing the respective request details in the Filtering log.
app examples||baddomain.com^$app=org.example.app — a rule to block requests that match the specified mask, and are sent from the org.example.app Android app.||baddomain.com^$app=org.example.app1|org.example.app2 — the same rule, but it works for both org.example.app1 and org.example.app2 apps.If you want the rule not to be applied to certain apps, start the app name with ~ sign.
app and ~ examples||baddomain.com^$app=~org.example.app — a rule to block requests that match the specified mask, and are sent from any app save for the org.example.app.||baddomain.com^$app=~org.example.app1|~org.example.app2 — same as above, but now two apps are excluded: org.example.app1 and org.example.app2.Compatibility with different versions of AdGuard. Only AdGuard for Windows, Mac, Android are technically capable of using this type of rules.
redirectAdGuard is able to redirect web requests to a local "resource".
redirect syntaxAdGuard uses the same filtering rules syntax as uBlock Origin. Also, it is compatible with ABP $rewrite=abp-resource modifier.
$redirect is a modifier for the basic filtering rules so rules with this modifier support all other basic modifiers like $domain, $third-party, $script, etc.
The value of the
$redirectmodifier must be the name of the resource that will be used for redirection.
$redirectrules' priority is higher than the regular basic blocking rules' priority. This means that if there's a basic blocking rule (even with$importantmodifier),$redirectrule will prevail over it. If there's an allowlist (@@) rule matching the same URL, it will disable redirecting as well (unless the$redirectrule is also marked as$important).
$redirect rules@@||example.org^$redirect will disable all $redirect rules for URLs that match ||example.org^.@@||example.org^$redirect=redirectName will disable all rules with $redirect=redirectName for any request that matches ||example.org^.redirect examples||example.org/script.js$script,redirect=noopjs
This rule redirects all requests to example.org/script.js to the resource named noopjs.
||example.org/test.mp4$media,redirect=noopmp4-1s
This rule redirects all requests to example.org/test.mp4 to the resource named noopmp4-1s.
More information on scriptlets, redirects, and their usage is available in this GitHub section.
Compatibility with different versions of AdGuard. This type of rules is not supported by AdGuard for iOS and Safari.
redirect-ruleThis is basically an alias to $redirect since it has the same "redirection" values and the logic is almost similar. The difference is that $redirect-rule is applied only in the case when the target request is blocked by a different basic rule.
Negating
$redirect-ruleworks exactly the same way as for regular$redirectrules. Even more than that,@@||example.org^$redirectwill negate both$redirectand$redirect-rulerules.
Examples:
||example.org/script.js
||example.org^$redirect-rule=noopjs
In this case, only requests to example.org/script.js will be "redirected". All other requests to example.org will be kept intact.
denyallowdenyallow modifier allows to avoid creating additional rules when it is needed to disable a certain rule for a specific domain(s). denyallow matches only target domains and not referrer domains.
Adding this modifier to a rule is equivalent to excluding the domains by the rule's matching pattern or to adding the corresponding exclusion rules. To add multiple domains to one rule, use the | character as a separator.
Please note that rules with the $denyallow modifier have the following restrictions:
||)$denyallow=~x.com) or have a wildcard TLD (e.g. $denyallow=x.*)The rules which violate these restrictions are considered invalid.
Example:
This rule:
*$script,domain=a.com|b.com,denyallow=x.com|y.com
is equivalent to this one:
/^(?!.*(x.com|y.com)).*$/$script,domain=a.com|b.com
or to these three:
*$script,domain=a.com|b.com
@@||x.com$script,domain=a.com|b.com
@@||y.com$script,domain=a.com|b.com
noopnoop modifier does nothing and can be used solely to increase rules' readability. It consists of a sequence of underscore characters (_) of any length and can appear in a rule as many times as needed.
noop examples:||example.com$_,removeparam=/^ss\\$/,_,image
||example.com$replace=/bad/good/,___,~third-party
Compatibility with different versions of AdGuard. Available in Developer builds only at this moment.
$removeheaderRules with $removeheader modifier are intended to remove headers from HTTP requests and responses. The initial motivation for this rule type is to be able to get rid of the Refresh header which is often used to redirect users to an undesirable location. However, this is not the only case where this modifier can be useful.
Just like $csp, $redirect, $removeparam, and $cookie, this modifier exists independently, rules with it do not depend on the regular basic rules, i.e. regular exception or blocking rules will not affect it. By default, it only affects response headers. However, you can also change it to remove headers from HTTP requests as well.
Basic syntax
||example.org^$removeheader=header-name — removes a response header called header-name||example.org^$removeheader=request:header-name — removes a request header called header-namePlease note, that $removeheader is case-insensitive, but we suggest always using lower case.
Negating $removeheader
This type of rules works pretty much the same way it works with $csp and $redirect modifiers.
Use @@ to negate $removeheader:
@@||example.org^$removeheader — negates all $removeheader rules for URLs that match ||example.org^.@@||example.org^$removeheader=header — negates the rule with $removeheader=header for any request matching ||example.org^.$removeheader rules can also be disabled by $document and $urlblock exception rules. But basic exception rules without modifiers don't do that. For example, @@||example.com^ will not disable $removeheader=p for requests to example.com, but @@||example.com^$urlblock will.Multiple rules matching a single request
In case of multiple$removeheaderrules matching a single request, we will apply each of them one by one.
$removeheader cannot remove headers from the list below:access-control-allow-originaccess-control-allow-credentialsaccess-control-allow-headersaccess-control-allow-methodsaccess-control-expose-headersaccess-control-max-ageaccess-control-request-headersaccess-control-request-methodorigintiming-allow-originallowcross-origin-embedder-policycross-origin-opener-policycross-origin-resource-policycontent-security-policycontent-security-policy-report-onlyexpect-ctfeature-policyorigin-isolationstrict-transport-securityupgrade-insecure-requestsx-content-type-optionsx-download-optionsx-frame-optionsx-permitted-cross-domain-policiesx-powered-byx-xss-protectionpublic-key-pinspublic-key-pins-report-onlysec-websocket-keysec-websocket-extensionssec-websocket-acceptsec-websocket-protocolsec-websocket-versionp3psec-fetch-modesec-fetch-destsec-fetch-sitesec-fetch-userreferrer-policycontent-typecontent-lengthacceptaccept-encodinghostconnectiontransfer-encodingupgrade$removeheader rules are not compatible with any other modifiers except $domain, $third-party, $app, $important, $match-case, and content type modifiers (e.g. $script, $stylesheet, etc). The rules which have any other modifiers are considered invalid and will be discarded.||example.org^$removeheader=refresh — removes Refresh header from all HTTP responses returned by example.org and its subdomains.||example.org^$removeheader=request:x-client-data — removes X-Client-Data header from all HTTP requests.This block of rules removes Refresh and Location headers from all HTTP responses returned by example.org save for requests to example.org/path/*, for which no headers will be removed:
||example.org^$removeheader=refresh
||example.org^$removeheader=location
@@||example.org/path/$removeheader
Compatibility with different versions of AdGuard. Available in Developer builds only at this moment.
However, the capabilities of the basic rules may not be sufficient to block ads. Sometimes you need to hide an element or change part of the HTML code of a web page without breaking anything. The rules described in this section are created specifically for this purpose.
Work with non-basic rules requires the basic knowledge of HTML and CSS. So, if you want to learn how to make such rules, we recommend to get acquainted with this documentation.
Element hiding rules are used to hide the elements of web pages. It is similar to applying { display: none; } style to selected element.
Note that element hiding rules may operate differently depending on the platform.
rule = [domains] "##" selector
domains = [domain0, domain1[, ...[, domainN]]]
selector — CSS selector, defines the elements to be hidden.domains — domain restriction for the rule.If you want to limit the rule application area to certain domains, just enter them separated with commas. For example: example.org,example.com##selector.
Please note that this rule will be also applied to all subdomains of
example.organdexample.com.
If you want the rule not to be applied to certain domains, start a domain name with ~ sign. For example:
~example.org##selector.
You can use both approaches in a single rule. For example, example.org,~subdomain.example.org##domain will work for example.org and all subdomains, except subdomain.example.org.
Please note, element hiding rules are not dependent on each other. If there is a rule
example.org##selectorin the filter and you add~example.org##selectorboth rules will be applied independently.
example.com##div.textad — hides a div with a class textad at example.com and all subdomains.example.com,example.org###adblock - hides an element with attribute id equals adblock at example.com, example.org and all subdomains.~example.com##.textad - hides an element with a class textad at all domains, except example.com and its subdomains.Important! Safari doesn't support both permitted and restricted domains. So the rules like
example.org,~foo.example.org##.textadare invalid in AdGuard for Safari.
Exceptions can disable some rules on particular domains. They are very similar to usual exception rules, but instead of ## you have to use #@#.
For example, there is a rule in filter:
##.textad
If you want to disable it for example.com, you can create an exception rule:
example.com#@#.textad
Sometimes, it may be necessary to disable all restriction rules. For example, to conduct tests. To do this, use the exclusion rule without specifying a domain. It will completely disable matching CSS elemhide rule on ALL domains:
#@#.textad
The same can be achieved by adding this rule:
*#@#.textad
We recommend to use this kind of exceptions only if it is not possible to change the hiding rule itself. In other cases it is better to change the original rule, using domain restrictions.
Sometimes, simple hiding of an element is not enough to deal with advertising. For example, blocking an advertising element can just break the page layout. In this case AdGuard can use rules that are much more flexible than hiding rules. With this rules you can basically add any CSS styles to the page.
Restrictions. Styles that lead to loading any resource are forbidden. Basically, it means that you cannot use any
<url>type of value in the style.Compatibility with different versions of AdGuard. CSS rules are not supported by AdGuard Content Blocker.
Note that CSS rules may operate differently depending on the platform.
rule = [domains] "#$#" selector "{" style "}"
domains = [domain0, domain1[, ...[, domainN]]]
selector — CSS selector, defines the elements we want to apply the style to.domains — domain restriction for the rule. Same principles as in element hiding rules.style — CSS style, that we want to apply to selected elements.example.com#$#body { background-color: #333!important; }
This rule will apply a style background-color: #333!important; to the body element at example.com and all subdomains.
Just like with element hiding, there is a type of rules that disable the selected CSS style rule for particular domains.
Exception rules syntax is almost the same, you just have to change #$# to #@$#.
For example, there is a rule in filter:
#$#.textad { visibility: hidden; }
If you want to disable it for example.com, you can create an exception rule:
example.com#@$#.textad { visibility: hidden; }
We recommend to use this kind of exceptions only if it is not possible to change the CSS rule itself. In other cases it is better to change the original rule, using domain restrictions.
CSS 3.0 is not always enough to block ads. To solve this problem AdGuard extends CSS capabilities by adding support for the new pseudo-elements. To use extended CSS selectors we have developed a separate open source module.
Application area. Extended selectors can be used in any cosmetic rule, whether they are element hiding rules or CSS rules.
Compatibility with different versions of AdGuard. Note that CSS rules are not supported by AdGuard Content Blocker.
Regardless of the CSS pseudo-classes you are using in the rule, you can use special markers to make these rules use the "Extended CSS" engine. It is recommended to use these markers for all "extended CSS" cosmetic rules so that it was easier to find them.
The syntax for extended CSS rules:
#?# — for element hiding (#@?# — for exceptions )#$?# — for CSS injection (#@$?# — for exceptions )We strongly recommend using these markers any time when you use an extended CSS selector.
example.org#?#div:has(> a[target="_blank"][rel="nofollow"]) — this rule blocks all div elements containing a child node that has a link with the attributes [target="_blank"][rel="nofollow"]. The rule applies only to example.org and its subdomains.example.com#$?#h3:contains(cookies) { display: none!important; } — this rule sets the style display: none!important to all h3 elements that contain the word cookies. The rule applies only to example.com and all its subdomains.example.net#?#.banner:matches-css(width: 360px) — this rule blocks all .banner elements with the style property width: 360px. The rule applies only to example.net and its subdomains.example.net#@?#.banner:matches-css(width: 360px) — this rule will disable the previous rule.Please note that now you can apply simple selectors using the ExtCss engine by using a rule like this:
#?#divFor more information on how to debug ExtendedCSS selectors, jump to this section of the article.
:has()Draft CSS 4.0 specification describes pseudo-class :has. Unfortunately, it is not yet supported by browsers.
Syntax
:has(selector)
Backward compatible syntax:
[-ext-has="selector"]
Supported synonyms for better compatibility: :-abp-has, :if.
Pseudo-class :has() selects the elements that includes the elements that fit to selector.
Examples
Selecting all div elements, which contain an element with the banner class:
<!-- HTML code -->
<div>Do not select this div</div>
<div>Select this div<span class="banner"></span></div>
Selector:
div:has(.banner)
Backward compatible syntax:
div[-ext-has=".banner"]
:if-not()This pseudo-class is basically a shortcut for :not(:has()). It is supported by ExtendedCss for better compatibility with some filters subscriptions, but it is not recommended to use it in AdGuard filters. The rationale is that one day browsers will add :has native support, but it will never happen to this pseudo-class.
:contains()This pseudo-class principle is very simple: it allows to select the elements that contain specified text or which content matches a specified regular expression. Regex flags are supported. Please note that this pseudo-class uses textContent element property for matching (and not the innerHTML).
Syntax
// matching by plain text
:contains(text)
// matching by a regular expression
:contains(/regex/i)
Backward compatible syntax:
// matching by plain text
[-ext-contains="text"]
// matching by a regular expression
[-ext-contains="/regex/"]
Supported synonyms for better compatibility:
:-abp-contains,:has-text.
Examples
Selecting all div elements, which contain text banner:
<!-- HTML code -->
<div>Do not select this div</div>
<div id="selected">Select this div (banner)</div>
<div>Do not select this div <div class="banner"></div></div>
Selector:
// matching by plain text
div:contains(banner)
// matching by a regular expression
div:contains(/this .* banner/)
// also with regex flags
div:contains(/this .* banner/gi)
Backward compatible syntax:
// matching by plain text
div[-ext-contains="banner"]
// matching by a regular expression
div[-ext-contains="/this .* banner/"]
Please note that in this example only a
divwithid=selectedwill be selected, because the next element does not contain any text;banneris a part of code, not a text.
:matches-css()These pseudo-classes allow to select an element by its current style property. The work of this pseudo-class is based on using the window.getComputedStyle function.
Syntax
/* element style matching */
selector:matches-css(property-name ":" pattern)
/* ::before pseudo-element style matching */
selector:matches-css-before(property-name ":" pattern)
/* ::after pseudo-element style matching */
selector:matches-css-after(property-name ":" pattern)
Backward compatible syntax:
selector[-ext-matches-css="property-name ":" pattern"]
selector[-ext-matches-css-after="property-name ":" pattern"]
selector[-ext-matches-css-before="property-name ":" pattern"]
property-name — a name of CSS property to check the element forpattern — a value pattern that is using the same simple wildcard matching as in the basic url filtering rules OR a regular expression. For this type of matching, AdGuard always does matching in a case insensitive manner. In the case of a regular expression, the pattern looks like /regex/.For non-regex patterns,
(,),[,]must be unescaped, because we require escaping them in the filtering rules.For regex patterns,
"and\should be escaped, because we manually escape those in extended-css-selector.js.
Examples
Selecting all div elements which contain pseudo-class ::before with specified content:
<!-- HTML code -->
<style type="text/css">
#to-be-blocked::before {
content: "Block me"
}
</style>
<div id="to-be-blocked" class="banner"></div>
<div id="not-to-be-blocked" class="banner"></div>
Selector:
// Simple matching
div.banner:matches-css-before(content: block me)
// Regular expressions
div.banner:matches-css-before(content: /block me/)
Backward compatible syntax:
// Simple matching
div.banner[-ext-matches-css-before="content: block me"]
// Regular expressions
div.banner[-ext-matches-css-before="content: /block me/"]
:matches-attr()This pseudo-class allows to select an element by its attributes, especially if they are randomized.
Syntax
selector:matches-attr("name"[="value"])
name — attribute name OR regular expression for attribute namevalue — optional, attribute value OR regular expression for attribute valueFor regex patterns,
"and\should be escaped.
Examples
<!-- HTML code -->
<div id="targer1" class="matches-attr" hsd4jkf-link="ssdgsg-banner_240x400"></div>
<div id="targer2" class="has matches-attr">
<div data-sdfghlhw="adbanner"></div>
</div>
<div id="targer3-host" class="matches-attr has contains">
<div id="not-targer3" wsdfg-unit012="click">
<span>socials</span>
</div>
<div id="targer3" hrewq-unit094="click">
<span>ads</span>
</div>
</div>
<div id="targer4" class="matches-attr upward">
<div >
<inner-afhhw class="nyf5tx3" nt4f5be90delay="1000"></inner-afhhw>
</div>
</div>
// for div#targer1
div:matches-attr("/-link/")
// for div#targer2
div:has(> div:matches-attr("/data-/"="adbanner"))
// for div#targer3
div:matches-attr("/-unit/"="/click/"):has(> span:contains(ads))
// for div#targer4
*[class]:matches-attr("/.{5,}delay$/"="/^[0-9]*$/"):upward(2)
:matches-property()This pseudo-class allows to select an element by its properties.
Syntax
selector:matches-property("name"[="value"])
name — property name OR regular expression for property namevalue — optional, property value OR regular expression for property valueFor regex patterns,
"and\should be escaped.
namesupports regexp for property in chain, e.g.prop./^unit[\\d]{4}$/.type
Examples
divProperties = {
id: 1,
check: {
track: true,
unit_2ksdf1: true,
},
memoizedProps: {
key: null,
tag: 12,
_owner: {
effectTag: 1,
src: 'ad.com',
},
},
};
// element with such properties can be matched by any of such rules:
div:matches-property("check.track")
div:matches-property("check./^unit_.{4,6}$/"))
div:matches-property("memoizedProps.key"="null")
div:matches-property("memoizedProps._owner.src"="/ad/")
:xpath()This pseudo-class allows to select an element by evaluating an XPath expression.
Can be placed only at the end of a selector, except for pseudo-class
:remove().
The :xpath() pseudo-class is different from other pseudo-classes. Whereas all other operators are used to filter down a resultset of elements, the :xpath() operator can be used both to create a new resultset or filter down an existing one. For this reason, subject selector is optional. For example, an :xpath() operator could be used to create a new resultset consisting of all ancestor elements of a subject element, something not otherwise possible with either plain CSS selectors or other procedural operators.
Syntax
[selector]:xpath(expression)
selector- optional, a plain CSS selector, or a Sizzle compatible selectorexpression — a valid XPath expressionExamples
// Filtering results from selector
div:xpath(//*[@class="test-xpath-class"])
div:has-text(/test-xpath-content/):xpath(../../..)
// Use xpath only to select elements
facebook.com##:xpath(//div[@id="stream_pagelet"]//div[starts-with(@id,"hyperfeed_story_id_")][.//h6//span/text()="People You May Know"])
:nth-ancestor()This pseudo-class allows to lookup the nth ancestor relative to the currently selected node.
It is a low-overhead equivalent to :xpath(..[/..]*).
Can be placed only at the end of a selector, except for pseudo-class
:remove().
Syntax
selector:nth-ancestor(n)
selector — a plain CSS selector, or a Sizzle compatible selector.n — positive number >= 1 and < 256, distance from the currently selected node.Examples
div.test:nth-ancestor(4)
div:has-text(/test/):nth-ancestor(2)
:upward()This pseudo-class allows to lookup the ancestor relative to the currently selected node.
Can be placed only at the end of a selector, except for pseudo-class
:remove().
Syntax
/* selector parameter */
subjectSelector:upward(targetSelector)
/* number parameter */
subjectSelector:upward(n)
subjectSelector — a plain CSS selector, or a Sizzle compatible selectortargetSelector — a valid plain CSS selectorn — positive number >= 1 and < 256, distance from the currently selected nodeExamples
div.child:upward(div[id])
div:contains(test):upward(div[class^="parent-wrapper-")
div.test:upward(4)
div:has-text(/test/):upward(2)
:remove() and pseudo-property removeSometimes, it is necessary to remove a matching element instead of hiding it or applying custom styles. In order to do it, you can use pseudo-class :remove() as well as pseudo-property remove.
Pseudo-class
:remove()can be placed only at the end of a selector.
Syntax
! pseudo-class
selector:remove()
! pseudo-property
selector { remove: true; }
selector — a plain CSS selector, or a Sizzle compatible selectorExamples
div.inner:remove()
div:has(> div[ad-attr]):remove()
div:xpath(../..):remove()
div:contains(target text) { remove: true; }
div[class]:has(> a:not([id])) { remove: true; }
Please note that all style properties will be ignored if
:remove()pseudo-class orremovepseudo-property is used.
The way element hiding and CSS rules are applied is platform-specific.
In AdGuard for Windows, Mac, and Android, we use a stylesheet injected into the page. The priority of cosmetic rules is the same as any other websites' CSS stylesheet. But there is a limitation: element hiding and CSS rules cannot override inline styles. In such cases, it's recommended to use extended selectors or HTML filtering.
In AdGuard browser extensions, the so called "user stylesheets" are used. They have higher priority than even the inline styles.
Extended CSS selectors use Javascript to work and basically add an inline style themselves, therefore they can override any style.
In most cases, the basis and cosmetic rules are enough to filter ads. But sometimes it is necessary to change the HTML-code of the page itself before it is loaded. This is when you need filtering rules for HTML content. They allow to indicate the HTML elements to be cut out before the browser loads the page.
Compatibility with different versions of AdGuard. Rules are supported by AdGuard for Windows, Mac, Android and by the AdGuard's Firefox add-on. This type of rules don't work in extensions for other browsers because they are unable to modify content on network level.
rule = [domains] "$$" tagName [attributes]
domains = [domain0, domain1[, ...[, domainN]]]
attributes = "[" name0 = value0 "]" "[" name1 = value2 "]" ... "[" nameN = valueN "]"
tagName — name of the element in lower case, for example div or script.domains — domain restriction for the rule. Same principles as in element hiding rules syntax.attributes — a list of attributes, that limit the elements selection. name - attribute name, value - substring, that is contained in attribute value.HTML code
<script data-src="/banner.js"></script>
Rule
example.org$$script[data-src="banner"]
This rule removes all script elements with the attribute data-src containing the substring banner. The rule applies only to example.org and all its subdomains.
In addition to usual attributes, which value is every element checked for, there is a set of special attributes that change the way a rule works. Below there is a list of these attributes:
tag-contentThis is the most frequently used special attribute. It limits selection with those elements whose innerHTML code contains the specified substring.
You should use
""to escape", for instance:
$$script[tag-content="alert(""this is ad"")"]
For example, let's take a look at this HTML code:
<script type="text/javascript">
document.write('<div>banner text</div>" />');
</script>
Following rule will delete all script elements with a banner substring in their code:
$$script[tag-content="banner"]
Nested elements. If we are dealing with multiple nested elements and they all fall within the same HTML filtering rule, they all are going to be deleted.
wildcardThis special attribute works almost like tag-content and allows you to check the innerHTML code of the document. Rule will check if HTML code of the element fits to the search pattern.
You should use
""to escape", for instance:
$$script[wildcard=""banner""]
For example:
$$script[wildcard="*banner*text*"]
It will check, if the element's code contains two consecutive substrings banner and text.
max-lengthSpecifies the maximum length for content of HTML element. If this parameter is set and the content length exceeds the value - a rule does not apply to the element.
Default value. If this parameter is not specified, the
max-lengthis considered to be 8192.
For example:
$$div[tag-content="banner"][max-length="400"]
This rule will remove all the div elements, whose code contains the substring banner and the length of which does not exceed 400 characters.
min-lengthSpecifies the minimum length for content of HTML element. If this parameter is set and the content length is less than preset value - a rule does not apply to the element.
For example:
$$div[tag-content="banner"][min-length="400"]
This rule will remove all the div elements, whose code contains the substring banner and the length of which exceeds 400 characters.
Similar to hiding rules, there is a special type of rules that disable the selected HTML filtering rule for particular domains.
The syntax is the same, you just have to change $$ to $@$.
For example, there is a rule in filter:
$$script[tag-content="banner"]
If you want to disable it for example.com, you can create an exception rule:
example.com$@$script[tag-content="banner"]
Sometimes, it may be necessary to disable all restriction rules. For example, to conduct tests. To do this, use the exclusion rule without specifying a domain.
$@$script[tag-content="banner"]
We recommend to use this kind of exceptions only if it is not possible to change the hiding rule itself. In other cases it is better to change the original rule, using domain restrictions.
AdGuard supports a special type of rules that allows you to inject any javascript code to websites pages.
Restrictions. Please note that this type of rules can be used only in trusted filters. This category includes your own User filter and all the filters created by AdGuard Team.
Compatibility with different versions of AdGuard. Javascript rules are not supported by AdGuard Content Blocker.
We strongly recommend using scriptlets instead of Javascript rules whenever possible. JS rules are supposed to help with debugging, but as a long-time solution a scriptlet rule should be used.
rule = [domains] "#%#" script
domains — domain restriction for the rule. Same principles as in element hiding rules.script — arbitrary javascript code in one string.example.org#%#window.__gaq = undefined; — executes the code window.__gaq = undefined; on all pages at example.org and all subdomains.Similar to hiding rules, there is a special type of rules that disable the selected javascript rule for particular domains.
The syntax is the same, you just have to change #%# to #@%#.
For example, there is a rule in filter:
#%#window.__gaq = undefined;
If you want to disable it for example.com, you can create an exception rule:
example.com#@%#window.__gaq = undefined;
Sometimes, it may be necessary to disable all restriction rules. For example, to conduct tests. To do this, use the exclusion rule without specifying a domain.
#@%#window.__gaq = undefined;
We recommend to use this kind of exceptions only if it is not possible to change the hiding rule itself. In other cases it is better to change the original rule, using domain restrictions.
Scriptlet is a JavaScript function that provides extended capabilities for content blocking. These functions can be used in a declarative manner in AdGuard filtering rules.
AdGuard supports a lot of different scriptlets. Please note that in order to achieve cross-blocker compatibility, we also support syntax of uBO and ABP.
Compatibility with different versions of AdGuard. Scriptlet rules are not supported by AdGuard Content Blocker.
rule = [domains] "#%#//scriptlet(" scriptletName arguments ")"
scriptletName (mandatory) is a name of the scriptlet from AdGuard's scriptlets library
arguments (optional) is a list of String arguments (no other types of arguments are supported)
example.org#%#//scriptlet("abort-on-property-read", "alert")
This rule will be applied to example.org pages (and its subdomains) and will execute the "abort-on-property-read" scriptlet with the "alert" parameter.
More information about scriptlets can be found on GitHub.
For more information on how to debug scriptlets, jump to this section of the artcile.
Each rule can be modified using the modifiers described in the following paragraphs.
rule = "[$" modifiers "]" [rule text]
modifiers = modifier0[, modifier1[, ...[, modifierN]]]
modifier - set of the modifiers described below.rule text - a rule to be modified.For example: [$domain=example.com,app=test_app]##selector.
In the modifiers values of the following characters must be escaped: [, ], ,, and \ (unless
it's used for the escaping). Use \ to escape them. For example, an escaped bracket looks like
this: \].
app lets you narrow the rule coverage down to a specific application (or a list of applications).
The modifier's behavior and syntax perfectly match the corresponding $app modifier of basic rules.
app examples:
[$app=org.example.app]example.com##.textad - hides a div with a class textad at example.com and all subdomains in requests sent from the org.example.app Android app.[$app=~org.example.app1|~org.example.app2]example.com##.textad - hides a div with a class textad at example.com and all subdomains in requests sent from any app except org.example.app1 and org.example.app2.[$app=com.apple.Safari]example.org#%#//scriptlet('prevent-setInterval', 'check', '!300'). This rule will apply the corresponding scriptlet only in Safari browser on Mac.[$app=org.example.app]#@#.textad — disables all ##.textad rules for all domains while using org.example.app.Compatibility with different versions of AdGuard. This type of rules is supported by AdGuard for Windows, Mac and Android. Developer builds only at this moment.
domain limits the rule application area to a list of domains (and their subdomains).
The modifier's behavior and syntax perfectly match the corresponding
$domain modifier of
basic rules.
domain examples:
[$domain=example.com]##.textad — hides a div with a class textad at example.com and all subdomains.[$domain=example.com|example.org]###adblock - hides an element with attribute id equals adblock at example.com, example.org and all subdomains.[$domain=~example.com]##.textad - this rule hides div elements of the class textad for all domains, except example.com and its subdomains.Please note that there are 2 ways to specify domain restrictions for non-basic rules:
1) the "classic" way is to specify domains before rule mask and attributes: example.com##.textad
2) the modifier approach is to specify domains via domain modifier: [$domain=example.com]##.textad
But rules with mixed style domains restriction are considered invalid. So, for example, the rule
[$domain=example.org]example.com##.textad will be rejected.
Compatibility with different versions of AdGuard. This type of rules is supported by AdGuard for Windows, Mac and Android. Developer builds only at this moment.
path limits the rule application area to specific locations or pages on websites.
path=pattern
pattern is a path mask to which the rule is restricted. Its syntax and behavior are pretty much the same as with the pattern for basic rules. You can also use special characters, except for ||, which does not make any sense in this case (see examples below).
Please note that
pathmodifier matches the query string as well.
pathmodifier supports regular expressions in the same way basic rules do.
path examples:
[$path=page.html]##.textad - hides a div with a class textad at /page.html or /page.html?<query> or /sub/page.html or /another_page.html[$path=/page.html]##.textad - hides a div with a class textad at /page.html or /page.html?<query> or /sub/page.html of any domain but not at /another_page.html[$path=|/page.html]##.textad - hides a div with a class textad at /page.html or /page.html?<query> of any domain but not at /sub/page.html[$path=/page.html|]##.textad - hides a div with a class textad at /page.html or /sub/page.html of any domain but not at /page.html?<query> [$path=/page*.html]example.com##.textad - hides a div with a class textad at /page1.html or /page2.html or any other path matching /page<...>.html of example.com[$domain=example.com,path=/page.html]##.textad - hides a div with a class textad at page.html of example.com and all subdomains but not at another_page.html[$path=/\\/(sub1|sub2)\\/page\\.html/]##.textad - hides a div with a class textad at both /sub1/page.html and /sub2/page.html of any domain (please, note the escaped special characters)Compatibility with different versions of AdGuard. Rules with
pathmodifier are supported by AdGuard for Windows, Mac, Android, and AdGuard browser extensions for Chrome, Firefox, Edge. Developer builds only at this moment.
If you maintain a third-party filter that is known to AdGuard, you might be interested in the information presented in this section. Please note that hints will be applied to registered filters only. The filter is considered to be registered and known by AdGuard, if it is present in the known filters index. If you want your filter to be registered, please file an issue to AdguardFilters repo.
We provide pre-processor directives that can be used by filters maintainers to improve compatibility with different ad blockers and provide:
Please note that any mistake in a pre-processor directive will lead to AdGuard failing the filter update in the same way as if the filter URL was unavailable.
Pre-processor directives can be used in the User Rules or in the custom filters.
The !#include directive allows to include contents of a specified file into the filter. It supports only files from the same origin to make sure that the filter maintainer is in control of the specified file. The included file can also contain pre-processor directives (even other !#include directives). Ad blockers should consider the case of recursive !#include and implement a protection mechanism.
Syntax
!#include file_path
file_path — same origin absolute or relative file path to be includedThe files must originate from the same domain but may be located in a different folder.
If included file is not found or unavailable, the whole filter update should fail.
Same-origin limitation should be disabled for local custom filters.
Examples
Filter URL: https://example.org/path/filter.txt
! Valid (same origin):
!#include https://example.org/path/includedfile.txt
!
! Valid (relative path):
!#include /includedfile.txt
!#include ../path2/includedfile.txt
!
! Invalid (another origin):
!#include https://domain.com/path/includedfile.txt
Filters maintainers can use conditions to supply different rules depending on the ad blocker type. When an adblocker encounters an !#if directive, followed eventually by an !#endif directive, it will compile the code inside of the directives block only if the specified condition is true. Condition supports all the basic logical operators.
A conditional directive beginning with an
!#ifdirective must explicitly be terminated with an!#endifdirective.Whitespaces matter.
!#ifis a valid directive, while!# ifis not.
Syntax
!#if (conditions)
rules_list
!#endif
!#if (conditions) — start of the blockconditions — just like in some popular programming languages, pre-processor conditions are based on constants declared by ad blockers. Ad blocker authors define on their own what exact constants do they declare. Possible values:
adguard — declared always; shows maintainers that this is one of AdGuard products; should be enough in 95% of cases! should be used before constant) in a specific product only:adguard_app_windows — AdGuard for Windowsadguard_app_mac — AdGuard for Macadguard_app_android — AdGuard for Androidadguard_app_ios — AdGuard for iOSadguard_ext_safari — AdGuard for Safariadguard_ext_chromium — AdGuard Browser extension for Chrome (and chromium-based browsers, e.g. new Microsoft Edge)adguard_ext_firefox — AdGuard Browser extension for Firefoxadguard_ext_edge — AdGuard Browser extension for Edge Legacyadguard_ext_opera — AdGuard Browser extension for Operaadguard_ext_android_cb — AdGuard Content Blocker for mobile Samsung and Yandex browsersext_ublock — special case; this one is declared when a uBlock version of a filter is compiled by the FiltersRegistryrules_list — list of rules!#endif — end of the blockExamples
! for all AdGuard products except AdGuard for Safari
!#if (adguard && !adguard_ext_safari)
||example.org^$third-party
domain.com##div.ad
!#endif
! directives even can be combined
!#if (adguard_app_android)
!#include /androidspecific.txt
!#endif
Safari is notoriously known for its harsh 50k max limit for filtering rules in content blockers. But in AdGuard for Safari and AdGuard for iOS max rule count is raised to 300k by splitting them into several content blockers. Generally, several filters categories are more or less independent, so there is such content blockers with such categories included:
User rulesandAllowlistare added to every content blocker.
The main issue with using multiple content blockers is that rules inside these content blockers cannot influence each other. This may lead to different unexpected issues. So filters maintainers may use !#safari_cb_affinity to define Safari content blockers affinity for the rules inside of the directive block.
Syntax
!#safari_cb_affinity(content_blockers)
rules_list
!#safari_cb_affinity
!#safari_cb_affinity(content_blockers) — start of the blockcontent_blockers — comma-separated list of content blockers. Possible values:
general — AdGuard General content blockerprivacy — AdGuard Privacy content blockersocial — AdGuard Social content blockersecurity — AdGuard Security content blockerother — AdGuard Other content blockercustom — AdGuard Custom content blockerall — special keyword that means that the rules must be included into all content blockersrules_list — list of rules!#safari_cb_affinity — end of the blockExamples
! to unhide specific element which is hidden by AdGuard Base filter:
!#safari_cb_affinity(general)
example.org#@#.adBanner
!#safari_cb_affinity
! to allowlist basic rule from AdGuard Tracking Protection filter filter:
!#safari_cb_affinity(privacy)
@@||example.org^
!#safari_cb_affinity
"Hint" is a special comment, instruction to the filters compiler used on the server side (see FiltersRegistry).
!+ HINT_NAME1(PARAMS) HINT_NAME2(PARAMS)
Note, that you can apply multiple hints.
For each filter, AdGuard compiles two versions: full and optimized. Optimized version is much more lightweight and does not contain rules which are not used at all or used rarely.
Rules usage frequency comes from the collected filter rules statistics. But filters optimization is based on more than that — some filters have specific configuration. This is how it looks like for Base filter:
"filter": AdGuard Base filter,
"percent": 30,
"minPercent": 20,
"maxPercent": 40,
"strict": true
Where:
~= (rules count in optimized filter) / (rules count in original filter) * 100percent valuepercent valuepercent < minPercent OR percent > maxPercent and strict mode is on then filter compilation should fail, otherwise original rules must be usedIn other words,
percentis the "compression level". For instance, for the Base filter it is configured to 40%. It means that optimization algorithm should strip 60% of rules.
Eventually, here are the two versions of the Base filter for AdGuard browser extension:
Important: If you want to add a rule which shouldn't be removed at optimization use the NOT_OPTIMIZED hint:
!+ NOT_OPTIMIZED
||example.org^
And this rule won't be optimized only for AdGuard for Android:
!+ NOT_OPTIMIZED PLATFORM(android)
||example.org^
Specify which platforms can apply this rule. List of existing platforms:
windows - Example: English filter for Windows - https://filters.adtidy.org/windows/filters/2.txt
mac - Example: English filter for Mac - https://filters.adtidy.org/mac_v2/filters/2.txt
android - Example: English filter for Android - https://filters.adtidy.org/android/filters/2.txt
ios - Example: English filter for iOS - https://filters.adtidy.org/ios/filters/2.txt
ext_chromium - Example: AdGuard browser extension for Chrome - https://filters.adtidy.org/extension/chromium/filters/2.txt
ext_ff - Example: AdGuard browser extension for Firefox - https://filters.adtidy.org/extension/firefox/filters/2.txt
ext_edge - Example: AdGuard browser extension for Edge - https://filters.adtidy.org/extension/edge/filters/2.txt
ext_opera - Example: AdGuard browser extension for Opera - https://filters.adtidy.org/extension/opera/filters/2.txt
ext_ublock - Example: uBlock Origin - https://filters.adtidy.org/extension/ublock/filters/2.txt
ext_safari - Example: AdGuard browser extension for Safari - https://filters.adtidy.org/extension/safari/filters/2.txt
ext_android_cb - Example: AdGuard Content Blocker - https://filters.adtidy.org/extension/android-content-blocker/filters/2.txt
Examples:
This rule will be available for Windows, Mac, and Android only:
!+ PLATFORM(windows,mac,android)
||example.org^
This rule will be available for every platform except Safari extension, iOS, and Android content blocker:
!+ NOT_PLATFORM(ext_safari, ext_android_cb, ios)
||example.org^
It may be possible to create simple filtering rules "in your head", but for anything even slightly more complicated you'd need additional tools to debug and iterate them. There are tools to assist you with that. You can use DevTools in Chrome and its analogs in other browsers, but most AdGuard products provide another one: Filtering log.
Filtering log is an advanced tool that will be helpful mostly to filter developers. It lists all web requests that pass through AdGuard, gives you exhaustive information on each of them, offers multiple sorting options, and has other useful features.
Depending on which AdGuard product you're using, Filtering log can be located in different places.
In AdGuard for iOS and in AdGuard for Safari Filtering log does not exist because of the way content blockers are implemented in Safari. AdGuard doesn't see the web requests and therefore can't display them.
Sometimes, you might need to check the performance of a given selector or a stylesheet. In order to do it without interacting with javascript directly, you can use a special debug style property. When ExtendedCss meets this property, it enables the debug mode either for a single selector or for all selectors, depending on the debug value. Open the browser console while on a web page to see the timing statistics for selector(s) that were applied there. Debugging mode displays the following stats for each of the debugged selectors:
array: time that it took to apply the selector on the page, for each of the instances that it's been applied (in milliseconds)
length: total number of times that the selector has been applied on the page
mean: mean time that it took to apply the selector on the page
stddev: standard deviation
squaredSum: sum of squared deviations from the mean
sum: total time it took to apply the selector on the page across all instances
Debugging a single selector
When the value of the debug property is true, only information about this selector will be shown in the browser console.
#$?#.banner { display: none; debug: true; }
Enabling global debug
When the value of the debug property is global, the console will display information about all ExtendedCSS selectors that have matches on the current page, for all ExtendedCSS rules from any of the enabled filters.
#$?#.banner { display: none; debug: global; }
If you don't have AdGuard installed, you can still test extended selectors, but you'll have to load ExtendedCSS to the current page first. To do so, copy and execute the following code in the browser console:
!function(E,x,t,C,s,s_){C=E.createElement(x),s=E.getElementsByTagName(x)[0],C.src=t,
C.onload=function(){alert('ExtCss loaded successfully')},s.parentNode.insertBefore(C,s)}
(document,'script','https://AdguardTeam.github.io/ExtendedCss/extended-css.min.js')
Alternatively, install an "ExtendedCssDebugger" userscript: https://github.com/AdguardTeam/Userscripts/blob/master/extendedCssDebugger/extended-css.debugger.user.js
You can now use the ExtendedCss constructor in the global scope, and its method ExtendedCss.query as document.querySelectorAll.
var selectorText = "div.block[-ext-has='.header:matches-css-after(content: Anzeige)']";
ExtendedCss.query(selectorText) // returns an array of Elements matching selectorText
If you're using AdGuard browser extension and want to debug a scriptlet rule, you can get additional information by simpy having the Filtering log opened. In that case, scriptlets will switch to debug mode and will write more information to the browser's console.
The following scriptlets may be especially useful for debug purposes:
debug-current-inline-script
debug-on-property-read
debug-on-property-write
log-addEventListener
log-eval
log
The following scriptlets may be used for debug purposes when applied without any parameters:
requestAnimationFrame
prevent-setInterval
prevent-setTimeout
We wish you luck with creating you own ad filters.
If you need an advice on how to create your own filters properly, our forum has a special section dedicated to writing your own filtering rules.