Menu
Sign up

Hide chat widgets and other elements before a screenshot: selectors that worked, and one that blanked the page

Remove chat widgets, promo bars and pop-ups from website screenshots with CSS selectors: what worked on Intercom, HubSpot and Zendesk, and one trap.

Published November 8, 2026 · 4 min read

Chat launchers, "We're hiring" bars, newsletter pop-ups and floating feedback tabs are useful on a live site and noise in a screenshot. They sit on top of the page, usually in a corner, and the fix is always the same: hide them before the capture. This page shows how, with the selectors that worked on four real sites, what ad blocking does not do, and the mistake that turned one of our captures into a white rectangle.

How we tested. On 2026-11-08 we captured the home pages of intercom.com, hubspot.com, zendesk.com and crisp.chat at 1280×800 through our screenshot API: plain, with ad and tracker blocking, and with hide_selectors. We found the selectors with Chrome DevTools in a separate browser session.

Blocking ads does not remove chat widgets

Site Chat widget on the page With block_ads + block_trackers
intercom.com launcher, bottom right still there
hubspot.com launcher and a greeting bubble still there
zendesk.com launcher, bottom right still there
crisp.chat none appeared in our captures —

Filter lists such as EasyList target ads and trackers; a site's own chat is neither. Cookie banners are a separate case with their own option (see cookie banners in screenshots). Everything else is hidden by selector.

Selectors that worked

curl -X POST "https://shareglint.com/v1/screenshots?wait=true" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.hubspot.com/", "block_cookie_banners": true,
       "hide_selectors": ["#hubspot-messages-iframe-container"]}'
Widget Selector Result
Intercom #intercom-container (plus .intercom-lightweight-app for the light launcher) launcher gone
HubSpot chat #hubspot-messages-iframe-container launcher and greeting gone
Zendesk's own site button[aria-label="Open chat"] launcher gone

The first two are the containers these vendors' standard widgets put into a page, so they usually work on other sites that use the same chat. The Zendesk one is that site's own button; on another site, look for the container its chat puts in the page. When you capture many unknown sites, a list of the common containers costs nothing on pages that lack them:

"hide_selectors": ["#intercom-container", ".intercom-lightweight-app",
                   "#hubspot-messages-iframe-container", "#crisp-chatbox", "iframe#launcher"]

hide_selectors takes up to 20 selectors. Each becomes its own display: none !important rule in a stylesheet added to the page, so an invalid selector cancels only itself, and the rule also hides elements that appear after it was added — chat widgets usually load a few seconds late.

The selector that blanked the page

Our first try on Zendesk was to hide "the box that holds the button", to catch anything drawn around it: div:has(> button[aria-label="Open chat"]). The capture came back completely white. In DevTools the button's parent turned out to be the page's main wrapper, a div 1265 px wide and 12,202 px tall, with the fixed-position button as one of its nine children. The selector was right about the structure and hid the whole site.

Two habits avoid this:

  • Hide the widget, not its neighbourhood. Prefer the element with the widget's own id, aria-label or title; be careful with :has(), parent selectors and bare tag names (iframe hides every embedded video and map too).
  • Test the selector first. In DevTools, document.querySelectorAll('your selector') in the console lists what it matches; hover the result to see each element's box on the page.

Clicking instead of hiding

Some overlays are better closed than hidden: a modal that dims the page behind it, a "choose your country" dialog, a promo bar with a close button. Hiding the dialog leaves the dimmed backdrop; clicking its close button lets the site remove both. click_selector takes a selector, or a list clicked in order, before the capture:

"click_selector": ["button[aria-label=\"Close\"]"]

A click that finds nothing fails the capture with the selector named, rather than returning a picture you did not ask for, so use it on sites you know.

In your own Puppeteer code

The same technique, without our API:

await page.goto(url, { waitUntil: 'load' });
await page.addStyleTag({ content: `
  #intercom-container, .intercom-lightweight-app,
  #hubspot-messages-iframe-container { display: none !important; }
` });
await page.screenshot({ path: 'shot.png' });

Add the style after the page has loaded but before the screenshot. Writing all selectors into one rule, as above, has a catch: one invalid selector makes the browser drop the whole rule (MDN: selector lists), so keep one rule per selector if the list comes from users. ## When the site is yours

For your own pages it is simpler still: tell the chat not to show itself on the URL you capture. Intercom's messenger settings have hide_default_launcher ("Hide the default launcher icon", Intercom docs); HubSpot's chat can be kept from loading with window.hsConversationsSettings = { loadImmediately: false } (HubSpot docs). Read a parameter such as ?screenshot=1 in your page and set them only then, so visitors keep their chat and the screenshot service gets a clean page. The same parameter can switch off a promo bar, a cookie banner you control, or an A/B test that would make two captures of the same page differ.

Cost

Hiding and clicking add nothing to the price: a viewport capture is 1 render of the quota, a full page 2, and the same options within 24 hours are served from cache (pricing). All options are in the screenshot API reference; for clean thumbnails in bulk, see website thumbnails.

FAQ

How do I hide a chat widget in a screenshot?

Hide its container with CSS before the capture: display: none !important on a selector that matches the widget and nothing else. In our test #intercom-container removed Intercom's launcher, #hubspot-messages-iframe-container HubSpot's chat, and button[aria-label="Open chat"] Zendesk's. With our API, pass them in hide_selectors.

Do ad blockers remove chat widgets from screenshots?

Not the ones we tried. With block_ads and block_trackers on, the chat launchers on intercom.com, hubspot.com and zendesk.com were all still in the picture. Chat widgets are first-party features, not ads; hide them by selector.

Why did my screenshot come out blank after hiding an element?

The selector matched more than the element. On zendesk.com, div:has(> button[aria-label="Open chat"]) looked like "the chat button's box", but the button's parent was the page's main wrapper, 12,202 px tall: hiding it left a white screenshot. Check what a selector matches in DevTools before using it.