Cache-Control Is Why Your Deploy Looks Broken
The deploy succeeded, the CDN has new files, and visitors still see the previous version for an hour. This is not a bug.
Two files, two lifetimes
Hashed assets — main.a1b2c3.js — are immutable. The name changes when the content does, so they can cache forever:
Cache-Control: public, max-age=31536000, immutable
HTML is the opposite. It is the file that points at the new hashes. Cache it and readers keep loading the old bundle:
Cache-Control: public, max-age=0, must-revalidate
The trap in the matcher
A rule like **/*.@(html) looks complete. It is not, if clean URLs are on. A request for / never ends in .html — the rewrite to index.html happens after header matching. Your homepage, the one page everyone hits, silently keeps the default one-hour cache.
Match the routes, not the filenames.
Diagnosing it
curl -sI https://your-site/ | grep -i 'cache-control\|last-modified'
Last-Modified pointing at your previous deploy is the whole answer. Compare a hashed asset name in the live HTML against your local build output — if they differ, you are looking at old bytes, not a broken build.