Table of Contents & Menu
Navigation

Working with sectionData

What is section data?

"Customer Section Data" allows Magento to expose server-side session data to browser JavaScript, especially on full-page cached pages.

Hyvä significantly simplifies private section data retrieval and invalidation compared to stock Magento (Luma). This guide covers essential details for working with it.

sectionData in a Nutshell

  • Customer Section Data is loaded via Ajax and stored in local storage.
  • On every page load it is broadcast with the JS event private-content-loaded.
  • The data is automatically invalidated after HTTP POST requests. A fresh version is loaded after the next page load.
  • Following Ajax POST requests, refresh the section data manually without a new page load by dispatching the reload-customer-section-data event.
  • To force a refresh even without a POST request, run hyva.setCookie('mage-cache-sessid', '', -1, true); before dispatching reload-customer-section-data.

Note

We use the terms "private section data", "section data", "private data" and "private content" interchangeably.

Important

In Hyvä it is not possible to subscribe to specific sections. All sections are always combined in one data object.

Initialization of sectionData

The initialization of sectionData is triggered in the footer of every page.

If a visitor lacks a private_content_version cookie, default section data is used. After any HTTP POST action sets this cookie, section data is fetched via Ajax and stored in LocalStorage.

Section data is refreshed from the server and stored in LocalStorage if:

  • LocalStorage data is deleted.
  • One hour has passed.
  • The private_content_version cookie changes on the next page load.
To update data *before* the next page load (e.g., after an Ajax POST), manually dispatch the reload-customer-section-data event.

After the section data is loaded, the event private-content-loaded is dispatched.

// this happens in the footer of every page

{
  function dispatchPrivateContent(data) {
    const privateContentEvent = new CustomEvent('private-content-loaded', {
      detail: {
        data: data
      }
    });
    window.dispatchEvent(privateContentEvent);
  }

  function loadSectionData() {
    // 1. load privateContent from localStorage or default values for visitors without a session.
    //
    // 2. determine if privateContent is valid.
    //    invalidation happens after 1 hour,
    //    or if the private_content_version cookie changed.
    //
    // 3. fetch privateContent from /customer/section/load if needed
    //
    // 4. dispatch privateContent event
    dispatchPrivateContent(data);
  }

  window.addEventListener('load', loadSectionData);
  window.addEventListener('reload-customer-section-data', loadSectionData);
}

Receiving customer data in Alpine.js components

We can receive customer data in Alpine.js by listening to the private-content-loaded event on the window:

<div x-data="" @private-content-loaded.window="console.log($event.detail.data)">

Here’s an example component that receives the customer and cart data and displays the customer name:

<script>
"use strict";

function initComponent() {
  return {
    cart: false,
    customer: false,
    receiveCustomerData(data) {
      if (data.cart) {
        this.cart = data.cart;
      }
      if (data.customer) {
        this.customer = data.customer;
      }
    }
  }
}
</script>

<div x-data="initComponent()"
     @private-content-loaded.window="receiveCustomerData($event.detail.data)"
>
  <template x-if="customer">
    <div>Welcome, <span x-text="customer.firstname"></span></div>
  </template>

  <template x-if="!customer">
    <div>Welcome Guest</div>
  </template>

</div>

Receiving the customer data in native JavaScript

<script>
"use strict";

function initGTM(event) {
  const sectionData = event.detail.data;

  if (sectionData.customer && sectionData.customer.firstname) {
    console.log('Welcome, ' + sectionData.customer.firstname);
  }

}

window.addEventListener('private-content-loaded', initGTM);
</script>

See it in action

To inspect the data dispatched with the private-content-loaded event, run this in your browser console:

addEventListener('private-content-loaded', event => console.log(event.detail.data));
dispatchEvent(new Event('reload-customer-section-data'));

Reloading / Invalidating sectionData

Client side

Reloading customer section data can be done by triggering the reload-customer-section-data event.

Important

Unlike Magento Luma, Hyvä does not invalidate private content sections individually. The entire section data is reloaded from the server only if:

  • The current data is over 1 hour old.
  • The private_content_version cookie changes (typically after a POST request).

Reload the customer-section-data by dispatching the event

window.dispatchEvent(new Event('reload-customer-section-data'));

Dispatching `reload-customer-section-data` reloads section data if it's expired or the private content version has changed. The `private-content-loaded` event is then triggered.

If you want to force-reload the section-data, this can be done by removing the mage-cache-sessid before dispatching the reload-customer-section-data event:

hyva.setCookie('mage-cache-sessid', '', -1, true); // remove the cookie
window.dispatchEvent(new CustomEvent("reload-customer-section-data")); // reload the data

The private-content-loaded event will always be triggered after reloading the sectionData, regardless if it was requested from the server or read from local storage.

Server side

To force the frontend to refresh the section data from the backend, either the mage-cache-sessid cookie or the private_content_version cookie need to be deleted.

The latter is done by Magento on any frontend or GraphQL POST request (but not for the REST api).

To do the same in custom PHP code during any POST request, inject Magento\Framework\App\PageCache\Version and call $version->process().

To force the refresh in a GET request, copy the code from Version::process.
(keep in mind that GET request responses are usually cached in the FPC).

$publicCookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata()
    ->setDuration(self::COOKIE_PERIOD)
    ->setPath('/')
    ->setSecure($this->request->isSecure())
    ->setHttpOnly(false);
$this->cookieManager->setPublicCookie(self::COOKIE_NAME, $this->generateValue(), $publicCookieMetadata);

Declaring default section data values

Since Hyvä 1.3.6

When a visitor lacks a server-side session, default section data is dispatched directly from the page source, not via Ajax. This reduces API requests and server load. Visitors without a session haven't interacted with the server to update state, so they receive default data. A session is created on the first HTTP POST request.

Some extensions may require section data to always be fully populated.
In such cases, the default value for the required section can be configured in the modules etc/frontend/di.xml file.

For example, the following configuration causes the directory-data section not to be emptied in the default section data, and, the wishlist section data is set to contain an empty items array.

<type name="Hyva\Theme\ViewModel\CustomerSectionData">
    <arguments>
        <argument name="defaultSectionDataKeys" xsi:type="array">
            <item name="directory-data" xsi:type="boolean">true</item>
            <item name="wishlist" xsi:type="string">{"items": []}</item>
        </argument>
    </arguments>
</type>

All other sections not explicitly listed in the configuration will be set to an empty array in the default data.