How to write filters

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.


All filter examples in this guide are only examples and are not meant to be used.

Table of contents

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.

Creating filters

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.

Blocking and hiding filters can be set to negate or reverse the effects of other filters. These are then considered exception filters.

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:

  1. Click the Adblock Plus icon and then click the gear icon in the upper-right corner.
    The Adblock Plus Settings tab opens.
  2. Select the Advanced tab and scroll to the Create and edit your filter list section.
  3. Click Start creating my filter list.
  4. 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 where 123 is a random number. Here, blocking the complete address won't help. You’ll need a more general filter, like*.gif, or even, which blocks everything in the “ads” directory.


Make sure that you don’t replace too much with wildcards. The filter will block all banners, but it’ll also block everything else from that you still might want to see.

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.


If you are unhappy with your filter adv blocking, you can define an exception rule @@advice. You only need to precede it by @@ to indicate an exception rule.

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 @@||^$document and you open a page from, 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 and *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 want to block all Flash, but if you add the filter swf, the address is also blocked. The solution is to add a pipe symbol (|) to the filter to show that there should be a definite end at this point. For example, the filter swf| blocks but not And the filter |http://baddomain.example/ blocks http://baddomain.example/banner.gif but not http://gooddomain.example/analyze?http://baddomain.example.

You might want to block as well as and 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: ||, and blocks all of these addresses while not blocking or http://gooddomain.example/analyze?

Marking separator characters

Sometimes, you might need to accept any separator character in a filter. For example, you might write a filter that blocks and but not Here, the symbol ^ can be used as a placeholder for a single separator character,^. 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: // : 8000 / ? a = 12 & b = %D1%82%D0%B5%D1%81%D1%82

This address can be blocked with the filters ^^ or ^%D1%82%D0%B5%D1%81%D1%82^ or ^^.


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).

Advanced features

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.



Here, /ads/* is the actual filter, and script and match-case are its options. Currently, the following options are supported:

Type options

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 document but 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 elemhide but 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 generichide but 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 $popup type 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 */BannerAd.gif$match-case blocks but not

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 restrictions

The option means that the filter should only be applied on pages from the domain. Multiple domains can be specified using | as the separator. For the option|, the filter is only applied on pages from or domains. If a domain name is preceded with ~, the filter should not be applied on pages from this domain. For example, means that the filter should be applied on pages from any domain but and| restricts the filter to the domain with the exception of subdomain.

Sitekey restrictions

The option 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 abcdsitekeydcba or 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

The option 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

The 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 $rewrite=abp-resource:blank-js sends an empty JavaScript. (Adblock Plus 3.5 or higher required.) Available internal resources are:

  • blank-text - empty text
  • blank-css - empty stylesheet
  • blank-js - empty JavaScript
  • 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
  1. rewrite= is restricted to certain domains using the $domain filter option. For more information, refer to the Domain restrictions section of this guide.
  2. rewrite= cannot be used together with the $third-party filter option, but can be used with $~third-party.
  3. 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 /banner\d+/ matches banner123 and banner321 but not banners. We recommend checking out Mozilla’s documentation on regular expressions to learn how to write them.


For performance reasons, we recommend avoiding regular expressions if possible.

Special comments

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: - 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: - 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.

Content Filters

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.

Basic rules

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:

Separator Type Body content
## Element hiding CSS selector (domains may be empty)
#?# Element hiding emulation Extended CSS selector
#@# Element hiding exception Selector
#$# Snippet filter Snippet

Element hiding basic rules

If you look at the source code of the webpage, you might find something like this:

<div class="textad"> Cheapest tofu, only here and now! </div> <div id="sponsorad"> Really cheap tofu, click here! </div> <textad> Only here you get the best tofu! </textad>

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, it will be applied on and, but not on You can also specify multiple domains by simply separating them with commas: domain1.example,domain2.example,domain3.example##.sponsor.

If a domain name is preceded with ~, the rule is not applied on pages from this domain. For example, is applied on pages from any domain, but "" and, make the rule apply on the "" domain with the exception of the "" subdomain.


Because of how element hiding is implemented, you can limit it only to full domain names. You cannot use any other part of the address and you cannot use domain as a replacement for domain.example,domain.test.

Attribute selectors

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.

Advanced selectors

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.


This functionality is recommended for advanced users. You should be comfortable with CSS selectors to use it. Adblock Plus won’t accept your custom filter if you use an invalid CSS syntax.

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-has()
  • :-abp-contains()
  • :-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. 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.

The :-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.

The filter hides all pages because the class is also contained somewhere in the <body>. To avoid hiding all pages, simply add > or +.

The :-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).

If you add the filter on and hard refresh, nothing changes. If you change the filter to and hard refresh, div.outer (which contains the middle section of the page) is blocked because somewhere within the <body> is the word "filters". To fix this, change the filter to After a hard refresh, only the headings of each article are hidden.

The :-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.


The old syntax for the CSS property filters is deprecated and will be automatically converted to the new format. The syntax to select the style properties remains the same.


When using the background-color property, use the rgb() notation. For example, instead of :-abp-properties(background-color: #3D9C4F;), use :-abp-properties(background-color: rgb(61, 156, 79)).


[-abp-properties='width:300px;height:250px;'] is converted to :-abp-properties(width:300px;height:250px;):-abp-properties() also selects elements using the style properties found in their pseudo-elements, like ::before and ::after. For example, :-abp-properties(content:'Advertisement') matches elements where the string Advertisement is found either ::before or ::after pseudo element.

Exception rules

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 using the exception rule The combination of these two rules has exactly the same effect as the single rule 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.


If you add the filter on, will not allowlist anything. If you add the filter will not allowlist anything. The filters must be exactly the same, i.e.

Snippet filters

Snippet filters allow running specialized code snippets (written in JavaScript) on pages with the list of specified domains. The body of the filter contain the snippet commands to run.

Please refer to the snippet filters tutorial for a more detailled guide on how to write snippet filters.


For security reasons, snippet filters can only be added to a user's custom filters list or in the ABP Anti-Circumvention Filter List, the latter being vetted and reviewed.

Generic / Specific filters

With the $generichide and $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, is a specific filter, whereas both ##.textad and 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, ||^ is considered generic whereas /ads/*$ 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\\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).

Was this article helpful?
245 out of 444 found this helpful