Guides / HTML to PDF
HTML to PDF

How to Remove Cookie Banners and Pop-ups Before Generating a PDF

Learn how to dismiss cookie banners, consent dialogs, and pop-ups before converting a web page to PDF.

Overview

When you convert a third-party URL with our HTML to PDF API, the page is loaded in a fresh browser session with no cookies. To the site, every request looks like a first-time visitor, so it shows its cookie consent banner, newsletter modal, or promo pop-up, and those overlays end up in your PDF, often covering the content you actually need.

This guide shows how to dismiss them before the PDF is captured. You can click through them with clickSelector or clickSelectorChainSetup, or hide them with the css and javascript parameters.

Find the right selector

Every option in this guide takes a CSS selector. To find one for the button or element you want to target:

  • Open the target URL in a private browser window, so the banner shows the same way it does for PDFGate.
  • Right-click the button (for example, "Accept all") and choose Inspect.
  • Look for a stable attribute: an id, a data-* attribute, or an aria-label.
  • Test it in the DevTools console with document.querySelector("#your-selector"). It should return exactly the element you want.

Prefer selectors that do not change between deployments. Consent platforms usually use fixed ids such as #onetrust-accept-btn-handler. Avoid generated class names like .css-1x9f2ab or .sc-bdVaJa, which change when the site is rebuilt.

Click a single button with clickSelector

If the banner closes with one click, pass the button's selector in clickSelector. The API waits for the element to appear, clicks it, and then continues rendering.

  • url: The page you want to convert.
  • clickSelector: CSS selector of the element to click before rendering.
CURL
NODE.JS
1curl https://api.pdfgate.com/generate/pdf \2  -X POST \3  -H "Content-Type: application/json" \4  -H "Authorization: Bearer YOUR_API_KEY" \5  --data '{6    "url": "https://example.com",7    "clickSelector": "#onetrust-accept-btn-handler"8  }' \9  -o output.pdf

clickSelector waits up to 30 seconds for the element. If it never appears, the request fails, and there is no option to continue without the click. If the banner does not show up on every request (for example, it only appears for some regions), use clickSelectorChainSetup instead: a chain with a single selector and ignoreFailingChains set to true generates the PDF whether or not the banner appears, as shown below.

Multi-step flows with clickSelectorChainSetup

Some banners need several clicks, for example opening the settings panel, rejecting all categories, and then confirming. clickSelectorChainSetup handles this with one or more chains of selectors.

  • chains: List of selector chains to run, from 1 to 20.
  • chains[].selectors: CSS selectors clicked in order, from 1 to 5 per chain.
  • ignoreFailingChains: Continues PDF generation even if every chain fails. Defaults to false.

Structure

1{2  "clickSelectorChainSetup": {3    "ignoreFailingChains": false,4    "chains": [5      { "selectors": ["#first-click", "#second-click"] },6      { "selectors": ["#alternative-click"] }7    ]8  }9}

How a chain runs:

  • Each selector is waited for (up to 5 seconds) and then clicked.
  • After each click, the API pauses for 300 ms so the next step of the UI can appear.
  • If a selector is not found within 5 seconds, that chain stops and is marked as failed. The remaining chains still run.
  • A chain succeeds only if every selector in it was found and clicked.

When clickSelectorChainSetup is set, clickSelector is ignored, so use one or the other.


Example: open settings, reject all, confirm

The selectors below are placeholders for a custom consent dialog. Replace them with the ones from your target site.

CURL
NODE.JS
1curl https://api.pdfgate.com/generate/pdf \2  -X POST \3  -H "Content-Type: application/json" \4  -H "Authorization: Bearer YOUR_API_KEY" \5  --data '{6    "url": "https://example.com",7    "clickSelectorChainSetup": {8      "chains": [9        {10          "selectors": [11            "#cookie-settings-button",12            "#reject-all-button",13            "#confirm-choices-button"14          ]15        }16      ]17    }18  }' \19  -o output.pdf

Multiple chains and failure handling

If you convert pages from many sites, or a site shows different banners depending on the visitor, add one chain per banner. All chains run in order, one after another. A chain whose first selector is not on the page simply fails and the next one starts.

With the default ignoreFailingChains: false, the request fails with a 422 error only when every chain fails. If at least one chain succeeds, the PDF is generated. Set ignoreFailingChains to true when it is acceptable for none of the pop-ups to appear, for example when a banner is only shown in some regions.

