Manifest V3 removed blocking webRequest, leaving developers wondering how to modify response bodies. Here is why declarativeNetRequest cannot touch payloads and how modern interceptors bypass the limitation.
The short version
Chrome's declarativeNetRequest (DNR) API handles headers, redirects, and blocking, but cannot read or modify response bodies by design.
The three common workarounds are DevTools Local Overrides (manual, file-based), chrome.debugger CDP (triggers an annoying yellow banner), and MAIN-world fetch/XHR interception.
ProxyCeptor uses a dual-engine architecture: DNR handles network-level rules, while an in-memory page script safely hooks fetch and XMLHttpRequest to provide full body mocks, recursive JSON deep merge, and latency injection without warnings.
The Manifest V3 dilemma: why declarativeNetRequest cannot touch response bodies
Under Chrome Manifest V2, developers used chrome.webRequest.onBeforeRequest and webRequestBlocking to synchronously intercept network streams and rewrite response payloads. To improve browser performance and security, Google deprecated blocking webRequest in Manifest V3, replacing it with declarativeNetRequest (DNR).
While declarativeNetRequest is fast and privacy-preserving, it has a major architectural constraint: the browser executes rules declaratively, meaning extension code never touches the raw response stream. DNR can block requests, redirect URLs, upgrade HTTP to HTTPS, and modify request/response headers. It cannot inspect, rewrite, or mock response bodies.
The 3 ways developers attempt to modify response bodies in Manifest V3
1. Chrome DevTools Local Overrides (native, but rigid)
Chrome DevTools lets you right-click a network request and select Override content. Chrome saves a static file to your local disk and serves it on reload. While useful for quick CSS or HTML edits, it fails for dynamic APIs: it cannot change HTTP status codes (e.g. simulate a 500 or 429), cannot inject delays, cannot partially merge JSON, and cannot be shared across a team. See DevTools Local Overrides vs a proxy interceptor.
Extensions can attach to a browser tab using chrome.debugger and use Fetch.requestPaused to fulfill requests with custom response bodies. However, this triggers a persistent yellow warning bar across the top of the browser: *"ProxyCeptor started debugging this browser"*. This makes it unsuitable for daily developer workflows, automated QA, and screen recordings.
3. MAIN-world fetch and XMLHttpRequest hooking (the modern standard)
Because extensions cannot touch bodies in the service worker, modern interceptors inject a script into the page's MAIN execution world (via chrome.scripting.executeScript({ world: "MAIN" }) or registered content scripts). This script monkey-patches window.fetch and window.XMLHttpRequest directly in the web app's runtime context, catching requests before they reach application code and returning synthetic or modified responses.
Capability matrix: what can actually modify response bodies in 2026?
Tool / Extension
Modify Headers
Redirect URL
Modify Response Body
JSON Deep Merge
Delay / Latency
No Warning Banner
Team Sync
ProxyCeptor
Yes (DNR)
Yes (DNR)
Yes (MAIN Hook)
Yes (Recursive Merge)
Yes (0–60s)
Yes (Zero Banner)
Yes (Cloud Workspace)
Requestly
Yes (DNR)
Yes (DNR)
Yes (Page Hook)
Via custom script
Yes
Yes
Yes (Paid)
ModHeader
Yes (DNR)
Limited
No
No
No
Yes
Profiles Export
DevTools Local Overrides
Yes
No
Yes (File-based)
No (Full replace only)
No
Yes
No (Local disk only)
Postman Interceptor
No (Capture)
No
No
No
No
Yes
Via Postman
How ProxyCeptor implements dual-layer interception
Rather than choosing between declarative speed and response body flexibility, ProxyCeptor combines both into a unified engine with zero certificate installation:
Layer 1: DeclarativeNetRequest (DNR): Handles fast, network-level operations before requests leave the browser. It manages host redirects (e.g. redirecting production APIs to localhost:3000), blocking tracking pixels, and injecting Authorization or CORS headers.
Layer 2: In-Memory Main-World Interceptor: Injects a lightweight hook into window.fetch, XMLHttpRequest, and navigator.sendBeacon. When a matching request resolves, it can completely replace the payload (replace-whole), execute custom JavaScript transforms (execute-js), or apply Recursive JSON Deep Merge (`merge-json`).
Smart TV Parity: Because Layer 2 operates in standard JavaScript rather than privileged extension APIs, the exact same rules run on Samsung Tizen, LG webOS, and Android TV through the ProxyCeptor SDK with zero root CA certificates.
Code walkthrough: how to intercept and modify fetch in Manifest V3
Here is the conceptual pattern used by modern interceptors to hook window.fetch inside the MAIN world without breaking standard web APIs:
proxyceptor-rule.code
CODE
1
Security checklist before installing an interceptor extension
Ensure the extension explicitly declares when traffic leaves your machine. ProxyCeptor keeps all traffic, logs, and rules strictly local unless you explicitly opt into Cloud Workspace sync.
Verify that the extension operates without requiring system-wide Root CA certificate installation. Traditional desktop proxies (Charles, Fiddler) decrypt all machine traffic; browser-level interceptors only inspect what you configure.
Always disable active mock rules when concluding QA testing to prevent unexpected stale data during production browsing.
Frequently asked questions
Can a Chrome extension modify the response body in Manifest V3?
Not through declarativeNetRequest alone. In Manifest V3, extensions must inject an interceptor into the page's MAIN execution world to hook window.fetch and XMLHttpRequest, or use the chrome.debugger API (which triggers a prominent browser warning banner). ProxyCeptor uses the MAIN-world injection approach for seamless, banner-free body mocking.
What is the difference between declarativeNetRequest and fetch interception?
declarativeNetRequest (DNR) is a browser-level API that modifies requests (headers, redirects, blocking) before they hit the network, but cannot see or alter response bodies. Fetch interception operates inside the web application's JavaScript runtime, allowing full inspection and modification of JSON payloads, status codes, and response timing.
How do I modify JSON response fields without overwriting the entire payload?
Use ProxyCeptor's Recursive JSON Deep Merge (merge-json) rule. It fetches the real response from your live API, deeply merges your delta patch into the response object, and delivers the combined result to the UI. This allows you to test edge cases while keeping the remaining 99% of live production data intact.
Can I simulate slow network latency on a single API endpoint in Chrome?
Yes. Chrome DevTools Network throttling throttles the entire browser connection. With an interceptor like ProxyCeptor, you can set a granular delay (e.g. 3,500ms) on a specific URL pattern while all other network calls run at full speed.
Vimal builds the front-end and runs the search and campaign side of ProxyCeptor, which means he cares about how a page feels and how people find it. He writes code-first guides for developers: the snippet comes before the theory, and the loading spinner gets a fair trial. Expect practical steps, honest opinions about browsers and a soft spot for a well-behaved fetch call.
Local Overrides is Chrome's built-in way to fake a response. It is great for quick edits and awkward for everything else. Here is exactly where the line is.