Guide

Clean screenshots: no ads, no cookie banners

Real pages are noisy. Two flags and a selector list capture the page somebody actually wanted, without consenting to anything on their behalf.

Render a news site cold and the screenshot is a consent modal with a page dimly behind it. Ads load late and shove the layout around. None of that is the thing you were trying to capture.

These are two different problems wearing one name, and Renderwolf treats them differently. Ads and trackers are network requests, so they are stopped before they load. Consent banners are elements injected by a script the site genuinely needs, so blocking that request would break the page - they are hidden with CSS after load instead.

The two flags

curl -X POST https://api.ironfang.uk/renderwolf/v1/screenshot \
  -H "Authorization: Bearer if_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.theguardian.com",
    "block_ads": true,
    "block_cookie_banners": true,
    "full_page": true
  }' \
  --output clean.png

block_ads drops requests to known ad and tracker networks - the ones that draw banners over content - so the page never spends time fetching them. block_cookie_banners hides the major consent frameworks and, just as importantly, undoes the scroll lock they set: without that, a full-page capture of a page that cannot scroll comes back one viewport tall.

Hidden, never accepted

Some screenshot services click "accept" on consent dialogs for you. Renderwolf will not. Clicking through is a consent decision made on the site owner's behalf, in a jurisdiction we do not know, and it gets recorded as theirs - that is not ours to do from a render farm. Hiding removes the banner from the picture without consenting to anything.

Removing anything else

Newsletter pop-ups, chat widgets, "download our app" bars: hide_selectors takes CSS selectors and hides whatever they match, applied after load so script-injected elements are covered.

{
  "url": "https://example.com/article",
  "block_cookie_banners": true,
  "hide_selectors": [".newsletter-modal", "#intercom-container", ".app-banner"]
}

Late content: wait for it, do not guess

A dashboard that fetches after first paint needs the capture to wait for the data, not for a stopwatch. wait_for_selector holds the render until the element that means "ready" exists, and fails loudly if it never appears - a half-drawn page returned as success is the worst outcome. wait_until: "networkidle" is the blunter tool for pages with no single ready marker.

{
  "url": "https://app.example.com/metrics",
  "wait_for_selector": "#chart-loaded",
  "block_ads": true
}

How the lists stay honest

The blocklists are deliberately short - a full filter list is tens of thousands of rules that each risk breaking a page - and a weekly canary renders real, banner-heavy sites against the exact lists that ship, so a consent framework changing its markup is something we find on a schedule rather than something you find in a screenshot.

Next