Skip to content

Back-forward Cache (bfcache)

The back-forward cache (bfcache) is a browser optimization that enables instant back and forward navigation.

Hyvä themes support bfcache, but it requires some configuration to enable, as it is not yet a standard feature in Magento 2.

Enabling bfcache involves two main steps:

  1. Backend Configuration: Adjusting server-side caching headers (Varnish/Fastly) to allow pages to be cached by the browser.
  2. Frontend Implementation: Updating JavaScript components to correctly handle page state when a page is restored from the cache.

Backend Configuration: Varnish & Fastly

By default, Magento 2 sends a Cache-Control: no-store header, which prevents browsers from using bfcache. To enable bfcache, you must remove this no-store directive.

You can do this by applying the following patch to your Varnish VCL files;

Patch to remove no-store from Varnish 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) {

Alternatively, you can use a third-party extension that provides more granular control over caching headers.

For example the Elgentos VarnishExtended

Frontend Implementation

When a page is restored from bfcache, its previous JavaScript state is preserved. This can cause issues with dynamic components, which may need to be reset to their default state (e.g., closing a mobile menu) or have their content updated (e.g., analytics trackers).

You can handle these situations by listening for the pageshow window event. If event.persisted is true, the page was restored from bfcache.

Example: Resetting the Mobile Menu

To ensure the mobile menu is closed when a user navigates back to a page, you can add a pageshow event listener to your AlpineJS component.

First, in your mobile.phtml template, add the x-bind directive to the component's root element:

x-bind="eventListeners"

Then, add the eventListeners object to the Alpine component's data. This will call closeMenu() if the page was restored from bfcache.

eventListeners: {
    ['@pageshow.window'](event) {
        if (event.persisted) {
            this.closeMenu();
        }
    }
}

Supported by default in the Default Theme v1.4+

Native components in the Hyvä Default Theme (v1.4+) are already bfcache-compatible. You only need to ensure your custom and third-party scripts (e.g., analytics) are also compatible.

Resources