Fix Firefox silently upgrading ws:// to wss:// against the dev backend

Firefox's implicit default extension-pages CSP includes
upgrade-insecure-requests, which rewrites the WS client's plain
ws://localhost:8080/ws connection to wss:// -- which nothing is
listening on, since the local dev backend has no TLS (deliberately;
see backend/CLAUDE.md). Symptom was silent: a CSP console message
about the upgrade, then a failed connection with no other signal.

Declaring an explicit content_security_policy.extension_pages in
wxt.config.ts (otherwise identical to Firefox's own default) replaces
the implicit one and drops the upgrade directive. Gated to
browser === 'firefox' since Chrome doesn't have this behavior and its
MV3 CSP can't be loosened this way regardless.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YXiHuScXrjxBh7yFGAPq3B
This commit is contained in:
2026-09-07 13:17:02 +02:00
co-authored by claude
parent 3bb1c2f0c8
commit 9f06a83b64
2 changed files with 13 additions and 2 deletions
+12 -2
View File
@@ -6,7 +6,7 @@ export default defineConfig({
modules: ['@wxt-dev/module-react'],
// Target Manifest V3 on both Chromium and Firefox (modern Firefox / Zen support it).
manifestVersion: 3,
manifest: {
manifest: ({ browser }) => ({
name: 'Nexa',
description: 'Your blockchain powered agent to help with your trading emotions.',
permissions: ['storage'],
@@ -20,5 +20,15 @@ export default defineConfig({
id: '[email protected]',
},
},
},
// Firefox's implicit default extension-pages CSP includes
// upgrade-insecure-requests, which silently rewrites our ws:// WS client
// connections to wss:// and breaks them against the plaintext local dev
// backend (no TLS in dev — see backend/CLAUDE.md). Declaring our own CSP
// (identical to the standard default otherwise) replaces Firefox's
// implicit one and drops that directive. Chrome doesn't have this
// behavior, so this is Firefox-only.
...(browser === 'firefox'
? { content_security_policy: { extension_pages: "script-src 'self'; object-src 'self'" } }
: {}),
}),
});