Had an issue with bfcache
Today I learned about bfcache when someone pointed out a problem on an example I did of a counter in htmx.
You load the page, counter (whose state is stored on the server) is at 0.
Increment counter, 1, 2, 3. Increment happens without a full page reload.
Go back to a previous page in your browser with the back button, then go forward again to the counter.
Counter is at 0 again.
Not because it reset, but because the browser cached the first full page load in its bfcache (back/forward cache).
You need to refresh the page to see the actual count value.
This only happened in Chrome (and Chrome-based browsers like Arc). Safari? No problem. Firefox? No problem. And also, Chrome with DevTools open with “Cache disabled” setting? No problem (that’s why I didn’t notice).
Solution?
I added these meta tags to my HTML head tag:
<meta http-equiv="Cache-Control" content="no-cache, no-store" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
I could also set them as HTTP headers, for example using Astro:
import { defineConfig } from 'astro/config'
import node from '@astrojs/node'
export default defineConfig({
output: 'server',
adapter: node({
mode: 'standalone',
}),
server: {
headers: {
'Cache-Control': 'no-cache, no-store',
Pragma: 'no-cache',
Expires: '0',
},
},
})
I had a hard time testing this because I couldn’t find a good way to clear the bfcache, until I had the idea of testing in incognito mode, and I was able to see it worked fine.
Read more about bfcache: https://web.dev/articles/bfcache
Note that they suggest using
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
console.log('This page was restored from the bfcache.')
} else {
console.log('This page was loaded normally.')
}
})
to detect a page was restored but this didn’t work at all, persisted is always false and this might be a bug.
Actually it is a bug in Chrome since 2014 🥲
If the no-cache no-store header is not an option, one snippet I found on StackOverflow to reload the page if page was detected to be from the bfcache, taking into consideration Chrome’s “bug”:
window.addEventListener(
'pageshow',
function (event) {
if (
event.persisted ||
performance.getEntriesByType('navigation')[0].type === 'back_forward'
) {
location.reload()
}
},
false,
)
…not optimal, of course.
But interesting.
Never heard of bfcache before.
download all my books for free
- javascript handbook
- typescript handbook
- css handbook
- node.js handbook
- astro handbook
- html handbook
- next.js pages router handbook
- alpine.js handbook
- htmx handbook
- react handbook
- sql handbook
- git cheat sheet
- laravel handbook
- express handbook
- swift handbook
- go handbook
- php handbook
- python handbook
- cli handbook
- c handbook
subscribe to my newsletter to get them
Terms: by subscribing to the newsletter you agree the following terms and conditions and privacy policy. The aim of the newsletter is to keep you up to date about new tutorials, new book releases or courses organized by Flavio. If you wish to unsubscribe from the newsletter, you can click the unsubscribe link that's present at the bottom of each email, anytime. I will not communicate/spread/publish or otherwise give away your address. Your email address is the only personal information collected, and it's only collected for the primary purpose of keeping you informed through the newsletter. It's stored in a secure server based in the EU. You can contact Flavio by emailing [email protected]. These terms and conditions are governed by the laws in force in Italy and you unconditionally submit to the jurisdiction of the courts of Italy.