I'm deploying a Single Page Application (SPA) on AWS S3 and CloudFront, and I'm facing an issue with caching that leads to outdated versions of the application being loaded.
Browsers like Chrome and Edge:
index.html directly from the disk cache without making a HEAD or GET request to check for updates.index.html file doesn't have the correct Cache-Control headers.index.html) are loaded, causing the application to run an older version.Redirect Configuration:
index.html is served.index.html.Requirements:
index.html: Should always check for updates. Headers like Cache-Control: no-cache or max-age=0, must-revalidate should force the browser to revalidate it..js, .css, etc.): These are hashed (e.g., main.abc123.js), so they can be cached long-term (Cache-Control: public, max-age=31536000, immutable).index.html and versioned assets (js/css files with hashes)./*). No cache-control header modification.index.html (lambda does not trigger here i think).Viewer response lambda@edge to add Cache-Control: no-cache for text/html files. Added Viewer request lambda@edge, to redirect anything without extension (not asset) to index.html. Works but i think there should be a better solution.index.html but keeps static assets cached long-term?Thx for help!
I'm deploying a Single Page Application (SPA) on AWS S3 and CloudFront, and I'm facing an issue with caching that leads to outdated versions of the application being loaded.
Browsers like Chrome and Edge:
index.html directly from the disk cache without making a HEAD or GET request to check for updates.index.html file doesn't have the correct Cache-Control headers.index.html) are loaded, causing the application to run an older version.Redirect Configuration:
index.html is served.index.html.Requirements:
index.html: Should always check for updates. Headers like Cache-Control: no-cache or max-age=0, must-revalidate should force the browser to revalidate it..js, .css, etc.): These are hashed (e.g., main.abc123.js), so they can be cached long-term (Cache-Control: public, max-age=31536000, immutable).index.html and versioned assets (js/css files with hashes)./*). No cache-control header modification.index.html (lambda does not trigger here i think).Viewer response lambda@edge to add Cache-Control: no-cache for text/html files. Added Viewer request lambda@edge, to redirect anything without extension (not asset) to index.html. Works but i think there should be a better solution.index.html but keeps static assets cached long-term?Thx for help!
Is it true that Chrome/Edge bookmarks skip checking for updates (e.g., ETag) if no Cache-Control header is set and load files directly from disk cache?
As far as I know, Cache-Control supersedes ETag. Cache-Control max-age tells the browser not even to attempt checking for ETag. However once the content is stale (as determined by the max-age), browsers can request the servers by providing its cached ETag value. This helps the server because if the ETag has not changed, the server may choose not to return the full-sized content and instead just say "304 Not Modified".
Does the 403 → 200 error response affect caching behavior, and if so, how can I improve it?
It does affect caching behavior, but isn't it a single page application? In other words, index.html is always involved anyway. And the caching is still subject to Cache Control headers. So you can still use max-age. I don't think this is an issue.
What’s the best caching configuration to ensure the app always checks for updates (e.g., ETag/header) for index.html but keeps static assets cached long-term?
It seems like you already know this, use Cache Control headers to control browser behavior. You can configure different max-age for different assets. And on the CloudFront side, just run invalidate cache whenever you have an updated version of index.html.
