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). *@
|
||||
<script>
|
||||
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>
|
||||
|
||||
|
||||
@@ -335,7 +335,12 @@ app.MapPost("/like", async (HttpContext ctx, AppDbContext db, [FromForm] string
|
||||
return Results.Json(new { liked, count });
|
||||
}).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 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('/'))); });
|
||||
@@ -368,7 +373,8 @@ self.addEventListener('notificationclick', e => {
|
||||
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); }));
|
||||
});
|
||||
""", "text/javascript"));
|
||||
""", "text/javascript");
|
||||
});
|
||||
|
||||
// ---- SEO: robots.txt + dynamic sitemap.xml (so Google indexes every live shift/job page) ----
|
||||
app.MapGet("/robots.txt", (HttpContext ctx) =>
|
||||
|
||||
Reference in New Issue
Block a user