Block ads and cookie banners in screenshots

Remove cookie consent banners and ads from screenshots and PDFs: what blockCookieBanners and blockAds do, which requests they stop, and what they leave alone.

Updated

Cookie banners and ads cover the content that a screenshot is for. This guide shows the two options that remove them, blockCookieBanners and blockAds, and what each one does to the page.

Turn both on

curl -X POST https://api.wayfern.com/api/v1/screenshot \
  -H "Authorization: Bearer $WAYFERN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/news/article",
    "capture": {
      "blockCookieBanners": true,
      "blockAds": true
    }
  }'

The capture costs 5 credits, the same as without the options. Both options also work in the capture object of a scrape with the screenshot or pdf format.

OptionREST defaultMCP default
blockCookieBannerstruetrue (block_cookie_banners)
blockAdsfalsetrue (block_ads)

blockAds is off by default on the REST API, so existing requests give the same images as before. The MCP tool turns it on, because an agent wants the content.

With blockCookieBanners, Wayfern does two things before the capture:

  1. It looks for a known control of a consent banner and clicks the first visible one. It tries accept controls first, then close controls, then reject controls. It clicks one control only.
  2. It hides the banner containers that are left with CSS, and turns scrolling back on for the page.

The second step matters for full-page captures. Many consent tools lock the page scroll while the banner shows. Without the fix, a full-page capture stays at the viewport height after the banner is gone.

Every step is best effort. A page with no banner, or with a banner that Wayfern does not know, is captured as it is. The request does not fail.

Ads and trackers

With blockAds, Wayfern also does two things:

  1. While the page loads, it aborts every request to a known ad or tracker host. The list holds ad servers, ad exchanges, content recommendation widgets, measurement pixels and session recording tools. A host matches when it is on the list or is a subdomain of a listed host, so securepubads.g.doubleclick.net matches doubleclick.net.
  2. Before the capture, it hides common ad slots that stay in the layout, such as Google ad units and recommendation widgets.

The blocked requests never leave the browser. The page does not download the ads, so a residential exit transfers fewer bytes, and residential bytes are metered.

What blockAds does not do:

  • It never blocks the page that you asked for. A screenshot of an ad network’s own site shows that site.
  • It does not block ads that a site serves from its own domain. Hide them with hideSelectors.
  • It does not hide generic elements such as a .ad class, because that name also appears in normal content.

Remove what is left

Some pages have other overlays: a newsletter popup, a chat button or a sticky header. Hide them with hideSelectors:

{
  "url": "https://example.com/news/article",
  "capture": {
    "blockAds": true,
    "hideSelectors": ["#newsletter-modal", ".chat-launcher", "header.sticky"]
  }
}

Each selector is set to display: none. You can give at most 50, each at most 512 characters. A selector that the browser cannot parse fails the request with 422 and error: "action_failed", so a typo does not leave the element in the image without notice.

To close a popup with its own button instead, use click. The page changes guide explains click, styles and scripts.

Check the result

The cleanup can only remove what it recognizes. When a page shows a wall instead of content, such as a sign-in prompt or a “verify you are human” page, the cleanup cannot help. Add capture.failIfContains with the text of that wall. The request then fails with content_matched and is not charged. See the content check guide.

Every field is in the Screenshot API reference.