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:
- Backend Configuration: Adjusting server-side caching headers (Varnish/Fastly) to allow pages to be cached by the browser.
- 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:
Then, add the eventListeners
object to the Alpine component's data. This will call closeMenu()
if the page was restored from bfcache.
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.