server { listen 80; listen [::]:80; server_name _; root /usr/share/nginx/html; index index.html; # The webapp uses real (History API) client-side routing, so any unknown path can safely fall # back to index.html -- the app resolves the actual view/topic client-side from the path itself # once index.html loads. index.html itself is never content-hashed, so it must always be # revalidated -- otherwise a browser holding a cached copy would keep requesting the *previous* # deploy's now-deleted /assets/*.js filenames after a new deploy replaces them. location / { add_header Cache-Control "no-cache"; try_files $uri $uri/ /index.html; } # Vite content-hashes every filename under assets/ (e.g. index-DYjopaLI.js) -- a new build never # reuses an old asset's URL, so these can be cached aggressively and indefinitely; a stale cached # copy simply never gets requested again once index.html points at the new hashed filenames. location /assets/ { add_header Cache-Control "public, max-age=31536000, immutable"; } }