Industry gossipTechnical guides·10 min read

How to Modify Response Bodies in Chrome Extensions: Manifest V3 Guide & Best Tools (2026)

What changed, and who it hurts.

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.

2. Chrome DevTools Protocol (`chrome.debugger` API)

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 / ExtensionModify HeadersRedirect URLModify Response BodyJSON Deep MergeDelay / LatencyNo Warning BannerTeam Sync
ProxyCeptorYes (DNR)Yes (DNR)Yes (MAIN Hook)Yes (Recursive Merge)Yes (0–60s)Yes (Zero Banner)Yes (Cloud Workspace)
RequestlyYes (DNR)Yes (DNR)Yes (Page Hook)Via custom scriptYesYesYes (Paid)
ModHeaderYes (DNR)LimitedNoNoNoYesProfiles Export
DevTools Local OverridesYesNoYes (File-based)No (Full replace only)NoYesNo (Local disk only)
Postman InterceptorNo (Capture)NoNoNoNoYesVia 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

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.

Written by

Vimal Kumar SEM & Front-end

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.

“Now go break something safely.”

More from Vimal →

Read next

Intercept your first request in under a minute

Create a free ProxyCeptor account to mock, delay, block and rewrite API traffic, then share the same rules with your team.

🚀 Mock, delay and break API calls in ChromeTry ProxyCeptor free