Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commite164a80unknown_key

Merge pull request #83 from ccantynz-alt/claude/review-readme-docs-ulqPK

Merge pull request #83 from ccantynz-alt/claude/review-readme-docs-ulqPK

fix(pwa): infinite reload loop on first SW install (incognito, fresh …
CC LABS App committed on May 15, 2026Parents: 46aff88 6345c3e
1 file changed+178e164a806a3308a7608718ccd2c057977dc957c5e
1 changed file+17−8
Modifiedsrc/views/layout.tsx+17−8View fileUnifiedSplit
537537// Block G1 — register service worker for offline / install support.
538538// Kept inline (and tiny) so we don't block first paint.
539539//
540// Block S2 extension — when an updated SW activates we force a single
540// Block S2 extension — when an UPDATED SW activates we force a single
541541// reload so the user picks up the fresh HTML immediately instead of
542// being stuck on the previous deploy's cached page (the "I saw /login's
543// old version even after merging" bug that triggered S2 in the first
544// place). The reload only fires when `controller` is already set, which
545// means this is NOT the first-ever install (no double-load on first
546// visit). A page-scoped guard prevents reload loops if the SW updates
547// twice in quick succession.
542// being stuck on the previous deploy's cached page.
543//
544// Critical: snapshot \`navigator.serviceWorker.controller\` BEFORE
545// registration. The SW's activate handler calls clients.claim() which
546// sets the controller during first install — so checking the controller
547// at statechange-time was always truthy and produced an infinite reload
548// loop on every first visit (incognito tab, fresh browser, etc).
549//
550// New guard: only reload if there was a previously-controlling SW at
551// page load. First-install path stays a single page render.
548552const pwaRegisterScript = `
549553 if ('serviceWorker' in navigator) {
554 var hadControllerAtLoad = !!navigator.serviceWorker.controller;
550555 window.addEventListener('load', function(){
551556 navigator.serviceWorker.register('/sw.js').then(function(reg){
552557 var reloaded = false;
554559 var newSW = reg.installing;
555560 if (!newSW) return;
556561 newSW.addEventListener('statechange', function(){
557 if (newSW.state === 'activated' && navigator.serviceWorker.controller && !reloaded) {
562 if (
563 newSW.state === 'activated' &&
564 hadControllerAtLoad &&
565 !reloaded
566 ) {
558567 reloaded = true;
559568 window.location.reload();
560569 }
561570