Caching headers for prefetched assets

Hello friends,

FIrst of all, love Netlify! So simple and powerful.

You can find a live deploy of my app here for reproducing the problem described below:

Now, my problem: I am using Webpack to bundle all my JS. On bundling, Webpack adds a content hash to the filename (‘cache busting through fingerprinting’) and adds the content hash to the JS script src in the HTML. Thus, I never have to worry about clients using outdated JS from their cache if my JS changed.

Because of this, I would like to change the caching headers of my JS files to a high max-age. Clients should cache the JS files for a very long time because my content hash fingerprinting will ensure that they get any updated JS anyways.

I was able to get that to work with Netlify in one of two ways:

  1. Use the netlify.toml file to specify the custom headers
  2. Enable the “Bundle JS” option in the post-processing. Your docs are not explicit that this option actually affects the caching policy but I inferred it from a blog post - might make sense to slightly tweak your docs there.

I prefer option 1 because it leaves the bundling within my control.

So what is the problem?

I also prefetch two key JS files (therapist.js and session.js). These prefetched JS files then get prefetched with the following cache-control header:

public, max-age=0, must-revalidate

This is not what I want. What I want is for these prefetched files is more something like this:

public, max-age=31556926

This second cache-control header is what I automatically get when I choose option 2 above (enable the “Bundle JS” postprocessing option). However, it only works for regular requests for this JS from the HTML script tag. It doesn’t work when I request the same JS files via prefetching.

Any ideas? What am I doing wrong? :slight_smile:

Thanks,
Yanick

You can modify headers for any file that isn’t asset-optimized (since those have the special handling, but also potentially create CORS problems since they are served from a different domain). You do this using our custom headers functionality:

For those two, you might use this in your separate headers file, or your toml file though that configuration being more verbose I don’t include it here:

/path/to/therapist.js:
   cache-control: public, max-age=31556926
/path/to/session.js
   cache-control: public, max-age=31556926

If the files have a hash in their names, you might be able to do something like put them all in a single directory, and use this syntax instead to cover all names past and present:

/path/to/*.js:
     cache-control: public, max-age=31556926

Note that both messing with these headers and cachebusting are generally regarded as antipatterns on Netlify - you should let our default caching do the work and NOT cachebust anything, since it slows your site down in many situations. This article has more details if you are curious:

We won’t stop you from doing it your way, so you’re welcome to keep using it, but it creates other problems like this one: