Cache busting with CRA React
When I updated my site, run npm run build and upload the new files to the server I am still looking the old version of my site.
Without React, I can see the new version of my site with cache-busting. I do this:
Previous file
<link rel="stylesheet" href="/css/styles.css">
New file
<link rel="stylesheet" href="/css/styles.css?abcde">
How can I do something like this or to achieve cache busting with create react app?
There are many threads in the GitHub of create react app about this but no one has a proper/simple answer.
Solution 1:
EDIT: create-react-app v2 now have the service worker disabled by default
This answer only apply for CRA v1
This is probably because of your web worker.
If you look into your index.js file you can see
registerServiceWorker();
Never wondered what it did? If we take a look at the file it got imported from we can see
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read {URL}
// This link also includes instructions on opting out of this behavior.
If you want to delete the web worker, don't just delete the line. Import unregister and call it in your file instead of the register.
import { unregister } from './registerServiceWorker';
and then call
unregister()
P.S. When you unregister, it will take at least one refresh to make it work
Solution 2:
I had the same issue when I use create-react-app
( and deploy to heroku). It keeps showing the old version of my app 😡.
I found the problem seems to be on the browser side, it caches my old index.html
with its outdated js bundle
You may want to add the following to your server side response header
"Cache-Control": "no-store, no-cache"
or if you are also using heroku create-react-app-buildpack
, update the static.json
file
"headers": {
"/**": {
"Cache-Control": "no-store, no-cache"
}
}
I think in this way you can still keep that poor service worker 😂, and the latest content will be shown on the N+1 load (second refresh)
Hope this helps...
Solution 3:
As mentioned by some of the previous answers here, both the service worker and the (lack of) cache headers can conspire against you when it comes to seeing old versions of your React app.
The React docs state the following when it comes to caching:
Using
Cache-Control: max-age=31536000
for yourbuild/static
assets, andCache-Control: no-cache
for everything else is a safe and effective starting point that ensures your user's browser will always check for an updatedindex.html
file, and will cache all of thebuild/static
files for one year. Note that you can use the one year expiration onbuild/static
safely because the file contents hash is embedded into the filename.
As mentioned by @squarism, older versions of create-react-app defaulted to opt-out of service worker registration, while newer versions are opt-in. You can read more about that in the official docs. It's quite a straightforward process to match you configuration to the latest template if you started with an older version of create-react-app and you want to switch to the new behaviour.
Related questions:
- How to avoid caching for create-react-app
- ReactJS: How to prevent browser from caching static files?
- how to clear browser cache in reactjs
Solution 4:
It appears that they changed from opt-out to opt-in with regards to the service worker. Here's the commit that changed the README and it has examples similar to Kerry G's answer:
https://github.com/facebook/create-react-app/commit/1b2813144b3b0e731d8f404a8169e6fa5916dde4#diff-4e6ec56f74ee42069aac401a4fe448ad
Solution 5:
If your problem is with resources statically referenced in index.html, such as .css files or additional .js files (e.g. configuration files), you can declare a React environment variable, assign a unique value to it and reference it in your index.html file.
In your build script (bash):
REACT_APP_CACHE_BUST={e.g. build number from a CI tool} npm run build
In your index.html:
<link rel="stylesheet" href="%PUBLIC_URL%/index.css?cachebust=%REACT_APP_CACHE_BUST%" />
The variable name has to start with REACT_APP_. More about environment variables in React: https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables.