Guide
How to block ads and trackers in one browser profile.
On this page
A system-wide ad blocker or a filtering DNS server changes every browser and app on your computer. Donut Browser filters per profile: one profile can block ads, trackers and malware domains while another loads everything. The filter works with a proxy, with a VPN and with no proxy at all, and it needs no extension. You need Donut Browser installed.
How the blocklist works
Each profile reaches the internet through a small Donut relay on your computer. With a blocklist on, the relay refuses a connection to a listed domain and to all of its subdomains before any lookup. The browser shows its own connection error for that request, and the page loads without it. No query for a blocked name leaves your computer.
The lists are the HaGeZi DNS blocklists. Donut downloads a list the first time a profile needs it, then refreshes the lists every 12 hours.
| Level | Source |
|---|---|
| None | No filtering |
| Light | HaGeZi Light |
| Normal | HaGeZi Multi Normal |
| Pro | HaGeZi Multi Pro |
| Pro++ | HaGeZi Multi Pro++ |
| Ultimate | HaGeZi Multi Ultimate |
| Custom | Your own sources and rules |
Each level from Light to Ultimate blocks more domains than the one before it, and a longer list breaks more sites. The domain count of each list is in the blocklist dialog (step 2).
1. Choose a level for the profile
Use one of these. The level applies from the next launch, so restart a running profile.
- In the profile table, click the profile’s DNS cell and choose a level.
- In Create new profile, open Advanced options and set DNS blocklist.
- For several profiles, select them and click Edit selected in the action bar. The Edit profiles dialog has a DNS blocklist field.
Ephemeral profiles can use a blocklist too.
2. Launch and test
Launch the profile and open a page with ads. Then open the same page in a profile with the level None and compare. If the list was not downloaded yet, the launch waits for it.
To see the lists, open Settings → DNS blocklist → “Block ads, trackers and malware” → Manage. The Blocklists tab shows each level with its badge (Fresh, Stale or Not cached), its domain count, size and date. Refresh All Lists downloads them again.
3. Build a custom list
The Custom lists tab in the same dialog builds one list that every profile with the level Custom uses.
| Field | What goes in it |
|---|---|
| Blocklist source URLs | One URL per line, for lists you want to merge in |
| Blocked domains | One domain per line |
| Allowed domains | Domains to take out of the compiled list. They win over every block rule. |
| Allowlist mode | When on, only the domains in Allowed domains (only these) load, with their subdomains. Everything else is blocked. An empty list turns filtering off. |
Click Save to compile the list. Import reads a .json or .txt file, and Export TXT and Export JSON write one.
Each line can be a plain domain (ads.example.com), a hosts-file line with 0.0.0.0, 127.0.0.1, :: or ::1, a wildcard (*.ads.example.com), or an adblock-style rule (||ads.example.com^). Lines that start with # or ! are comments.
Use domain lists only. Browser filter lists with element-hiding rules, such as example.com##.banner, do not work here: Donut cuts such a line at the #, and the rule then blocks all of example.com. Exception rules (@@) and rules with $ options in a source list are not understood either.
Allowlist mode suits a profile that must reach a few sites only, such as one web app for one account.
Another way: a filtering DNS server
Some public DNS servers return no answer for ad and tracker domains. Donut can send a profile’s DNS queries to one of them, through the profile’s proxy or VPN:
- Stop the profile and open its panel → Network.
- In the DNS field, enter a DNS over HTTPS address such as
https://adblock.dns.mullvad.net/dns-query, and save it.
When the server answers “no such domain”, Donut tells the browser the host is unreachable. You can use this together with a blocklist. If the DNS server does not answer, pages in the profile do not load.
Set the level with the API
PUT /v1/profiles/{id} has no blocklist field. Use the bulk editor route, which takes one or many profiles and works on every plan:
curl -sS -X POST http://127.0.0.1:10108/v1/profiles/bulk-edit \
-H "Authorization: Bearer $DONUT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile_ids": ["<profile id>"], "patch": {"dns_blocklist": "pro"}}'
# {"changed":1}const res = await fetch("http://127.0.0.1:10108/v1/profiles/bulk-edit", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.DONUT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
profile_ids: [profileId],
patch: { dns_blocklist: "pro" },
}),
});
console.log(res.status, await res.json());import os, requests
response = requests.post(
"http://127.0.0.1:10108/v1/profiles/bulk-edit",
headers={"Authorization": f"Bearer {os.environ['DONUT_API_KEY']}"},
json={"profile_ids": [profile_id], "patch": {"dns_blocklist": "pro"}},
timeout=10,
)
print(response.status_code, response.json())The values are none, light, normal, pro, pro_plus, ultimate and custom. "none" or null turns the filter off. An unknown value returns 400 with DNS_BLOCKLIST_INVALID, and a running profile returns 409; in both cases nothing changes. Templates take the same value in settings.dns_blocklist, and an AI agent can use the MCP tool update_profile_dns_blocklist. See Bulk-edit profiles.
What a DNS blocklist cannot do
A blocklist works on whole domains. It cannot hide an empty ad box, and it cannot block an ad that a site serves from its own domain, such as a video ad on the site’s own servers. For that, add a content-blocking extension to the profile. See Extensions.
Blocked requests do not show in Traffic Details, and Donut keeps no count of them.
Troubleshooting
| Problem | What to do |
|---|---|
| A site breaks or a button does nothing | Lower the level, or switch the profile to Custom and add the domain to Allowed domains. |
| An allowed domain is still blocked | Allowed domains match exactly. If example.com is on the list, allowing cdn.example.com does not free it. Allow the listed parent domain. |
| The launch fails with “Failed to fetch DNS blocklist” | Donut could not download the list. Check your connection, or choose another level. |
| A level change does nothing | The profile was running. Stop it and launch it again. |
| Pages do not load after you set a DNS server | The server does not answer through the profile’s route. Clear the profile’s DNS field. |
Related
- DNS and DNS blocklist: the settings in the app.
- How to use a SOCKS5 proxy with a username and password
- How to create many browser profiles, each with its own proxy
DNS blocklists are part of the free plan, for every profile. Download Donut Browser for macOS, Windows or Linux.
Last updated .