Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To block images in Puppeteer, enable request interception before navigation, abort requests whose browser-perceived resource type is image, and continue every other request:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.setRequestInterception(true);
page.on('request', request => {
  if (request.isInterceptResolutionHandled()) return;

  if (request.resourceType() === 'image') {
    request.abort();
  } else {
    request.continue();
  }
});

await page.goto('https://example.com');
await browser.close();

The listener must be installed before page.goto(). Once interception is enabled, every request pauses until Puppeteer continues it, aborts it, responds to it, or completes it from cache.

What image blocking does in Puppeteer

Puppeteer can observe each network request made by a page. Its request.resourceType() method reports the type Chromium assigned to that request, including image, script, stylesheet, font, xhr, fetch and document. Aborting only the requests classified as image prevents those downloads while leaving HTML, JavaScript, CSS and data requests available.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This is different from hiding images with CSS after they download. CSS changes the rendered page but does not prevent network transfer. Request interception stops the request at the network layer, so it is the appropriate method when your goal is to reduce image traffic or make a capture/rendering workflow independent of image downloads.

Complete implementation

Minimal ES-module script

Install Puppeteer in a Node.js project, then save this as an ES module (for example, block-images.mjs):

npm install puppeteer
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();

  await page.setRequestInterception(true);
  page.on('request', request => {
    if (request.isInterceptResolutionHandled()) return;

    if (request.resourceType() === 'image') {
      request.abort();
    } else {
      request.continue();
    }
  });

  await page.goto('https://example.com', {
    waitUntil: 'networkidle2'
  });

  await page.screenshot({ path: 'without-images.png', fullPage: true });
} finally {
  await browser.close();
}

waitUntil: 'networkidle2' is optional. It waits for a relatively quiet network, but pages with analytics, polling or other long-lived connections may never become completely idle. Use a selector wait or a bounded timeout when the page has continuing background traffic.

CommonJS version

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.setRequestInterception(true);
    page.on('request', request => {
      if (request.isInterceptResolutionHandled()) return;
      request.resourceType() === 'image'
        ? request.abort()
        : request.continue();
    });
    await page.goto('https://example.com');
  } finally {
    await browser.close();
  }
})();

Why the listener must run before navigation

page.setRequestInterception(true) affects requests made after interception is enabled. Registering the listener after page.goto() allows early document, preload or image requests to proceed normally. The safe order is: create the browser and page, enable interception, attach the request listener, then navigate.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not enable interception without resolving every request. If a handler neither calls continue(), abort() nor respond(), that request remains paused and page loading can appear to hang.

Choosing a blocking rule

Resource-type matching (recommended)

Use request.resourceType() === 'image' when you want to block what Chromium recognizes as an image, regardless of its URL. This catches image URLs without conventional extensions, such as CDN endpoints that return an image from a path like /asset?id=42.

URL-suffix matching

You can instead inspect request.url() and abort selected extensions:

