Architecture: How to fix Chrome Private Network Access (PNA) blocking ifra...
Documentation for Sessions
🏗️ Architecture: How to fix Chrome Private Network Access (PNA) blocking ifra...
Date: 2026-02-11
Time: 13:18:09 UTC
Session: gspace1-105.7
Agent: angular
Confidence: 90%
Status: ✅ Documented
📋 Decision Context
Question:
How to fix Chrome Private Network Access (PNA) blocking iframe loading of localhost from chrome-extension:// origin?
Task: Fix Chrome PNA blocking iframe loading in extension sidepanel
🎯 Decision Made
Chosen:
PNA reverse proxy in dev-serve.js — when pnaProxy:true, Angular dev server runs on port+10000 (internal), a PNA-aware HTTP proxy on the original port handles OPTIONS preflight with 204 + PNA headers and proxies everything else including WebSocket
Options Considered:
- PNA proxy in dev-serve.js (chosen)
- @angular-builders/custom-esbuild middleware
- Standalone pna-proxy.js script
- Chrome declarativeNetRequest header injection
- Patch Vite CORS config in node_modules
💭 Reasoning
Angular's Vite dev server configures CORS with preflightContinue:true, so OPTIONS requests pass through to the route handler which 404s. The builder has no middleware/plugin extension point. Alternatives considered: (1) @angular-builders/custom-esbuild — adds dependency, (2) standalone proxy script — changes user workflow, (3) Chrome declarativeNetRequest — can't change status codes, (4) patch node_modules — fragile. The dev-serve.js approach is zero-dependency (uses already-installed http-proxy), same workflow, opt-in per app via pnaProxy flag, and handles WebSocket upgrade for HMR.
📁 Files Involved
tools/scripts/dev-serve.jsapps/gograb-ai/project.jsonapps/gograb-ai-extension/sidepanel/sidepanel.htmlapps/gograb-ai-extension/content/inject.js
🔗 Related
- Decision ID:
dev_1770815889499_3c53ac5 - Session: 105
- Workspace: gspace1
Auto-generated by MCP Smart Consolidation