Skip to content

Fix blank page + chunk load errors after deploys#346

Open
HarmlessHarm wants to merge 3 commits into
developfrom
claude/empty-page-syntax-error-b3re8l
Open

Fix blank page + chunk load errors after deploys#346
HarmlessHarm wants to merge 3 commits into
developfrom
claude/empty-page-syntax-error-b3re8l

Conversation

@HarmlessHarm

Copy link
Copy Markdown
Collaborator

Summary

Fixes issue #264: returning users experiencing blank pages with "Unexpected token '<'" errors after deploys. The root cause is a service worker update race condition where a new SW activates mid-page-load and purges the old precache while the page is still loading old chunks, causing asset requests to fall through to SSR and return HTML instead of JavaScript.

Changes

Service Worker Update Strategy (quasar.conf.js, src-pwa/register-service-worker.js)

  • Removed skipWaiting: true from workbox options so new SWs install in the waiting state instead of activating immediately under a live page
  • Completely rewrote the SW registration hooks:
    • Deleted the counterproductive updated() handler that was clearing all caches (including the new precache)
    • Deleted the updatefound()registration.update() call
    • Added controllerchange listener to reload once when a waiting SW takes control (happens at page-load time)
    • Added visibility-change listener to check for updates when the user returns to the tab (throttled to once per minute)
    • If a waiting SW exists at registration time, send it SKIP_WAITING to activate it immediately while the page is barely started

Removed Dead Code (src-pwa/custom-service-worker.js)

  • Deleted the file; it was only used with InjectManifest mode but the app uses GenerateSW, so it was never active

Chunk Load Safety Net (src/router/index.js)

  • Added error handler to detect failed lazy-route chunk loads and auto-reload once (with a 30-second guard to prevent infinite reload loops)

Friendly Missing Asset Response (src-ssr/index.js)

  • Added middleware to intercept requests for missing static assets (hashed chunks from previous builds) before they reach the SSR catch-all
  • Returns a 400 status with a friendly "something went wrong, please reload" page instead of HTML served as JavaScript
  • Prevents "Unexpected token '<'" errors and provides a better UX for both automated chunk requests and direct user navigation

Result

  • Active sessions are never interrupted by SW updates; the new version applies on the next page load
  • The race condition is eliminated by construction: old precache stays intact while new SW waits
  • Residual chunk-load failures are self-healed with a single automatic reload
  • Missing assets fail cleanly with proper HTTP status codes instead of poisoning the page with HTML-as-script

https://claude.ai/code/session_01JZmaRYSXLRX3USEf7oMoGH

claude added 3 commits July 2, 2026 11:41
…sset 400 page (#264)

- Remove skipWaiting so a new service worker installs in the background
  and waits instead of purging the precache under a running session
- Check for updates on tab focus; activate the waiting worker on the
  next page load via SKIP_WAITING + one controllerchange reload
- Remove the delete-all-caches updated() handler (deleted the new
  precache too) and the dead custom-service-worker.js (ignored under
  GenerateSW)
- Reload once on ChunkLoadError via router.onError, with a 30s guard
  against reload loops
- Answer requests for missing static assets with a 400 + friendly
  reload page instead of SSR HTML, which caused 'Unexpected token <'
@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants