45

I have a site built with create-react-app and hosted on Firebase Hosting. What can I do to specify the browser cache needs to be updated after new deploys, and ideally only for pages, assets, and stylesheets that have been changed since the last deploy?

Is there a way to access the deploy id and include that (or any other unique identifier) in the headers so the browser can compare to what it has in local storage or cache and determine whether a hard refresh is necessary? I looked over the Firebase Deploying as well as Full config docs but there's no mention on how to access hosting metadata like the last deploy time.

Setting a Cache-Control value to max-age=[any number] doesn't seem ideal because it disregards when the next deployment will occur (which might be unknown to begin with unless there are regular schedules).

Pat Needham
  • 5,698
  • 7
  • 43
  • 63

2 Answers2

79

I figured it out. Had to update the firebase.json file according to this Github comment:

{
  "hosting": {
    "headers": [
      { "source":"/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}] }
    ]
  }
}
Pat Needham
  • 5,698
  • 7
  • 43
  • 63
  • 3
    Firebase docs on this here: https://firebase.google.com/docs/hosting/full-config#headers – btd Aug 18 '18 at 16:11
  • 2
    Cache-Control docs here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control – btd Aug 18 '18 at 16:23
  • 2
    Does this clear the cache only when you deploy a new build or it clears every time user visits the site? – Ishwar Rimal Oct 14 '21 at 07:18
  • I believe it only clears the cache on new deploys, but it's been a while so I could easily be wrong. Probably best to check the Firebase docs link @btd posted as they would be more up to date – Pat Needham Oct 14 '21 at 20:36
  • 1
    Separate question but same topic, what if you redeploy but then a certain % of users never refresh the page and so still have stale .js files loaded? I'm particularly worried about this when making deployments that affect data that goes into firestore (e.g. previous .js files update firestore doc with 4 fields, then the new content updates with 5 fields populated...) – Ryan Jan 19 '22 at 16:09
  • @Ryan I had that same concern before, since I'll go days without refreshing some websites that just work. My best guess for how to handle that in the most effective way is to treat the new deploys as events that get added to a Firestore collection, and have a client-side listener for when new deploy events occur, so that when they do, you can display a popup saying something like a "New site update, please refresh" link that when clicked will refresh the page – Pat Needham Jan 19 '22 at 16:20
  • Thanks @PatNeedham glad I'm not the only one! Your idea is a good one, either that or if the issue is firestore specific maybe set a firestore rule to match the new deployment logic and handle gracefully if the request is outdated, along the lines of what you mentioned as a pop-up – Ryan Jan 20 '22 at 05:36
4

Please set "max-age=0" in your firebase.json.

    "headers": [
        {
            "source": "/service-worker.js",
            "headers": [
                {
                    "key": "Cache-Control",
                    "value": "no-cache, no-store, must-revalidate"
                }
            ]
        },
        {
            "source": "**/*.@(jpg|jpeg|gif|png|svg|webp|js|css|eot|otf|ttf|ttc|woff|woff2|font.css)",
            "headers": [
                {
                    "key": "Cache-Control",
                     "value": "max-age=0"
                }
            ]
        }
    ]
Kei
  • 134
  • 5