Back-Forward Cache (bfcache) for Instant Navigation
The back-forward cache (bfcache) is a browser optimization for instant page restoration. When users click the browser's back or forward buttons, bfcache restores complete page snapshots from memory instead of reloading the entire page. This browser caching mechanism dramatically improves navigation performance and Core Web Vitals metrics by providing nearly instantaneous page transitions.
Hyvä themes are bfcache-compatible, but Magento 2's default Cache-Control: no-store header blocks browser page caching. Enabling bfcache for instant back-forward navigation requires two changes: modifying server cache control headers to allow browser page storage, and adding frontend JavaScript handlers to reset component state when pages are restored from the browser cache.
Implementation Overview
Enabling bfcache in a Hyvä theme involves two components:
- Backend Configuration: Modify Varnish or Fastly VCL to remove
no-storefrom theCache-Controlheader, allowing browsers to cache pages for back-forward navigation - Frontend Implementation: Add
pageshowevent listeners to JavaScript components that need to reset state or refresh data when a page is restored from cache
Backend Configuration: Removing no-store from Cache Headers
Magento 2 sends Cache-Control: no-store by default, which explicitly prevents browsers from storing pages in any cache, including the bfcache. To enable browser back-forward caching, modify the Varnish VCL configuration to remove the no-store directive while preserving other cache control behaviors that prevent regular HTTP caching.
Varnish VCL Patch for bfcache Support
The following VCL patch enables bfcache by changing the server-sent Cache-Control header. The modification removes no-store from the header value while keeping no-cache and must-revalidate, which allows browsers to store pages in the bfcache for instant back-forward navigation while still preventing traditional HTTP caching of dynamic Magento content.
Apply this patch to your Varnish VCL files for versions 4, 5, and 6. Each version requires the same single-line change in the vcl_deliver subroutine:
Varnish VCL Patch for bfcache Support
This patch was generated using the default Magento vcl.
diff --git a/etc/varnish4.vcl b/etc/varnish4.vcl
index ffb489c..07e0fd6 100644
--- a/etc/varnish4.vcl
+++ b/etc/varnish4.vcl
@@ -212,7 +212,7 @@ sub vcl_deliver {
if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
- set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
+ set resp.http.Cache-Control = "no-cache, must-revalidate, max-age=0";
}
if (!resp.http.X-Magento-Debug) {
diff --git a/etc/varnish5.vcl b/etc/varnish5.vcl
index 3347b93..6f72ad0 100644
--- a/etc/varnish5.vcl
+++ b/etc/varnish5.vcl
@@ -209,7 +209,7 @@ sub vcl_deliver {
if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
- set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
+ set resp.http.Cache-Control = "no-cache, must-revalidate, max-age=0";
}
if (!resp.http.X-Magento-Debug) {
diff --git a/etc/varnish6.vcl b/etc/varnish6.vcl
index 4e07ac5..e32be55 100644
--- a/etc/varnish6.vcl
+++ b/etc/varnish6.vcl
@@ -215,7 +215,7 @@ sub vcl_deliver {
if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
- set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
+ set resp.http.Cache-Control = "no-cache, must-revalidate, max-age=0";
}
if (!resp.http.X-Magento-Debug) {
Alternative: Third-Party Extensions
For more granular control over caching headers without manual VCL modifications, consider the Elgentos VarnishExtended extension.
Fastly Configuration
Fastly CDN requires similar VCL modifications. For Fastly-specific instructions, see the Mage-OS Theme Optimization module documentation.
Frontend Implementation: Handling Restored Page State
When a browser restores a page from bfcache, the page's JavaScript state is preserved exactly as it was when the user navigated away. Dynamic components like open mobile menus, modal dialogs, or loading spinners remain in their previous state after bfcache restoration. Analytics trackers, cart totals, and other data-dependent components may display stale information because they don't re-execute their initialization code during bfcache page restoration.
To handle bfcache page restoration properly, frontend components must detect when the page is restored from the browser cache and reset their state or refresh their data as needed.
Detecting bfcache Page Restoration with pageshow Event
The browser's pageshow event fires whenever a page becomes visible, including both normal page loads and bfcache restorations. The event.persisted property indicates whether the page was restored from bfcache (true) or freshly loaded (false).
Use this event listener pattern to detect bfcache restoration and trigger component state resets:
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// Page was restored from bfcache - reset state as needed
console.log('Page restored from browser back-forward cache');
}
});
The event.persisted property is the reliable indicator for bfcache restoration. Always check this property rather than assuming every pageshow event represents a restoration.
Resetting Component State with Alpine.js
Alpine.js components in Hyvä themes can listen for the pageshow event using Alpine's event binding syntax. The following example demonstrates how to reset mobile menu state when a page is restored from bfcache.
Resetting Mobile Menu on bfcache Restore
In your mobile.phtml template, add the x-bind directive to the component's root element:
Add the eventListeners object to the Alpine component's data to close the menu when the page is restored:
bfcache Compatibility in Hyvä Default Theme
Built-in bfcache Support in Hyvä Default Theme v1.4+
All native components in Hyvä Default Theme version 1.4 and later include bfcache-compatible pageshow event handlers. Custom components and third-party scripts (analytics, chat widgets, etc.) must implement their own pageshow handlers to ensure correct behavior when pages are restored from the browser back-forward cache.