Make sw.js non-cacheable and self-update so the worker fix actually reaches clients
The sw.js file was cacheable (text/javascript, not covered by the HTML no-cache rule), so browsers/CDN kept serving the old v1 worker and never picked up the v2 fix. Serve sw.js with no-cache/no-store, call reg.update() on load, and reload once on controllerchange so stale cached pages are dropped immediately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -221,7 +221,16 @@
|
|||||||
@* Register the PWA service worker (offline + push notifications). *@
|
@* Register the PWA service worker (offline + push notifications). *@
|
||||||
<script>
|
<script>
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
window.addEventListener('load', function () { navigator.serviceWorker.register('/sw.js').catch(function () {}); });
|
window.addEventListener('load', function () {
|
||||||
|
navigator.serviceWorker.register('/sw.js').then(function (reg) {
|
||||||
|
reg.update(); // always check for a newer worker so fixes reach clients fast
|
||||||
|
// When a new worker takes control, reload once so stale cached pages are dropped.
|
||||||
|
var refreshed = false;
|
||||||
|
navigator.serviceWorker.addEventListener('controllerchange', function () {
|
||||||
|
if (refreshed) return; refreshed = true; location.reload();
|
||||||
|
});
|
||||||
|
}).catch(function () {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -335,7 +335,12 @@ app.MapPost("/like", async (HttpContext ctx, AppDbContext db, [FromForm] string
|
|||||||
return Results.Json(new { liked, count });
|
return Results.Json(new { liked, count });
|
||||||
}).RequireAuthorization().DisableAntiforgery();
|
}).RequireAuthorization().DisableAntiforgery();
|
||||||
|
|
||||||
app.MapGet("/sw.js", () => Results.Content("""
|
app.MapGet("/sw.js", (HttpContext ctx) =>
|
||||||
|
{
|
||||||
|
// The worker file must NEVER be cached — otherwise an old worker keeps serving stale pages and
|
||||||
|
// browsers never pick up a new version (the fix can't reach clients because the file is cached).
|
||||||
|
ctx.Response.Headers.CacheControl = "no-cache, no-store, must-revalidate";
|
||||||
|
return Results.Content("""
|
||||||
const CACHE = 'hamkadr-v2';
|
const CACHE = 'hamkadr-v2';
|
||||||
const OFFLINE = '<!doctype html><html lang="fa" dir="rtl"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>آفلاین</title><body style="font-family:Vazirmatn,system-ui,sans-serif;text-align:center;padding:48px 20px;color:#334155"><h2 style="margin:0 0 8px">اتصال اینترنت برقرار نیست</h2><p style="color:#64748b">صفحه باز نشد؛ اتصال خود را بررسی و دوباره تلاش کنید.</p><button onclick="location.reload()" style="margin-top:14px;padding:10px 24px;border:0;border-radius:10px;background:#0d9488;color:#fff;font:inherit;cursor:pointer">تلاش دوباره</button></body></html>';
|
const OFFLINE = '<!doctype html><html lang="fa" dir="rtl"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>آفلاین</title><body style="font-family:Vazirmatn,system-ui,sans-serif;text-align:center;padding:48px 20px;color:#334155"><h2 style="margin:0 0 8px">اتصال اینترنت برقرار نیست</h2><p style="color:#64748b">صفحه باز نشد؛ اتصال خود را بررسی و دوباره تلاش کنید.</p><button onclick="location.reload()" style="margin-top:14px;padding:10px 24px;border:0;border-radius:10px;background:#0d9488;color:#fff;font:inherit;cursor:pointer">تلاش دوباره</button></body></html>';
|
||||||
self.addEventListener('install', e => { self.skipWaiting(); e.waitUntil(caches.open(CACHE).then(c => c.add('/'))); });
|
self.addEventListener('install', e => { self.skipWaiting(); e.waitUntil(caches.open(CACHE).then(c => c.add('/'))); });
|
||||||
@@ -368,7 +373,8 @@ self.addEventListener('notificationclick', e => {
|
|||||||
const url = (e.notification.data && e.notification.data.url) || '/';
|
const url = (e.notification.data && e.notification.data.url) || '/';
|
||||||
e.waitUntil(clients.matchAll({ type: 'window' }).then(cl => { for (const c of cl) { if ('focus' in c) { c.navigate(url); return c.focus(); } } return clients.openWindow(url); }));
|
e.waitUntil(clients.matchAll({ type: 'window' }).then(cl => { for (const c of cl) { if ('focus' in c) { c.navigate(url); return c.focus(); } } return clients.openWindow(url); }));
|
||||||
});
|
});
|
||||||
""", "text/javascript"));
|
""", "text/javascript");
|
||||||
|
});
|
||||||
|
|
||||||
// ---- SEO: robots.txt + dynamic sitemap.xml (so Google indexes every live shift/job page) ----
|
// ---- SEO: robots.txt + dynamic sitemap.xml (so Google indexes every live shift/job page) ----
|
||||||
app.MapGet("/robots.txt", (HttpContext ctx) =>
|
app.MapGet("/robots.txt", (HttpContext ctx) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user