From a3ecac3507271a543d8330b810d9b987ce29fc3c Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 11 Oct 2026 09:50:42 -0400 Subject: [PATCH] =?UTF-8?q?fix(server):=20Cache-Control=20no-cache=20on=20?= =?UTF-8?q?/static=20=E2=80=94=20heuristic=20caching=20served=20stale=20bu?= =?UTF-8?q?ndles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The static handler sent no Cache-Control, so browsers fell back to heuristic caching (10% of age since Last-Modified) and kept serving a stale reader.js for hours after a deploy — fixed web bugs reported as "not fixed". no-cache forces revalidation every load; the filesystem Last-Modified/If-Modified-Since pair keeps unchanged loads cheap. Found while closing out the PDF adjust v2 session: the user's Chrome was running a pre-endpoint bundle, which read as "the web has not been fixed". --- internal/router/router.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/router/router.go b/internal/router/router.go index e4eb7093..fca5c84b 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -250,6 +250,21 @@ func RegisterRoutes(cfg *Config) *handlers.Handler { registerWebSocketRoutes(cfg) registerFrontendRoutes(cfg) registerDocumentationRoutes(cfg) + + // Static bundles are served unhashed (reader.js, index.js), so the + // browser must revalidate on every load — with no Cache-Control it + // fell back to heuristic caching and served stale bundles for hours + // after a deploy (user-visible: fixed web bugs "not fixed"). no-cache + // still allows cheap If-Modified-Since 304 revalidation. + e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c *echo.Context) error { + if strings.HasPrefix(c.Request().URL.Path, "/static/") { + c.Response().Header().Set(echo.HeaderCacheControl, "no-cache") + } + return next(c) + } + }) + e.Static("/static", "web/static") // Catch-all 404 handler - must be last