From 33bc06440ec67f807a29238c75c2aa5bf1e513cc Mon Sep 17 00:00:00 2001 From: Padreug Date: Thu, 4 Jun 2026 11:17:15 +0200 Subject: [PATCH] feat: serve hub SPA shell with Cache-Control: no-cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hashed assets stay immutable via the existing regex location; the SPA shell (index.html, served via tryFiles fallback for /, deep links, and literal /index.html) now revalidates on every load so new deploys are picked up without browsers holding a stale shell that references deleted hashed assets. no-cache = cache + revalidate (304), not "don't store" — bandwidth cost is a single conditional request per page load. Co-Authored-By: Claude Opus 4.7 (1M context) --- webapp.nix | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/webapp.nix b/webapp.nix index 20495fd..5c8d820 100644 --- a/webapp.nix +++ b/webapp.nix @@ -319,11 +319,20 @@ in { locations = { "/" = { - # Try files, fallback to index.html for SPA routing + # Try files, fallback to index.html for SPA routing. + # Everything matching this prefix ultimately serves the SPA + # shell (index.html), which must revalidate on every load so + # new deploys are picked up without the browser holding a + # stale shell pointing at deleted hashed assets. The more- + # specific regex location below overrides this for hashed + # static assets, which stay immutable. tryFiles = "$uri $uri/ /index.html"; + extraConfig = '' + add_header Cache-Control "no-cache"; + ''; }; - # Cache static assets aggressively + # Cache static assets aggressively (Vite emits content-hashed filenames) "~* \\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$" = { extraConfig = '' expires 1y;