Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React app has to clear browser cache after new deployment

We are deploying our React application on the apache server using the Jenkins pipeline. When we deploy new codes, most of the new features work fine but not for all changes reflect the latest in the browser. Users have to open an incognito window or clear cache to see the new feature.

I have seen a few solutions related to angular applications But anything specific to React application, I do not see anywhere. During the build time, Can we add something that will automatically serve the latest changes for end-user? I guess, Cache busting is required But how can we do without a lot of modification in the code, as the above solution did for Angular app.

like image 908
Nimish goel Avatar asked May 15 '20 07:05

Nimish goel


3 Answers

The usual approach is to add a hash to the script and other assets filenames depending on the time or content. So when before you had script.js now it will be script.[contenthash].js. The content hash will be different every time you change the content of the script.

Now when a user requests the index.html of your app it will reference the script including the individual content hash. If users previously loaded the script.abc123.js and now the index.html references a script.cba321.js the browser will know that it has not previously seen this file and load it. This way users have the current version of your scripts and other assets (js, css, images, ...). For this to work however it is important that users always load the recent version of the index.html.

This approach is not react specific but an universal approach and best practice. It is however used and suggested by create-react-app (see: https://github.com/facebook/create-react-app).

Since it would be quite tedious to do this manually all the time there are a lot of scripts and strategies available to use module bundlers to achieve this goal. E.g. by using WebPack: https://webpack.js.org/guides/caching/

There are other approaches like setting caching response headers for script files, which however I can not recommend in this case.

like image 112
realAlexBarge Avatar answered Sep 20 '22 19:09

realAlexBarge


I personally use below in my development environment for testing

# Never cache these...
# HTTP 1.1=>Cache-Control, HTTP 1.0=>pragma and Expires=>proxy

# for html,htm,json,js,css as follows
<filesMatch "\.(html|htm|json|js|css)$">
  FileETag None
  <ifModule mod_headers.c>
     Header unset ETag
     Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
     Header set Pragma "no-cache"
     Header set Expires "0"
  </ifModule>
</filesMatch>

The server adds ETag header to a response containing a resource being served, and the client caches the resource and remembers its entity tag (the value of ETag).

Other easy way would be using query string, incrementing the querystring each time you make a changes or use some unique string whenever you make changes, example as follows. You don't have to change apache config browser will load respective script.

# first version
<script src="path/to/your/app-loader.js?version=1"></script>
like image 28
Akshay Hegde Avatar answered Sep 16 '22 19:09

Akshay Hegde


You have to configure caching policy of your server.

Example for nginx:

location /{
     alias /www/your/app/;
     try_files $uri $uri/ /index.html;
     add_header Cache-Control "no-store, no-cache, must-revalidate";
}

You can learn more here https://medium.com/@pratheekhegde/setting-caching-headers-for-a-spa-in-nginx-eb2f75f52441

like image 28
vicacid Avatar answered Sep 16 '22 19:09

vicacid