Search code examples
htmlvue.jsbrowser-cache

VueJS/browser caching production builds


I have a VueJS app. Whenever I run npm run build it creates a new set of dist/* files, however, when I load them on the server (after deleting the old build), and open the page in browser, it loads the old build (from cache i assume). When I refresh the page, it loads the new code no problem.

This is my index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
        <meta http-equiv="cache-control" content="max-age=0" />
        <meta http-equiv="cache-control" content="no-cache" />
        <meta http-equiv="expires" content="-1" />
        <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
        <meta http-equiv="pragma" content="no-cache" />
        <link rel="stylesheet" href="/static/css/bootstrap.min.css"/>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

Is there a way to force it to load new code every time or (ideally) to check if the old files are gone from the server, then refresh the browser?


Solution

  • This problem is annoying, no doubt. Had to solve it using a custom Front end version endpoint sent in the header. I am using a rails backend and Vue + Axios as front-end. Note I don't need a service worker and hence not using one.

    Essentially I am just reloading whenever there is a get request and that the version of the application has changed (the server can inform the same)

    axiosConfig.js

    axios.interceptors.response.use(
      (resp) => {
        const fe_version = resp.headers['fe-version'] || 'default'
        if(fe_version !== localStorage.getItem('fe-version') && resp.config.method == 'get'){
          localStorage.setItem('fe-version', fe_version)
          window.location.reload() // For new version, simply reload on any get
        }
        return Promise.resolve(resp)
      },
    )
    

    Rails Backend

    application_controller.rb

    after_action :set_version_header
    
    def set_version_header
      response.set_header('fe-version', Setting.key_values['fe-version'] || 'default')
    end
    

    application.rb (CORS config assuming Vue running on port 8080)

    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins ['localhost:8080', '127.0.0.1:8080']
        resource '*', expose: ['fe-version'], headers: :any, methods: [:get, :post, :delete, :patch], credentials: true
      end
    end if Rails.env.development?
    

    Wrote a detailed article here: https://blog.francium.tech/vue-js-cache-not-getting-cleared-in-production-on-deploy-656fcc5a85fe