I have an SPA where all the files on my domain are static. I'm using CloudFlare to cache them to reduce load on my server.
My goal would be to have CloudFlare cache all my files until my deploy script tells it a file changed. And client browsers should see whatever cache-control header I set from my server, which would be something like cache-control: public,max-age=31536000
for files I'm generating with hashes in URLs (like JS/CSS/image files) and cache-control: no-cache
for my index.html file (which is served from many URLs due to this being a SPA, and cannot have a hash in it).
All of this works perfectly, except index.html. With index.html, it seems that Cloudflare sees the no-cache header and decides it cannot cache my index.html file, so I see "cf-cache-status: DYNAMIC" in my GET request header and it hits my server for every request.
The documentation says "Use Page Rules to implement custom caching options." Reading up on that, apparently I can use Page Rules to add the Cache Everything setting to all files. I did that, but now I see cf-cache-status: EXPIRED
in the headers for index.html, which means it's still hitting my server every request, I guess because it still sees my cache-control: no-cache
and decides it can't serve the cached page. So "Cache Everything" is not helping.
Reading further, I see the Cloudflare-CDN-Cache-Control header, which seems to be exactly what I want. I can set different cache-control values for CloudFlare and for browsers. So I set Cloudflare-CDN-Cache-Control: public,max-age=86400
in the hopes that CloudFlare will start caching my index.html file. But it seems to not matter - in my browser I still see cf-cache-status: DYNAMIC
. And I don't know how I can debug this further.
At this point, I feel like I'm probably just doing something fundamentally wrong. Feels like what I want is the same thing nearly any SPA would want, so there is probably an easy and reliable way to achieve it. But from Googling for answers, I don't find anything clear. What am I missing? I just want the cache-control values form my server to be sent to the browser, and for Cloudflare itself to cache all my files until my deploy script tells it to clear the cache.
Of course 5 minutes after posting, I figured it out! The key is to set "Cache Everything" and Cloudflare-CDN-Cache-Control together, and also make sure the "Browser Cache TTL" setting is set to "Respect Existing Headers".