Add cache-busting version query to static assets
Cloudflare was caching /static/style.css and /static/app.js at the edge for up to 4 hours (its default Browser Cache TTL, since the app sets no explicit Cache-Control), so deploys could look like they hadn't landed even though the origin was already up to date. A content hash of style.css/app.js/htmx.min.js, computed once at startup, is now appended as ?v=<hash> to their URLs in base.html, so every deploy that changes those files produces new, never-cached URLs and needs no manual cache purge. Also commits the live-sync-updates design spec, which was written but never staged earlier in the session. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import hashlib
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
|
||||
@@ -13,11 +14,27 @@ from app.security.credentials import CredentialCipher
|
||||
from app.web.forms import UserFormData
|
||||
|
||||
DASHBOARD_SUMMARY_WINDOW = timedelta(days=7)
|
||||
CACHE_BUSTED_STATIC_FILES = ("style.css", "app.js", "htmx.min.js")
|
||||
|
||||
router = APIRouter()
|
||||
templates = Jinja2Templates(directory=str(Path(__file__).resolve().parent / "templates"))
|
||||
|
||||
|
||||
def _compute_static_version(static_dir: Path) -> str:
|
||||
hasher = hashlib.sha256()
|
||||
for name in CACHE_BUSTED_STATIC_FILES:
|
||||
try:
|
||||
hasher.update((static_dir / name).read_bytes())
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
return hasher.hexdigest()[:10]
|
||||
|
||||
|
||||
templates.env.globals["static_version"] = _compute_static_version(
|
||||
Path(__file__).resolve().parent / "static"
|
||||
)
|
||||
|
||||
|
||||
def _next_sync_tick(request: Request):
|
||||
scheduler = getattr(request.app.state, "scheduler", None)
|
||||
return getattr(scheduler, "next_tick", None)
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16.png">
|
||||
<link rel="shortcut icon" href="/static/favicon.ico">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<script src="/static/htmx.min.js" defer></script>
|
||||
<script src="/static/app.js" defer></script>
|
||||
<link rel="stylesheet" href="/static/style.css?v={{ static_version }}">
|
||||
<script src="/static/htmx.min.js?v={{ static_version }}" defer></script>
|
||||
<script src="/static/app.js?v={{ static_version }}" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
|
||||
Reference in New Issue
Block a user