Reputation: 2852
I've created a React application with create-react-app
, as you may know there's a npm run build
command which exports everything you need for deployment inside of the build
folder.
It basically contains an index.html
file with all the required assets (images, compressed JavaScript and css files plus some others)
When deploying, I've setup a DigitalOcean droplet with Ubuntu 16 where I installed Express.js in order to setup a server to handle requests, it looks like this:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(process.env.PORT || 8080);
I keep that server running using pm2 with this command: pm2 start server.js
I've installed Nginx to be a proxy with this config (please note Cache-Control, Pragma and Expires headers I'm sending in every response):
upstream react_dev {
server 127.0.0.1:8080;
keepalive 64;
}
server {
server_name dev.24mm.co;
charset utf-8;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 40m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
location / {
proxy_set_header X-Prerender-Token [my-prerender.io-token];
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 240s;
set $prerender 0;
if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
set $prerender 0;
}
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8;
if ($prerender = 1) {
#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
set $prerender "service.prerender.io";
rewrite .* /$scheme://$host$request_uri? break;
proxy_pass http://$prerender;
}
#if (!-f $request_filename) {
if ($prerender = 0) {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;
proxy_pass http://react_dev;
break;
}
}
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/dev.24mm.co/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/dev.24mm.co/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = dev.24mm.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
server_name dev.24mm.co;
return 404; # managed by Certbot
}
No matter what I do, every time I deploy my project (i.e. I run npm run build
) the browser is looking for the old JavaScript and CSS files, because it has a cached version of the main index.html
document. That's of course causing a very bad user experience because all users are seeing a blank page after each deploy.
I'm wondering how to tell the browser never to cache the index.html
file.
Upvotes: 1
Views: 822
Reputation: 112787
If the browser is not honoring the cache headers, it's usually a registered service worker that gets old assets.
If you have used the service worker in an older version of your app and you don't want to use it anymore, you must explicitly unregister it.
import { unregister } from './registerServiceWorker';
unregister();
Upvotes: 2