Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesSome 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.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →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.
#1 Best Overall
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.
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:
Rank #2
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.
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.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →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 asimage. - 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
fetchorxhr, 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.
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.
Rank #4
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.
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.
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.
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
- 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.
Recommended Free Tools
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.
Quick Recap
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.