CURL
NODE.JS
1curl https://api.pdfgate.com/generate/pdf \2  -X POST \3  -H "Content-Type: application/json" \4  -H "Authorization: Bearer YOUR_API_KEY" \5  --data '{6    "url": "https://example.com",7    "clickSelectorChainSetup": {8      "ignoreFailingChains": true,9      "chains": [10        { "selectors": ["#onetrust-reject-all-handler"] },11        { "selectors": ["#CybotCookiebotDialogBodyButtonDecline"] },12        { "selectors": [".newsletter-modal .close-button"] }13      ]14    }15  }' \16  -o output.pdf

Each chain whose first selector is missing adds up to 5 seconds to the request. Keep the list to the banners you actually expect on the page.

Many sites use a consent management platform rather than a custom banner. The selectors below are commonly used by these platforms, but they are examples, not a guaranteed list: they can change when the platform updates its banner, differ between banner templates, and be customized by each site. Always confirm them on your target page and adjust them for your use case.


OneTrust

  • #onetrust-accept-btn-handler: The "Accept all" button.
  • #onetrust-reject-all-handler: The "Reject all" button, when the site enables it.
  • #onetrust-consent-sdk: The container of the banner, useful for hiding it with CSS.
1{2  "clickSelectorChainSetup": {3    "ignoreFailingChains": true,4    "chains": [5      { "selectors": ["#onetrust-reject-all-handler"] }6    ]7  }8}

Cookiebot

  • #CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll: The "Allow all" button.
  • #CybotCookiebotDialogBodyButtonDecline: The "Deny" button.
  • #CybotCookiebotDialog: The container of the dialog.
1{2  "clickSelectorChainSetup": {3    "ignoreFailingChains": true,4    "chains": [5      { "selectors": ["#CybotCookiebotDialogBodyButtonDecline"] }6    ]7  }8}

Rejecting non-essential cookies is usually the safer choice: it closes the banner without enabling tracking scripts that can add network requests and slow down rendering. Accepting is useful when the site hides content (such as embedded videos or maps) until consent is given.

Hide elements instead of clicking

If you do not need the site to register a consent choice, hiding the overlay is often simpler and faster. It does not wait for any element, so it never fails when the banner is missing.

  • css: CSS injected into the page before rendering.
  • javascript: JavaScript injected into the page before rendering.

Hide the banner containers with display: none !important. Many banners also lock scrolling on html or body, which can cut the PDF short, so reset overflow as well.

CURL
NODE.JS
1curl https://api.pdfgate.com/generate/pdf \2  -X POST \3  -H "Content-Type: application/json" \4  -H "Authorization: Bearer YOUR_API_KEY" \5  --data '{6    "url": "https://example.com",7    "css": "#onetrust-consent-sdk, #CybotCookiebotDialog, .newsletter-modal { display: none !important; } html, body { overflow: visible !important; }"8  }' \9  -o output.pdf

To remove the elements from the page entirely, pass a script in the javascript parameter:

1document2  .querySelectorAll("#onetrust-consent-sdk, #CybotCookiebotDialog, .newsletter-modal")3  .forEach((element) => element.remove());45document.documentElement.style.overflow = "visible";6document.body.style.overflow = "visible";

You can also combine both approaches: click to accept, then hide leftovers such as a floating "Cookie settings" button with css:

1{2  "url": "https://example.com",3  "clickSelectorChainSetup": {4    "ignoreFailingChains": true,5    "chains": [6      { "selectors": ["#onetrust-accept-btn-handler"] }7    ]8  },9  "css": "#ot-sdk-btn-floating { display: none !important; }",10  "delay": 100011}

Execution order and waiting

The API applies these options in the following order:

  • The page loads. With waitForNetworkIdle, the API also waits until there are no network connections.
  • waitForSelector waits for its element, up to 30 seconds.
  • clickSelector or clickSelectorChainSetup run.
  • javascript and then css are injected.
  • delay pauses before rendering.
  • loadImages scrolls the page and waits for images.

This has a few practical consequences:

  • Clicks happen before your css is applied, so hiding other elements never blocks a click.
  • delay runs after the clicks. Use it when accepting consent loads more content or triggers an animation you need to finish.
  • If a banner appears late, waitForSelector on the banner makes sure it is there before the clicks run.

For more on these options, see How to Wait for Dynamic Content Before Generating a PDF.

Additional Notes

Selectors are matched in the main document only. If a banner is rendered inside an <iframe>, it cannot be clicked. Hide the iframe or its container with css instead.

A banner that looks right in your browser may differ for PDFGate. Sites often show different banners per region, language, or screen size. If a chain fails unexpectedly, check the page with the same viewport and userAgent you send in the request, and consider adding an alternative chain.

Each request starts a new browser session, so consent is never remembered between requests. Include the click or hide options in every request.

For a full list of supported options, see the HTML to PDF API Reference.