🐛(frontend) cache hashed next static assets and revalidate html

Files under /_next/static/ carry a content hash in their name but were
served without Cache-Control, so browsers fell back to heuristic freshness
and revalidated each of the ~45 files of a page with a conditional request.
Serve them with a one-year immutable lifetime.

HTML pages, service-worker.js and public files keep a stable name: send
Cache-Control: no-cache so the browser revalidates them and always gets
the chunk list and service worker of the current release. The headers are
repeated in every location, as nginx drops the inherited add_header
directives as soon as a location defines its own.

Closes #2770

Signed-off-by: Anthony LC <anthony.le-courric@mail.numerique.gouv.fr>
This commit is contained in:
Anthony LC
2026-10-05 16:34:08 +02:00
parent 2bd30312cd
commit 6e5dee38e9
2 changed files with 17 additions and 0 deletions
+1
View File
@@ -90,6 +90,7 @@ and this project adheres to
- 🐛(documentation) fix minio port and keycloak realm in the k8s guide #2751
- 🐛(collaboration) bound the calls yhub makes to the backend with a timeout,
`YHUB_BACKEND_REQUEST_TIMEOUT_MS`, 5s by default #2753
- 🐛(frontend) cache hashed `/_next/static/` assets and revalidate HTML #2770
- 🐛(backend) compensate document duplication failures #2755
- 🐛(frontend) open search results in a new tab with ctrl/cmd+click #2719
- 🐛(docker) pull minio images from pgsty
@@ -5,21 +5,37 @@ server {
root /app;
# Files under /_next/static/ have a content hash in their name: they never
# change, so browsers can keep them for good.
# `add_header` is not inherited when a location defines its own.
location /_next/static/ {
try_files $uri =404;
add_header Cache-Control "public, max-age=31536000, immutable";
add_header X-Frame-Options DENY always;
}
# Everything else (HTML pages, service-worker.js, public files) has a stable
# name: the browser must revalidate it, so that it always gets the chunk list
# of the current release and the latest service worker.
location / {
try_files $uri index.html $uri/index.html =404;
add_header Cache-Control "no-cache";
add_header X-Frame-Options DENY always;
}
location ~ "^/docs/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/?$" {
try_files $uri /docs/[id]/index.html;
add_header Cache-Control "no-cache";
add_header X-Frame-Options DENY always;
}
location ~ "^/user-reconciliations/(active|inactive)/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/?$" {
try_files $uri /user-reconciliations/$1/[id]/index.html;
add_header Cache-Control "no-cache";
add_header X-Frame-Options DENY always;
}