JavaScript: versioning your files to avoid browser cache

JavaScript and CSS files are usually cached in the browser after the first access. The browser cache is used to store web application assets like images, CSS, and JS code on your computer’s hard drive.

This is so that the next time the web application is opened, your browser simply retrieves the assets for the page from the hard drive instead of downloading the same file from the server.

But the downside of caching is that when you update some assets on your web application (CSS style or JavaScript code) the new version of the code won’t be downloaded because, to the browser, your application still requests the same file.

For example, let’s say you have the following util.js file:

function fnExample() {
  return "Hello";
}

Then you load it into your HTML file <head> tag as follows:

<head>
  <script src="util.js"></script>
  <script>
    document.write(fnExample());
  </script>
</head>
<body>
  <body></body>
</body>

The string "Hello" will be written on your <body> tag, and you’re done. But suppose some time later you decided to change the string from "Hello" to "World" as follows:

function fnExample() {
  return "World";
}

You might find that everything works great in your computer, and you push the update to the server. But because of caching that’s activated on your production server, the file util.js still returns "Hello" instead of "World".

To fix this problem, you needed to add versioning to your util.js file request on the <script> tag. The easiest way would be by adding a query string parameter v as follows:

<head>
  <script src="util.js?v=1"></script>
</head>

By simply adding the versioning query parameter, the browser would consider that the application is requesting a different file, and will download the file instead of serving the one cached on your hard drive. When you update the JS file again, you can bump the version up to version two:

<head>
  <script src="util.js?v=2"></script>
</head>

This simple query string parameter is enough to avoid browser cache, but you can also add an automated versioning to the file name by using timestamp or a randomized 10 number digits to the assets.

Automate versioning with Webpack

If you’re using build tools like Webpack, you can even automate the output file name as shown in the Webpack caching guide. Instead of using a query string parameter, Webpack will append the version of your JavaScript files into the name, for example util.bfjs921.js.

In the following webpack.config.js file, the name of the JS file generated by Webpack follows the [name].[contenthash].js pattern. The contenthash will be replaced by a unique hash based on the content of the file:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.js",
  plugins: [
    new HtmlWebpackPlugin({
      title: "My Web Application",
    }),
  ],
  output: {
    filename: "[name].[contenthash].js",
    path: path.resolve(__dirname, "dist"),
    clean: true,
  },
};

By using this method, the file name of your JS file will always change between builds. For example, you may have the following output file from Webpack when you build your application three times:

main.b746e3eb72875af2caa9.js # first build
main.216e852f60c8829c2289.js # second build
main.ad717f2466ce655fff5c.js # third build

Because Webpack also generates the index.html file, you don’t need to change the <script> tag manually each time the hash changes. Webpack will take care of putting the right <script> tag for you.

Depending on the complexity of your web application, you may choose between simply adding a version query parameter to the <script> tag or using build tools like Webpack to automate the versioning for you.

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.