Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Playwright’s routing API: register a handler with page.route() for one page, or browser_context.route() for pages in a browser context. In the handler, inspect route.request.resource_type, call route.abort() for requests to block, and explicitly continue requests that should load. The examples below show both synchronous and asynchronous Python, how to choose the route’s scope, and the edge cases that can make a route appear not to work.
Block a resource type on one page
A route matches requests, not rendered elements. Match all URLs with **/*, check the browser-reported resource type, and abort only the category you want to block. Continue everything else; a matching request waits for the handler to resolve it.
Synchronous Python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.route(
"**/*",
lambda route: route.abort()
if route.request.resource_type == "image"
else route.continue_(),
)
page.goto("https://example.com")
browser.close()
This aborts image requests from that page and allows other matched requests to proceed. Register the route before navigating so it can handle requests triggered by the navigation.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchAsynchronous Python
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
async def handle_route(route):
if route.request.resource_type == "image":
await route.abort()
else:
await route.continue_()
await page.route("**/*", handle_route)
await page.goto("https://example.com")
await browser.close()
asyncio.run(main())
In asynchronous code, the handler must await the route action. The key behavior is the same in either API: abort the selected category and resolve the remaining requests with continue_().
#1 Best Overall
Other resource categories
Change "image" to the category that fits your test. Playwright’s request resource types include stylesheet, media, font, script, xhr, and fetch, among others. For example, to block fonts only, use route.request.resource_type == "font". Blocking scripts or stylesheets can substantially change page behavior and appearance, so do it only when that altered page is what your test is meant to examine.
Choose page scope or browser-context scope
| Route location | Coverage | Popup behavior | When to use it |
|---|---|---|---|
page.route() |
Requests made by that page | Does not intercept a popup page’s first request | Use when the policy applies to one page and popup initial navigation does not need coverage. |
browser_context.route() |
Requests made by pages in that browser context | Covers popup requests, including the popup’s initial request | Use when the policy should apply across pages or must cover popup startup. |
Register a context route before creating or navigating pages that should be covered:
context.route(
"**/*",
lambda route: route.abort()
if route.request.resource_type == "image"
else route.continue_(),
)
page = context.new_page()
page.goto("https://example.com")
If a page route and context route both match, the page route takes precedence. If more than one route on the same page matches a request, the most recently registered route takes precedence. Keep those precedence rules in mind when a broad blocking rule seems to override a narrower one—or vice versa.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesRank #2
Match by resource type or URL
Use route.request.resource_type when the rule is about what the browser is loading, such as images or fonts, regardless of the URL used to serve it. Use a URL pattern when the rule is about a particular path or filename pattern; the Playwright API examples include matching image extensions. A URL pattern is not the same as a resource-type test: one targets an address pattern, the other the browser’s classification of the request.
Both approaches use a route handler that must resolve matching requests. With a URL-specific rule, continue requests that match the pattern but should not actually be blocked; with a broad pattern such as **/*, explicitly allow every category outside your blocking condition.
Important routing behavior and caveats
Service workers can bypass routing
Page and context routing does not intercept requests intercepted by a service worker. If routes or expected network events appear to be missing, Playwright documents creating the context with service_workers="block" as a mitigation:
Rank #3
context = browser.new_context(service_workers="block")
Use that setting only when disabling service workers fits the test objective. If the application’s behavior with its service worker active is what you are testing, keep that environment intact and account for the documented routing limitation instead. See Playwright’s service worker guidance.
Free tools Windows power users keep installed
One-click scans. No signup required.
Redirects are not all routed independently by a page route
For redirects, a page route handler is called only for the first URL in the redirect chain. If a test depends on handling a later destination as a separate routed request, do not assume the page route will run again for it.
Routing disables the HTTP cache
Enabling routing disables the HTTP cache. A routed test can therefore behave differently from an otherwise similar test without routes, especially when you compare timings or repeat page loads. Treat that as a property of the test setup rather than assuming that the resource rule alone explains a timing difference.
Every matched request must be resolved
A request that matches a route stalls until its handler takes an action. The handler can continue it, abort it, or fulfill it. The examples here use an explicit allow path with continue_(); omitting that path can leave requests waiting rather than letting them reach the network. See the official Playwright Python network guide and the BrowserContext, Page, and Request API references.
Troubleshoot a route that does not behave as expected
- The page still loads images or another targeted category. Confirm the condition uses the exact resource type you intend, and that the route was registered before navigation or the request. Check whether a service worker is intercepting the requests; consider
service_workers="block"only if it is appropriate for the test. - The popup’s first page request was not blocked. A route registered with
page.route()does not intercept that initial popup request. Register the rule withbrowser_context.route()instead. - The page hangs or requests appear stalled. Ensure every matching request takes an action. Keep an explicit
continue_()branch for requests that should proceed. - A later redirect destination did not trigger the page handler. A page route handles only the first URL in a redirect chain; account for that limit when designing the test.
- Page-load timings changed after adding a route. Routing disables the HTTP cache. Compare like-for-like setups and avoid treating routed and unrouted runs as identical cache conditions.
- A newly registered rule appears to override another. Check both scope and registration order: page routes take precedence over context routes, and among matching routes on the same page the most recently registered takes precedence.
Performance, reliability, and test design
Blocking requests can make a test exercise a deliberately reduced version of a page, but it also changes what the page can render or execute. For example, blocking images changes visual output; blocking scripts may change application behavior; blocking stylesheets or fonts may change layout. Choose a resource category because it supports a specific test goal, not simply because it is available to block.
For stable results, register routes at the narrowest scope that covers the pages under test, make the allow path explicit, and account for service workers, redirects, and cache behavior. Do not compare a routed run’s load time directly with an unrouted run without noting that routing disables the HTTP cache. The documentation establishes these behavioral constraints, but does not provide a general speed improvement or performance figure for blocking resources.
Or skip the browser setup
If your goal is to get a clean screenshot rather than test which browser requests an application makes, ScreenshotNeo offers a website screenshot API and MCP server. It accepts a URL and returns a PNG, JPEG, WebP, or PDF. Its cleanup steps accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. AI agents can use its MCP server tools take_screenshot, get_page_info, and capture_pdf.
Python example (see the ScreenshotNeo documentation):
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Equivalent one-request examples:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month with no card.
Recommended Free Tools
Frequently Asked Questions
Does aborting an image request remove an image element from the page?
No. Routing aborts the network request; it does not remove or rewrite the page’s HTML. The page may still contain an image element whose resource failed to load.
Can I use request routing to test what happens when a resource fails?
Yes. Aborting a selected request lets the test exercise the page with that request unavailable. Keep the test’s purpose in view: the result reflects the intentionally altered network behavior, not an unmodified page load.
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.

