fix(nginx): add no-cache header for index.html to prevent stale SPA s…#9440
fix(nginx): add no-cache header for index.html to prevent stale SPA s…#9440vansh17June wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughNginx configurations for the admin and web applications now provide exact-match shell routes with security headers and disabled caching. The admin route returns 404 when missing and serves as the fallback for unresolved requests; the web route remains the SPA fallback target. ChangesNginx shell routing
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/admin/nginx/nginx.conf (1)
29-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAlign formatting and documentation with the web configuration.
Consider adding the explanatory comment from the web configuration here for consistency, and fixing the minor 1-space indentation offset on the
locationdirective to match the rest of the file.♻️ Proposed refactor
- location = /god-mode/index.html { - root /usr/share/nginx/html; - add_header X-Frame-Options "DENY" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header Cache-Control "no-cache, must-revalidate" always; - try_files $uri =404; - } + # index.html is not content-hashed like /assets/*, so it must never be + # cached long-term. Safari/iOS's aggressive heuristic caching can otherwise + # keep serving a stale shell indefinitely, even after a fix is deployed. + location = /god-mode/index.html { + root /usr/share/nginx/html; + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Cache-Control "no-cache, must-revalidate" always; + try_files $uri =404; + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/admin/nginx/nginx.conf` around lines 29 - 37, Align the /god-mode/index.html location block with the surrounding nginx configuration by correcting the location directive’s indentation and adding the corresponding explanatory comment used in the web configuration. Keep the existing headers and try_files behavior unchanged.apps/web/nginx/nginx.conf (1)
42-48: 📐 Maintainability & Code Quality | 🔵 TrivialConsider updating the AIO proxy configuration.
The changes here correctly prevent heuristic caching for the Nginx deployments. However, based on the context snippets, the All-In-One (AIO) deployment (
apps/proxy/Caddyfile.aio.ce) serves the web and admin applications directly via Caddy'sfile_serverrather than proxying to these Nginx containers.Because Caddy does not append
Cache-Controlheaders by default, Safari's heuristic caching might still cause stale application shells in the AIO setup. Consider applying a similar caching policy via theheaderdirective in the Caddyfile in a future PR to cover AIO users.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/nginx/nginx.conf` around lines 42 - 48, Update the AIO Caddy configuration in Caddyfile.aio.ce to add an explicit no-cache policy for the web and admin applications served by file_server. Use Caddy’s header directive to set the equivalent Cache-Control response headers, preserving the existing file-serving behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@apps/admin/nginx/nginx.conf`:
- Around line 29-37: Align the /god-mode/index.html location block with the
surrounding nginx configuration by correcting the location directive’s
indentation and adding the corresponding explanatory comment used in the web
configuration. Keep the existing headers and try_files behavior unchanged.
In `@apps/web/nginx/nginx.conf`:
- Around line 42-48: Update the AIO Caddy configuration in Caddyfile.aio.ce to
add an explicit no-cache policy for the web and admin applications served by
file_server. Use Caddy’s header directive to set the equivalent Cache-Control
response headers, preserving the existing file-serving behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3b1a5c48-1a1b-4f8e-aa07-06fa44bd367e
📒 Files selected for processing (2)
apps/admin/nginx/nginx.confapps/web/nginx/nginx.conf
Description
Adds explicit
Cache-Control: no-cache, must-revalidateheaders forindex.htmlin the web (
apps/web/nginx/nginx.conf) and admin (apps/admin/nginx/nginx.conf)nginx configs.
index.htmlis not content-hashed like the files under/assets/*, so without anexplicit cache header, browsers rely on nginx's default heuristic caching. Safari
in particular applies aggressive heuristic caching to responses without an explicit
Cache-Controlheader, which can cause it to keep serving a staleindex.htmlindefinitely — even after a bug fix is deployed to production — until the user
manually clears site data.
This was flagged as a secondary finding in #9439 (the Safari/iOS
requestIdleCallbackcrash issue): even once that crash fix ships in a release,Safari/iOS users could keep hitting the old broken build because of this caching
gap.
Type of Change
Screenshots and Media (if applicable)
N/A — this is a header-only nginx config change, not a UI change.
Test Scenarios
curl -I http://localhost:3000/index.htmlreturns
Cache-Control: no-cache, must-revalidate/assets/*static chunks are unaffected and still use their existingcaching behavior
X-Frame-Options,X-Content-Type-Options,Strict-Transport-Security,X-XSS-Protection) are still present onindex.htmlresponses
try_filesfallback for bothapps/webandapps/admin(/god-mode/index.html)References
Related to #9439
Summary by CodeRabbit