01 Feb 2021  guides

CSS Cache-Busting in BunnyCDN using Jekyll Variables

There’s an easy way of combining Jekyll functionality with BunnyCDN’s features to ensure your visitors always get the most recent version of your CSS file, thus preventing any stale CSS cached in the browser from overriding newly deployed assets.

Reference BunnyCDN

The first thing to do after setting up your BunnyCDN Pull Zone is to configure Jekyll to serve CSS, JS, and other assets from the CDN instead of your origin server.

An easy way to work with CDN URLs in Jekyll is by using variables. In your _config.yml file, you can use the following to enable your Pull Zone URL to be accessible across your entire site:

assets: "https://assets.paramdeo.com"

Serve CSS from BunnyCDN

Using that example, you can then change the URL that your CSS is served from to match your chosen Pull Zone. In your head.html (or wherever you have your CSS relationship declared), change the CSS location to the following:

<link href="{{ site.assets }}/css/style.css" rel="stylesheet">

Now when you build your site, the CSS will be served from the CDN.

If you’re serving locally for an extended period of time and need to use the local CSS for real-time changes to appear, simply comment out the assets: "https://assets.paramdeo.com" in your _config.yml file and the variable will not resolve and thus will be ignored, thereby serving CSS locally. Next we’ll move onto the issue of cache busting.

Vary Cache from BunnyCDN at Build Time

BunnyCDN has a neat feature in their Pull Zone options to allow for varying the cache via URL Query String. You can find this option in your BunnyCDN account by navigating to Pull Zones > foobar > Caching > General.

Scrolling to the bottom under Vary Cache you’ll be presented with the following options. Select URL Query String and save your vary configuration as shown below:

Now, if you call for example https://assets.paramdeo.com/css/style.css?text=1234 you would be served up a fresh CSS file from BunnyCDN, which effectively invalidates the older version that exists in your (and your user’s) local browser cache. The only thing left to do is automate this process.

Generate Query String at Build Time

Timestamps in Jekyll are mostly used to get the date that a post was published, but Jekyll also has a variable called {{ site.time }} which returns the current time (i.e. the time that Jekyll processed that variable when building/serving).

If you glance at my site’s footer for example, this is what I use to display the build time of my site.

{{ site.time }} accepts the same filtering arguments for formatting  as any other Liquid variable in Jekyll. And because the site’s timestamp is generated when a build is completed, it will always be unique.

The goal is to therefore choose a timestamp format that can be validly passed to a query string, i.e. no spaces or special characters. For this, Jekyll provides the %s placeholder, which returns an integer representing the number of seconds since 1970-01-01 00:00:00 UTC, which is also known as UNIX Time.

Going back to our CSS markup in head.html, we can now insert this variable in our markup:

<link href="{{ site.assets }}/css/style.css?timestamp={{ site.time | date: '%s' }}" rel="stylesheet">

An example of the output after building the site would look like https://assets.paramdeo.com/css/style.css?timestamp=1612197275. Such a URL will be different each time the site is built, and therefore will cause the user to fetch a fresh version of your site’s CSS.

In this way, you can lengthen the time that CSS and other assets are cached in BunnyCDN, while keeping the HTML cache value lower. This allows a visitor to pull fresher HTML (which will reflect changes to your content) and also invalidate the browser’s CSS cache if the HTML tells it to do so.

While this method caters to Jekyll since that’s the Static Site Generator (SSG) that I use, varying the cache via query string is really a feature that’s built into BunnyCDN (and most other CDNs for that matter); so it should work in a similar manner for any SSG and that supports passing of the build time as an integer.

Webmentions & Comments

Copyright © Paramdeo Singh. Built with Jekyll and ❤ in Guyana. All Rights Reserved.

Last Site Build on Fri, 26 Feb 2021 11:52:37 -0400