dev: fix Vite HMR blocked by stale service worker CSP - #742
Merged
Merged
Conversation
The Vite HMR CSP overlay landed in #738, but the PWA service worker captures its CSP from the response that installed it and keeps using that snapshot until its own JS bytes change. Existing SWs in the browser pre-date the overlay, so cross-origin fetches to ``http://hostname:5173`` still hit a stale ``connect-src`` and get blocked from inside the SW's ``fetch`` handler — even after the page CSP is correct. ``cache_page(COMMON_TIMEOUT)`` on the SW URL compounded this: SW endpoints should never be server-cached because the browser uses byte-level diff to detect updates. - Skip non-GET and cross-origin requests in the SW ``fetch`` handler so Vite HMR (and any future cross-origin asset) is governed by the page CSP, not the SW's snapshot. Also a more conventional SW shape: there's no point caching cross-origin responses we can't reason about. - Add ``self.clients.claim()`` in ``activate`` to pair with the existing ``skipWaiting()``, so the replacement SW takes over open tabs in one reload instead of two. - Drop ``cache_page`` from the SW URL. Browsers handle SW update detection themselves; a server-side cache only pins content and CSP. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ajslater
added a commit
that referenced
this pull request
May 9, 2026
Brings in v1.11.5 release work: Vite HMR / service-worker / dev-server fixes (#738, #739, #742), the OCR-overlay revert (#741), comicbox 3.0.1, and assorted dep bumps (vuetify ^4.0.7, sass-loader ^16.0.8, @types/node ^25.6.2). No migration conflicts: the prior eda6461 merge already consolidated develop's ``0041_cleanup_phantom_comic_as_folder_rows`` into this branch's ``0041_browser_table_view``. The phantom-Comic cleanup ships as the final ``RunPython`` operation in that combined migration; the current merge brings no further migration churn from develop, so the 0041 file is unchanged. ``makemigrations --check --dry-run`` reports no drift. Verified: 193 backend tests + 27 frontend tests pass, ruff clean.
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.
Summary
Follow-up to #738 / #739. The Vite HMR CSP overlay was correctly added to the page CSP, but cross-origin Vite client fetches (
http://hostname:5173/static/@vite/client) were still being blocked from inside the PWA service worker:The CSP shown to the SW is missing both the
vite_hmrandschema_graphoverlays (both DEBUG-gated) — i.e. it's the snapshot the SW captured at install time, before the dev-only overlays existed. Service workers don't refresh their CSP unless their script bytes change, andcache_page(COMMON_TIMEOUT)on the SW URL was pinning the response server-side for an hour, blocking the byte-level diff that triggers SW updates.Changes
codex/templates/pwa/serviceworker.js—fetchhandler passes through non-GET and cross-origin requests, so Vite HMR is governed by the page CSP rather than the SW's snapshot. Also a more conventional SW shape: there's no point caching cross-origin responses.codex/templates/pwa/serviceworker.js— addedself.clients.claim()inactivateto pair with the existingskipWaiting(), so the replacement SW takes over open tabs in one reload instead of two.codex/urls/pwa.py— droppedcache_pagefrom/serviceworker.js. Browsers handle SW update detection themselves; a server-side cache only pins content and CSP.Test plan
Client().get('/serviceworker.js')— confirmedconnect-srcnow listsws://hostname:5173,http://hostname:5173, and thescript-srcVite origin.make fix/bun run lintclean (the pre-existingremark"Cannot process specified file" error is unrelated and present on develop without these changes).serviceworker.js. (Existing stale SW gets replaced on first reload thanks to byte change +clients.claim.)🤖 Generated with Claude Code