Add support for inspecting iframes#997
Open
karthikiyengar wants to merge 11 commits into
Open
Conversation
Upgrade to Manifest v3 and add iframe inspection support
5 tasks
jerelmiller
added a commit
that referenced
this pull request
Jun 29, 2026
### Summary This PR enables `apollo-client-devtools` to detect and interact with Apollo Clients running inside **same-origin iframes**, in addition to the main window. ### Problem Previously we only detected clients in the top-level window. If a page had iframes with their own Apollo Client instances, those clients were invisible to the extension. ### Solution 1. **Updated extension manifests**: Added `all_frames: true` to content scripts so `tab.js` and `hook.js` run in every frame (main window + iframes) 2. **Added multi-port architecture with frameId tracking**: Changed `background.ts` from tracking a single `tab` port per tab to a `Map<tabPorts, frameId>` per tab, enabling multiple frames to connect while tracking which frame each port belongs to 3. **Introduced client --> frame mapping**: Added a `clientFrames: Map<clientId, frameId>` to track which Apollo Client belongs to which frame, enabling targeted message routing 4. **Implemented frameId-based message routing**: RPC requests for a specific client are now routed only to the frame that owns that client, eliminating broadcast overhead 5. **Added SKIP_RESPONSE pattern for discovery**: The `getClients` handler in `hook.ts` uses `SKIP_RESPONSE` so frames without Apollo Clients don't pollute discovery responses ## Files Changed | File | Change | |------|--------| | [src/extension/chrome/manifest.json](cci:7://file:///Users/camillelawrence/Desktop/repos/apollo-client-devtools/src/extension/chrome/manifest.json:0:0-0:0) | Add `all_frames: true` | | [src/extension/firefox/manifest.json](cci:7://file:///Users/camillelawrence/Desktop/repos/apollo-client-devtools/src/extension/firefox/manifest.json:0:0-0:0) | Add `all_frames: true` | | [src/extension/rpc.ts](cci:7://file:///Users/camillelawrence/Desktop/repos/apollo-client-devtools/src/extension/rpc.ts:0:0-0:0) | Export `SKIP_RESPONSE` symbol + handler logic to skip sending responses | | [src/extension/background/background.ts](cci:7://file:///Users/camillelawrence/Desktop/repos/apollo-client-devtools/src/extension/background/background.ts:0:0-0:0) | `Set<tabPorts>` --> `Map<Port, frameId>`, add `clientFrames` mapping, implement targeted routing | | [src/extension/tab/hook.ts](cci:7://file:///Users/camillelawrence/Desktop/repos/apollo-client-devtools/src/extension/tab/hook.ts:0:0-0:0) | Add `SKIP_RESPONSE` to `getClients` handler for frames without clients | | [src/extension/tab/handleExplorerRequests.ts](cci:7://file:///Users/camillelawrence/Desktop/repos/apollo-client-devtools/src/extension/tab/handleExplorerRequests.ts:0:0-0:0) | Replace throw with silent return | | [development/client/public/iframe.html](cci:7://file:///Users/camillelawrence/Desktop/repos/apollo-client-devtools/development/client/public/iframe.html:0:0-0:0) | Test page for iframe scenarios | ## Automated Tests Added Two new unit tests in `src/extension/__tests__/rpc.test.ts`: | Test | Description | |------|-------------| | `does not send response when handler returns SKIP_RESPONSE` | Verifies that when a handler returns `SKIP_RESPONSE`, no RPC response message is posted | | `SKIP_RESPONSE allows handler to be re-registered after unsubscribe` | Verifies that handlers using `SKIP_RESPONSE` can be properly unsubscribed and re-registered | ## Manual Verification Steps 1. **Single frame (regression test)** - Load a page with a single Apollo Client (no iframes) - Open DevTools --> Apollo tab - Verify the client is detected and all features (Queries, Mutations, Cache) work normally 2. **Multi-frame detection** - Start dev server: `npm run start:dev` - Open Chrome with the extension loaded: `npm run chrome` - Navigate to `http://localhost:3000` - Add a client in the main window and a client inside the iframe - Verify **both clients** appear in the DevTools client dropdown 3. **Targeted routing verification** - With both clients (main window + iframe) registered from step 2 - Select the iframe's client in DevTools - Run queries/mutations and inspect the cache - In Chrome DevTools console for the **background script**, confirm RPC requests are routed only to the correct frame (look for `frameId` in console logs in dev mode) ## Limitations - **Same-origin only**: Per browser security, `all_frames: true` only works for same-origin iframes. Cross-origin iframes remain invisible. ## References - Closes #380 - Related: PR #828, PR #997 --------- Co-authored-by: Jerel Miller <jerelmiller@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prior discussions:
#951
#380
This PR adds support for using Apollo DevTools with iframes by leveraging the
all_framescapability afforded to browser extensions.Since we're using fork actively as an internally published extension, this branch also contains some changes that upgrades the extension from Manifest V2 to V3.