This guide is designed to help you write and maintain your own Adblock Plus filters. Creating your own filters gives you more control over the things you want to see and don’t want to see on the websites that you visit, including ads, images, requests, and scripts.
Table of contents
- About Adblock Plus filters
- Creating filters
- Basic filter rules
- Advanced features
- Specifying filter options
- Using regular expressions
- Special comments
- Content filters
- Implementing a sitekey on the server
About Adblock Plus filters
The following filter lists come pre-installed with Adblock Plus:
- Acceptable Ads
- EasyList (+ bundled language filter list - depending on your browser’s language setting)
- ABP Anti-circumvention filter list
In addition to these pre-installed filter lists, you can create your own filters. A filter is simply a rule that tells your browser which elements to block. A filter list is a set of rules that tells your browser what to block.
There are several types of filters, or filter rules, including:
- Blocking filters
- Applied on the network level to decide whether a request should be blocked.
- Content filters
- (including hiding filters oftentimes referred to as element hiding filters)
- Hide particular elements on a page, including element hiding with extended selectors (emulation) as well as snippets.
- Exception filters
- Used to unblock certain requests or unhide certain elements on certain websites. Additionally, they can allow certain network requests despite filters that would otherwise block the requests.
You can easily create your filter(s) via the Adblock Plus Settings page.
Adblock Plus (version 3.4 and higher) for all browsers that support WebExtensions API like Chrome, Edge, Firefox, Opera and Yandex Browser:
- Click the Adblock Plus icon and then click the gear icon in the upper-right corner.
The Adblock Plus Settings tab opens.
- Select the Advanced tab and scroll to the Create and edit your filter list section.
- Click Start creating my filter list.
- Enter your filter and click Save.
Basic filter rules
The most trivial filter you can define is the address of the request you want to block. However, this address often changes every time you open a page. For example, it could be
123 is a random number. Here, blocking the complete address won't help. You’ll need a more general filter, like
http://example.com/ads/banner*.gif, or even
http://example.com/ads/, which blocks everything in the “ads” directory.
Defining exception rules
If you notice that your filter is blocking something it shouldn't, you might consider using an exception rule rather than removing or matching the filter. Exception rules allow you to define cases where filters shouldn't be applied. Exception rules are no different from filter rules; you can use wildcards or regular expressions.
Exception rules can do more, however. For example, if you specify
$document option, you’ll get an exception for the entire page. If your exception rule is
@@||example.com^$document and you open a page from
example.com, Adblock Plus will be turned off on this page and nothing will be blocked.
Matching at the beginning or end of an address
Adblock Plus typically treats each filter as if it has a wildcard at its beginning and end (i.e. there’s no difference between the filters
*ad*). While this is usually unproblematic, sometimes you might want the filter you defined to only match at the beginning or the end of an address.
You might want to block
http://example.com/banner.gif as well as
http://www.example.com/banner.gif. You can do this by putting two pipe symbols in front of the filter. This ensures that the filter matches at the beginning of the domain name:
||example.com/banner.gif, and blocks all of these addresses while not blocking
Marking separator characters
Sometimes, you might need to accept any separator character in a filter. For example, you might write a filter that blocks
http://example.com:8000/ but not
http://example.com.ar/. Here, the symbol
^ can be used as a placeholder for a single separator character,
http://example.com^. The separator character can be anything but a letter, a digit, or one of the following:
%. The end of the address is also accepted as a separator.
In the following example, all separator characters are shown bolded in blue:
http: // example.com : 8000 / foo.bar ? a = 12 & b = %D1%82%D0%B5%D1%81%D1%82
This address can be blocked with the filters
Any rule that starts with an exclamation mark (!) is considered a comment. Adblock Plus ignores this rule for actual blocking, so it’s safe to write whatever you want in the comment. You can place a comment rule above a filter to describe its purpose or function, or you can place a comment above your filter list stating your authorship (most filter list authors do this).
Specifying filter options
Adblock Plus allows you to specify a number of options to modify the behavior of a filter. These options should be separated with a comma (
,) after a dollar sign (
$) at the end of the filter.
/ads/* is the actual filter, and
match-case are its options. Currently, the following options are supported:
These determine which types of elements a filter can block (or allowlist in case of an exception rule). Multiple type options can be specified to indicate that the filter should be applied to several types of elements. Possible types include:
script- external scripts loaded via the HTML script tag
image- regular images, typically loaded via the HTML img tag
stylesheet- external CSS stylesheet files
object- content handled by browser plug-ins, e.g. Flash or Java
xmlhttprequest- requests started using the XMLHttpRequest object or fetch() API
subdocument- embedded pages, usually included via HTML inline frames (iframes)
ping- requests started by or navigator.sendBeacon() (Adblock Plus 2.7.1 or higher is required)
websocket- requests initiated via WebSocket object (Adblock Plus 2.8 or higher is required)
webrtc- connections opened via RTCPeerConnection instances to ICE servers (Adblock Plus 1.13.3 or higher for Chrome and Opera, 3.0 or higher for Firefox, is higher required)
document- the page itself, but only works for exception rules. You can use this option to allowlist an entire iframe or website.
elemhide- for exception rules only, similar to
documentbut only turns off element hiding rules on the page rather than all filter rules (Adblock Plus 1.2 or higher is required)
generichide- for exception rules only, similar to
elemhidebut only turns off generic element hiding rules on the page (Adblock Plus 2.6.12 or higher is required)
genericblock- for exception rules only, just like
generichidebut turns off generic blocking rules (Adblock Plus 2.6.12 or higher is required)
popup- pages opened in a new tab or window Note: Filters will not block pop-ups by default, only if the
$popuptype option is specified.
font- external font files
media- regular media files like music and video
other- types of requests not covered in the list above
match-case- ensures that the filter only applies to requests with matching letter case, e.g. the filter
Inverse type options
These specify which requesttypes the filter should not be applied to. Possible inverse type options include ~script, ~image, ~stylesheet, ~object, ~xmlhttprequest, ~subdocument, ~ping, ~websocket, ~webrtc, ~document, ~elemhide, ~other
Restriction to third-party/first-party requests
If the third-party option is specified, the filter is only applied to requests from a different origin than the currently viewed page. Similarly, ~third-party restricts the filter to requests from the same origin as the currently viewed page.
domain=example.com means that the filter should only be applied on pages from the
example.com domain. Multiple domains can be specified using
| as the separator. For the option
domain=example.com|example.net, the filter is only applied on pages from
example.net domains. If a domain name is preceded with
~, the filter should not be applied on pages from this domain. For example,
domain=~example.com means that the filter should be applied on pages from any domain but
domain=example.com|~foo.example.com restricts the filter to the
example.com domain with the exception of
sitekey=abcdsitekeydcba means that the filter should only be applied on pages that provide a public key and a signature that can be verified by that very same public key that is also contained in the filter (but without the trailing
=). Multiple sitekeys can be specified using
| as a separator. For example, the option
sitekey=abcdsitekeydcba|bcdesitekeyedcb only allows the filter to be applied on pages providing either sitekey
bcdesitekeyedcb. This is similar to domain restrictions, but allows for scenarios where a single filter should apply to a very large number of domains. Note: Sitekey restrictions require modifications on the server-side.
Content Security Policies
csp=script-src: 'none' causes a Content Security Policy header of
script-src: 'none' to be injected into HTTP responses for requested documents matching the filter (assuming that exception rules with the same option don't also match and that the document isn’t allowlisted). The Content Security Policy
script-src: 'none' blocks all scripts, including inline, in the document. This filter option should generally be avoided, except as a last resort to counter advanced circumvention. (Adblock Plus 3.1 or higher is required.)
Redirecting requests to internal resources
rewrite= option allows the rewriting of URLs (or redirecting requests) to an internal resource in order to deactivate it without causing an error. Indicate the internal resource by name and prefix
abp-resource: in order to be recognized. For example
blank-text- empty text
blank-css- empty stylesheet
blank-html- empty HTML document
blank-mp3- a 0.1s silent MP3 audio file
1x1-transparent-gif- 1x1 pixel transparent GIF image
2x2-transparent-png- 2x2 pixels transparent PNG image
3x2-transparent-png- 3x2 pixels transparent PNG image
32x32-transparent-png- 32x32 pixels transparent PNG image
Any other value will make the filter have no effect and let the request pass through.
A few notes about using the rewrite option
rewrite=is restricted to certain domains using the
$domainfilter option. For more information, refer to the Domain restrictions section of this guide.
rewrite=cannot be used together with the
$third-partyfilter option, but can be used with
- The filter pattern has to be
*or start with
Using regular expressions
Adblock Plus supports filters written in regular expressions (regex). For example, the filter
banner321 but not
banners. We recommend checking out Mozilla’s documentation on regular expressions to learn how to write them.
Special comments only have an effect in downloaded filter lists, not in custom filters. They can set a number of parameters for the filter list:
! Homepage: http://example.com/- This comment determines which webpage should be linked as filter list homepage.
! Title: FooList- This comment sets a fixed title for the filter list. If this comment is present, the user is no longer able to change the title.
! Expires: 5 days- This comment sets the update interval for the filter list. The value can be given in days (e.g. 5 days) or hours (e.g. 8 hours). Any value between 1 hour and 14 days is possible. Note that the update will not necessarily happen after this time interval. The actual update time is slightly randomized and depends on some additional factors to reduce server load.
! Redirect: http://example.com/list.txt- This comment indicates that the filter list has moved to a new download address. Adblock Plus ignores any file content beyond that comment and immediately tries downloading from the new address. In case of success, the address of the filter list is updated in the settings. This comment is ignored if the new address is the same as the current address, meaning that it can be used to enforce the "canonical" address of the filter list.
! Version: 1234- This comment defines a numerical version of the filter list. This version number is displayed in issue reports and can be used to verify that the report refers to the current version of the filter list.
Unfortunately, there are some advertisements that can't be blocked at download time. This is because they’re embedded as text in the webpage itself. For that case, there are filters that run directly on the content of the page. They are split between two main types: element hiding and snippets.
Element hiding filters are designed to indicate which element in the page are to be hidden.
Snippet filters are used to run snippets of code in the page to defeat more complex advertising display.
Content filters follow the following structure.
domains- A domain or a list of comma-separated domain names. May be empty for element hiding filters.
separator- This sequence marks the end of the domain list and the start of the actual content filter. It determine the type of filter. The possible values are list below.
body- The body of the filter, depending on the type.
Here is a list of possible values:
||Element hiding||CSS selector (domains may be empty)|
||Element hiding emulation||Extended CSS selector|
||Element hiding exception||Selector|
Element hiding basic rules
If you look at the source code of the webpage, you might find something like this:
Cheapest tofu, only here and now!
Really cheap tofu, click here!
Only here you get the best tofu!
You’ll need to download the webpage in order to download the advertisements. After the webpage is downloaded, you can hide the advertisement(s) that you don’t want to see.
The example advertisement above is contained inside an element with the class attribute
textad. The rule
##.textad hides any such element. Here the separator
## marks an element hiding rule while the rest (the body) is a CSS selector identifying the elements that need to be hidden. You can hide elements by their ID attribute (similarly,
###sponsorad hides the second advertisement) and by their name (e.g.
##textad for the third advertisement).
Limiting rules to certain domains
Typically, you may want to hide a specific ad on one site, but don't want your rule to be applied to another site. For example, the rule
##.sponsor might hide valid code on some sites. But, if you write it as
example.com##.sponsor, it will be applied on
http://something.example.com/, but not on
http://example.org/. You can also specify multiple domains by simply separating them with commas:
If a domain name is preceded with
~, the rule is not applied on pages from this domain. For example,
~example.com##.sponsor is applied on pages from any domain, but
example.com,~foo.example.com##.sponsor make the rule apply on the
"example.com" domain with the exception of the
Some advertisers don't make it easy for you — their text advertisements have neither an ID nor a class attribute. You can use other attributes to hide those, for example
##table[width="80%"] hides tables with a width attribute set to 80%. If you don't want to specify the full value of the attribute,
##div[title*="adv"] hides all
div elements with a title attribute containing the string
"adv". You can also check the beginning and the end of an attribute, for example
##div[title^="adv"][title$="ert"] hides div elements with title starting with
"adv" and ending with
"ert". As you see, you can also use multiple conditions —
table[width="80%"][bgcolor="white"] matches tables with a width attribute set to 80% and
bgcolor attribute set to white.
In general, any CSS selector supported by your browser can be used for element hiding. For example the following rule hides anything following a
div element with class "adheader": ##.adheader + *. For a full list of CSS selectors, refer to W3C’s CSS selectors documentation. Please keep in mind that browsers are slower to process these types of selectors than selectors based on class or ID attribute only.
Extended CSS selectors (Adblock Plus-specific)
Sometimes the standard CSS selectors aren't powerful enough to hide an advertisement. For those cases, we’ve added some new selectors, namely:
:-abp-properties()(Adblock Plus 1.13.3 or higher for Chrome and Opera is required.)
When writing an element hiding filter that makes use of these extended selectors, you must use the
#?# syntax, e.g.
example.com#?#selector. It's important to note, however, that doing so creates a performance impact, so do so sparingly and make sure those filters are specific to as few domains and elements as possible.
:-abp-has(selector)selector selects elements based on their content. For example,
:-abp-has(> div > a.advertiser)selects elements that contain, as a direct descendant, a
<div>that contains an
<a>with the class advertiser. The inner selector can be relative to the element scope and can use any pseudo-selectors, including
:-abp-has(), to determine whether the selection will occur.
:-abp-contains(text)selector selects elements based on their text content. For example,
div.sidebar > span:-abp-contains(Advertisement)selects the elements within a
<div>, with a class of sidebar that contains the word "Advertisement". In practice, you'd want to combine this with a
:-abp-has()to select the outer container (something like
div.sidebar > div:-abp-has(span:-abp-contains(Advertisement))to select the container that contains an advertisement label).
:-abp-properties(properties)selector selects elements based on stylesheet properties. For example,
:-abp-properties(width:300px;height:250px;)selects elements that have a corresponding CSS rule in a stylesheet which sets the width and height to the values 300px and 250px, respectively. Property names are matched case-insensitively. Furthermore, wildcards can be used so that
:-abp-properties(width:*px;height:250px;)matches any width specified in pixels and a height of 250 pixels.
You can also use regular expressions by surrounding the properties expression with "/". For example,
:-abp-properties(/width:30[2-8]px;height:250px;/) matches widths between 302 and 308 pixels and a height of 250 pixels.
Exception rules can deactivate existing rules on particular domains. These are mostly useful to filter subscription authors who are extending another filter subscription that they cannot change. For example, the rule
##.textad can be deactivated on example.com using the exception rule
example.com#@#.textad. The combination of these two rules has exactly the same effect as the single rule
~example.com##.textad. It’s recommended that you use exception rules only when you cannot change an overly general element hiding rule. In all other cases, limiting this rule to the necessary domains is preferable. These exceptions will be applied to extended CSS selector rules as well.
Please refer to the snippet filters tutorial for a more detailled guide on how to write snippet filters.
Generic / Specific filters
$genericblock filter options, the distinction between generic and specific filters becomes important.
We classify a filter to be specific if it matches one or more domains, or matches a sitekey. If a filter has no domains specified (or only domain exceptions) and no sitekey, it then counts as generic. For example,
example.com##.textad is a specific filter, whereas both
~example.com##.textad are generic.
Note that when working with blocking rules the domain must be specified under the
$domain option for them to be considered specific. For example,
||example.com^ is considered generic whereas
/ads/*$domain=example.com is site-specific.
Implementing a sitekey on the server
To apply a sitekey-restricted filter, a webpage needs to return base64-encoded versions of the public key and a signature that Adblock Plus can validate. Currently, this means including them in both the HTTP response header (X-Adblock-Key: abcdpublickeydcba_abcdsignaturedcba) and the root tag of the document ().
Create a private RSA key and then a DER representation of the public key. The key should be at least 2048 bits in length, but preferably 4096 bits in length. The data used for creating the signature is a concatenated list of request variables (namely URI, host, and user agent) separated by the NUL character "\0". For example, For example,
/index.html?q=foo\0www.example.com\0Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0.
To generate the signature for this string, use the signature algorithm
SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE (default when using OpenSSL).