const imageExtensions = /.(png|jpe?g|gif|webp|avif|svg)(?|#|$)/i;

page.on('request', request => {
  if (request.isInterceptResolutionHandled()) return;
  if (imageExtensions.test(request.url())) {
    request.abort();
  } else {
    request.continue();
  }
});

This is useful when a site-specific URL rule matters, but it is narrower than resource-type matching. It misses extensionless image endpoints and may match a URL that does not actually return an image. Do not combine an extension test with an assumption that all image URLs have file extensions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Blocking selected hosts or paths

For a targeted rule, combine the resource type with URL inspection:

page.on('request', request => {
  if (request.isInterceptResolutionHandled()) return;
  const url = request.url();
  const isTargetedImage = request.resourceType() === 'image' &&
    url.includes('images.example-cdn.test');
  isTargetedImage ? request.abort() : request.continue();
});

Keep the condition explicit so scripts, CSS and API calls from the same host continue to load.

Handling multiple request listeners safely

Several libraries or application modules may attach request listeners. More than one listener can then attempt to resolve the same request, producing Puppeteer’s “Request is already handled!” exception. Check request.isInterceptResolutionHandled() immediately before the resolution call:

page.on('request', request => {
  if (request.isInterceptResolutionHandled()) return;
  if (request.resourceType() === 'image') request.abort();
  else request.continue();
});

Keep the check and abort/continue/respond call together and synchronous. Do not check, await another operation, and resolve later; another listener can handle the request during that gap.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Cooperative interception priorities

When all handlers supply numeric priorities, Puppeteer’s cooperative mode selects the highest-priority action. If priorities tie, abort outranks respond, which outranks continue. A handler that omits a priority switches interception back to legacy behavior. If you compose third-party handlers, follow one consistent priority strategy or centralize the rules in a single listener.

What counts as an image—and what does not

  • Usually blocked: normal <img> resources, CSS background images and other requests Chromium classifies as image.
  • Not automatically blocked: an image embedded as a data URL, pixels drawn into a canvas, or an image fetched through an API and decoded by JavaScript. Those may appear as fetch or xhr, so blocking them requires a separate, site-specific rule.
  • Still allowed: stylesheets, fonts, scripts, documents and API requests, because the example continues every non-image request.

If a page relies on an image request to trigger application logic, aborting it can alter page behavior. Test the workflow’s required selectors and interactions rather than assuming only visual output changes.

Verification and diagnostics

Log classifications

page.on('request', request => {
  console.log(request.resourceType(), request.method(), request.url());
  if (request.isInterceptResolutionHandled()) return;
  request.resourceType() === 'image' ? request.abort() : request.continue();
});

Run this against the target page and check whether the unwanted request is reported as image. If it is fetch or xhr, a resource-type-only rule will not block it.

Count blocked requests

let blockedImages = 0;
page.on('request', request => {
  if (request.isInterceptResolutionHandled()) return;
  if (request.resourceType() === 'image') {
    blockedImages++;
    request.abort();
  } else {
    request.continue();
  }
});

await page.goto('https://example.com');
console.log(`Blocked ${blockedImages} image requests`);

This count describes requests handled by your listener, not a guaranteed bandwidth saving. Cached resources, redirects and page behavior can affect the actual transfer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshooting

The page hangs after interception is enabled

Cause: a request was left unresolved. Ensure every branch calls exactly one of continue(), abort() or respond(). Add logging before each branch and look for a handler that returns without resolving.

“Request is already handled!” appears

Cause: multiple listeners resolved the same request. Add the immediate isInterceptResolutionHandled() guard, remove duplicate listeners, or coordinate handlers with cooperative numeric priorities.

Images still appear

Confirm interception and the listener are installed before goto. Log resourceType(); the page may be using data URLs, canvas content, or image data returned through fetch/xhr. For ordinary extensionless image URLs, resource-type matching is preferable to suffix matching.

Scripts or styles stop working

Check that the non-image branch calls request.continue(). Avoid broad URL rules that match a shared CDN serving JavaScript or CSS. Restrict a host/path rule with resourceType() === 'image' where possible.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Navigation never reaches the selected wait condition

Image blocking can expose pages that already depend on perpetual analytics or polling requests. Replace an overly strict network-idle condition with waitForSelector, a deliberate delay, or a bounded timeout appropriate to the page.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability and cost considerations

Puppeteer’s official guidance does not publish a universal speed or bandwidth benchmark for this technique. The result depends on image count, image sizes, cache state, connection quality and page behavior. Measure your own workload if a precise improvement matters.

Request interception adds a decision point to every request, so keep the handler lightweight. Prefer a single synchronous listener, avoid asynchronous work inside it, and use a Set or precompiled regular expression for larger rule sets. Always close the browser in a finally block so failures do not leave Chromium processes running.

Aborting images can make screenshots incomplete, break lazy-loading logic, or change layout when dimensions are not reserved. If you need visual fidelity, consider allowing images after a required selector appears, or block only known decorative hosts rather than every image.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your goal is a clean screenshot rather than controlling a local Puppeteer session, ScreenshotNeo provides a website screenshot API and MCP server. A single request returns PNG, JPEG, WebP or PDF, and its capture options include full-page screenshots, CSS-selector elements, device and retina settings, waits, custom JavaScript and CSS, request blocking, cookies, headers and more.

Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

For a direct image request, see the ScreenshotNeo API documentation:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms along with newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing provides two months free. Create a free ScreenshotNeo account to try it without a card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Practical checklist

  • Enable interception before navigation.
  • Use resourceType() === 'image' for the general rule.
  • Continue every non-image request.
  • Guard each resolution with isInterceptResolutionHandled().
  • Use URL matching only when a narrower, site-specific rule is required.
  • Log classifications when images are not being caught.
  • Test lazy loading, canvas rendering and application logic after blocking.
  • Close the browser even when navigation fails.

Frequently Asked Questions

Can I block images on only one page in a browser?

Yes. Enable interception and attach the listener to that page object; other pages created in the same browser are unaffected unless you configure them separately.

Can request interception replace an ad blocker?

It can abort requests matching rules you define, but it is not a complete filter list or browser extension. You must maintain the hosts, paths or resource types your workflow requires.

Does aborting an image request remove its HTML element?

No. The element remains in the DOM, but its resource fails to load. Layout and scripts may react according to the page’s own error handling.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.