caddyserver / website

The Caddy website
157 stars 153 forks source link

Add Cache-Control "public,max-age=0,must-revalidate" to index.html in SPA Example #410

Closed d3473r closed 1 month ago

d3473r commented 4 months ago

Edit the SPA example

Add the Cache-Control "public,max-age=0,must-revalidate" for index.html header to the SPA example.

In SPAs the index.html must be prevented from being cached, in the index.html the (fingerprinted) javascript and css file are referenced (these can be cached becaused they get a new random suffix everytime they are built)

mholt commented 4 months ago

Is this strictly true for all SPAs? Mine work without this. The example here should be as minimal as possible, but in the new docs we can expand the examples.

d3473r commented 4 months ago

Afaik as soon as you do try_files {path} /index.html you should explicitly set a cache-control index.html, see vercel https://github.com/vercel/serve/issues/258, aws (they recommend 60 sec for index.html) https://aws.amazon.com/blogs/networking-and-content-delivery/host-single-page-applications-spa-with-tiered-ttls-on-cloudfront-and-s3/ or codecentric https://www.codecentric.de/wissens-hub/blog/deployment-configurable-single-page-application

But you are right, maybe a second example which talks about this issue would be better than modifying the minimal example.

One then could also add a long cache time (public,max-age=31536000,immutable) for css and js files as they are fingerprinted and have a different name when the application.is rebuild

d3473r commented 4 months ago

Can you point me to the new docs, then i can add this example there

mholt commented 4 months ago

Oh I haven't got them ready yet. 😅 that's on me, I'm a bit behind lately.

francislavoie commented 1 month ago

I reworked this, I moved this below the other two examples and added an explanation. Thanks for the idea!

d3473r commented 1 month ago

Hi @francislavoie, thank you for merging the example!

But i don't understand the explanation you added to it. The reason for adding the header Cache-Control "public, max-age=0, must-revalidate" is not to instructs clients to cache the index.html, rather its to instruct clients to explicitly not to cache it.

To give you an example, if i do a angular build (or any other spa build that uses fingerprinting), you'll get this index.html:

<!DOCTYPE html>
<html lang="en" data-critters-container>
  <head>
    <meta charset="utf-8" />
    <title>CaddySpa</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link rel="stylesheet" href="styles-5INURTSO.css" />
  </head>
  <body>
    <app-root></app-root>
    <script src="polyfills-FFHMD2TL.js" type="module"></script>
    <script src="main-ITZNYXFD.js" type="module"></script>
  </body>
</html>

As you can see the css and js files are fingerprinted: styles-5INURTSO.css, polyfills-FFHMD2TL.js and main-ITZNYXFD.js

If i now change some javascript and build the spa again I'll get this index.html:

<!DOCTYPE html>
<html lang="en" data-critters-container>
  <head>
    <meta charset="utf-8" />
    <title>CaddySpa</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link rel="stylesheet" href="styles-5INURTSO.css" />
  </head>
  <body>
    <app-root></app-root>
    <script src="polyfills-FFHMD2TL.js" type="module"></script>
    <script src="main-7MRHVRTZ.js" type="module"></script>
  </body>
</html>

You can see now that the main.js got a new fingerprint and is now main-7MRHVRTZ.js. The browser will now load this new js file an the spa is updated.

Now comes the problem when the index.html is cached: The browser will download or use already cached outdated fingerprinted css and js files and serve a old spa version. That means for css and js files you can use a long cache time (even one year) as they have unique fingerprinted names, but the index.html you can never cache, as it will change for every build of the spa.

francislavoie commented 1 month ago

Ah okay, my mistake. If you want to do a follow-up PR to adjust the wording, that would be great 👍