Magento 2 & LocalStorage: What Your Browser Knows About You (and Why)

When your Magento 2 site is running with Varnish properly configured, every page is served by the Full Page Cache (FPC), without PHP execution or database. It’s fast, it’s clean, but… how do you display custom elements like:

  • the customer name in the header,
  • confirmation messages,
  • or even the contents of the basket?

🧠 JavaScript, Knockout and localStorage to the rescue

Magento has chosen a full front system based on:

  • Knockout.js to dynamically bind data to the interface,
  • localStorage, via the mage-cache-storage key mage-cache-storage, to store information sensitive to the user context (cart, client, messages, etc.).

🧰 What does it contain mage-cache-storage ?

Magento stores:

  • the contents of the basket,
  • customer information (login, name, etc.),
  • alert messages (success, errors, etc.),
  • any section declared as “volatile” in modules via sections.xml.

🔁 How does Magento update this data?

It automatically makes an Ajax call to:

/customer/section/load?sections=cart,customer,messages

The logic for knowing when to update a section relies on the  sections.xml files provided by each module.
Example :

<action name="checkout/cart/couponPost">
    <section name="cart"/>
</action>

Here, Magento knows that if the URL /checkout/cart/couponPost is called, the cart cart section must be reloaded.

All these mappings are compiled into a JSON file injected into the pages, which allows Magento to prepare the list of sections to follow.

🛠 JS side: Magento_Customer/js/customer-data.js

This file manages everything:

  • listening to Ajax requests with the function onAjaxComplete,
  • detection of actions triggering a section update,
  • update of localStorage, with management of data_id to version the data.

The onAjaxComplete function:

          var sections,
                redirects;
            if (settings.type.match(/post|put|delete/i)) {
                sections = sectionConfig.getAffectedSections(settings.url);

                if (sections && sections.length) {
                    this.invalidate(sections);
                    redirects = ['redirect', 'backUrl'];

                    if (_.isObject(jsonResponse) && !_.isEmpty(_.pick(jsonResponse, redirects))) { //eslint-disable-line
                        return;
                    }
                    this.reload(sections, true);
                }
            }

📥 Fetch data into your JS

Need to access the contents of the shopping cart or the customer’s name?
Start by importing the customer-data module into your JS file:

define([
    'Magento_Customer/js/customer-data'
], function (customerData) {
    var cart = customerData.get('cart')(); // take care of theses 2 "()"

    // Example : Display checkout summary count 
    console.log(cart.summary_count);
});

💡 customerData.get('cart') returns a Knockout observable. So you need to run it () to get the actual data.

🔄 Listen to updates

You can also listen to the changes in real time:

var cart = customerData.get('cart');
cart.subscribe(function (cartData) {
    // Callback triggered every time the "cart" section is updated console.log('Cart updated', cartData);
});

✅ In summary

Magento 2 intelligently combines:

  • an ultra-high-performance caching frontend,
  • and a Knockout-driven localStorage to manage custom data.

This is what allows each customer to see their cart, their messages, without breaking the cache… and without sacrificing performance.