Override Cache-Control index.html

Hi there,

I am trying to override the default Cache-Control policy that netlify has. I have read about how to do so in the documentation and i created a netlify.toml file with a number of rules that specify Cache-Control = “public, max-age=3600”. This is working great for all my assets like css, js, images, etc. But when i set Cache-Control for index.html (or any other html page for that matter), it is always overridden with the netlify default – which forces must-revalidate. I understand the risks of setting my own cache-control headers. What i need to know is, what does it take to force netlify to use the one I specify for html pages?

None of these work:

for = “/*”
[headers.values]
Cache-Control = “public, max-age=3600”

for = “/index.html”
[headers.values]
Cache-Control = “public, max-age=3600”

for = “index.html”
[headers.values]
Cache-Control = “public, max-age=3600”

for = “/*.html”
[headers.values]
Cache-Control = “public, max-age=3600”

for = “*.html”
[headers.values]
Cache-Control = “public, max-age=3600”

Hey @jasonwaters and welcome to the forum :wave:

I’m surprised the first rule doesn’t work!

for = “/*”
[headers.values]
Cache-Control = “public, max-age=3600”

But beyond that, the reason sounds like what’s described in this thread:

Could you take a look and confirm that that’s what you’re running into? If so, I can add you to our open feature request. If not, please send a Netlify URL and some more details so we can dig in further.

Hi Jen,

In general, I am observing very unpredictable behavior from netlify with respect to Cache-Control headers. It seems to override my netlify.toml settings most of the time. Take a look at the live site here: https://target-perf-site.netlify.app/ and the netlify.toml file here: netlify.toml · GitHub

Is it a bug?

Hey @jasonwaters,
We spent quite a while digging into this. The easiest thing to address is that we noticed that your header for value is * but it needs to be /* as you mentioned at the top of the thread.

We also did find that we have an issue open internally about how we handle 304s. But! The initial requests that return 200s should be doing the right thing. Please let us know if you’re seeing something different. And we can keep you posted if/when there’s movement on the 304 bug.

Hi jen,

I have both for “" and "/” in my netlify.toml file.

This is a major issue for us, I am surprised that this issue is not a more urgent priority for netlify.

You have only one custom header value, Jason. It is applied only to /*. If you have specified two, we did not get your netlify.toml file or it did not parse correctly.

As Jen said, we’ve gotten a bug filed on 304’s. Your use pattern is pretty atypical for Netlify - most people use our default caching settings with great success:

…so we haven’t put as much effort into your use case as the path that more than 99.9% of our customers use.

We’ll follow up here if the bug gets fixed; in the meantime, we recommend you not override our cache controls.

@fool I’m not sure what you mean that i have only one custom header value. You can see the netlify.toml file I use here: https://github.com/jasonwaters/atjs-performance/blob/master/event-landing-page/netlify.toml

Hi, @jasonwaters. If you look at the deploy details for the current published deploy, it also confirms only a single header rule is being processed:

  • 1 new file uploaded
    1 asset changed.

  • No redirect rules processed
    This deploy did not include any redirect rules. Learn more about redirects.

  • 1 header rule processed
    All header rules deployed without errors.

  • All linked resources are secure
    Congratulations! No insecure mixed content found in your files.

  • Build time: 4s. Total deploy time: 4s

I’m seeing two issues in netlify.toml. I’ve included an example below. I see rules defined like this:

[[headers]]
  for = "/*"
  [headers.values]
    Some-Header = "some value"

  for = "/foo/*"
  [headers.values]
    Some-Header = "some value"
    
  for = "/bar/*"
  [headers.values]
    Some-Header = "some value"

However, a new [[headers]] line is needed before each rule like so instead:

[[headers]]
  for = "/*"
  [headers.values]
    Some-Header = "some value"

[[headers]]
  for = "/foo/*"
  [headers.values]
    Some-Header = "some value"
    
[[headers]]
  for = "/bar/*"
  [headers.values]
    Some-Header = "some value"

Also, rules are checked in order. We recommend putting the most specific rules first. The * in a header (or redirect) rule will match forward slashes.

This means that the first rule will match any request. It will always been the only rule used even if other, more specific, rules exist and apply. This is only because it is the first rule. If it were the last rule, it would not override the others.

To change that behavior, put rules in order of mosts specific first to least specific last. For example, rules like this:

[[headers]]
  for = "/rule/most/specific/of/all"
  [headers.values]
    Some-Header = "value for that exact path"

[[headers]]
  for = "/rule/most/specific/*"
  [headers.values]
    Some-Header = "value for any path begining /rule/most/specific/" # (except "/rule/most/specific/of/all") 

[[headers]]
  for = "/rule/*"
  [headers.values]
    Some-Header = "value for any path begining /rule/" # (except the ones above)

[[headers]]
  for = "/foo/*"
  [headers.values]
    Some-Header = "value for /foo/"
    
[[headers]]
  for = "/bar/*"
  [headers.values]
    Some-Header = "value for /bar/"

[[headers]]
  for = "/*"
  [headers.values]
    Some-Header = "value for all the rest"

If that doesn’t work or if there are other questions, please let us know.

@luke Thank you very much for taking the time to inspect my netlify.toml file, the feedback really helps. I didn’t realize i needed a [[headers]] line for each rule. After changing it i can see it is recognizing the rules now.

Cheers

2 Likes