Get Fresh Pages with Messed Up Caches

While fixing Content-Security-Policy header, I have messed up the caches. I have accidentally pushed a change to keep all pages in the cache indefinitely. Situation: browsers are now serving stale pages.

Netlify custom headers documentation does not mention that wildcards may swallow everything, and does not give any examples of pattern use, in practice /*.* pattern matches same paths with /*. But, while digging forum posts this post come up, though a support engineer mentions it is an unsupported feature.

/*
  Cache-Control: public, max-age=360
/*.(jpg|jpeg|gif|png|webp|svg)
  Cache-Control: public, max-age=31536000, immutable

One can specify it in this manner, take caution, order matters. First pattern matches everything, second one overwrites settings.

Cache-Control #

The header controls how long a resource will be kept in browser caches, and when should it be refreshed. A balance is important, to not request same data repeatedly for less bandwidth and better performance, while not serving stale data.

DirectiveEffect
publicmay be stored by any cache
privatemay be stored only by browser’s cache
no-cachemay be stored, must revalidate
no-storemay not be stored, with max-age=0 force re-validate
max-age=<seconds>max time resource is fresh
must-revalidatemust not use stale copy without successful validation on the server
immutablewill not change over time, do not revalidate

For more directives and detailed info check out MDN docs.

We can store static resources like images, JS and CSS files forever1. When we must change these resources, we should employ Cache Busting2 strategies.

Cache-Control: public, max-age=31536000, immutable
Warning: Double check resources, they will be kept indefinitely.

For a static site, HTML endpoints (URLs) will remain same, though content will change. We can use several strategies.

  • Do not cache at all:
    Cache-Control: no-store, max-age=0
    
  • Cache only a short time (5 mins):
    Cache-Control: public, max-age=300 xx
    

Clear-Site-Data #

The header is still a working draft. Even though it seems to be supported, it is not working as advertised in Firefox. Setting it on Chrome removes offline data correctly.

Clear-Site-Data: "cache"
Attention to the double quotes. Other directives are "cookies", "cookies", "storage", "executionContexts", "*".

What now? #

Andrews Betts has several solutions. Iframe + POST method from the article should work cross-browser for same-origin resources, to transparently refresh a specific resource stuck in cache.

For now, all the visitors I get are friends, so a self refresh is a possibility. I am going to skip it, but it may come in handy in the future.


  1. RFC 2616 HTTP/1.1 servers SHOULD NOT send Expires dates more than one year in the future. ↩︎

  2. Modifying URL to replace an existing file that is already cached.

    • File name versioning (e.g. style.v2.css)
    • File path versioning (e.g. v2/style.css)
    • Query strings (e.g. style.css?ver=2)
     ↩︎