Skip to content

Working with sectionData

We’ve greatly simplified the logic of private section data retrieval and invalidation.

Compared to stock Magento, its become a lot simpler to understand and work with.

Note

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

The following are the key things you should know about private section data in Hyvä:

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 no data is present in LocalStorage, one hour has passed, or the private_content_version cookie changed, fresh section data is requested from /customer/section/load on the next page load and stored in LocalStorage. If you need to update the section data before the next page load, you need to dispatch the reload-customer-section-data event manually.

When the data is loaded, the event private-content-loaded is triggered.

// 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.
    //
    // 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(hyva.getDummyPrivateContent());
  }

  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:

Here’s a working example on CodePen:

https://codepen.io/wigman/pen/JjKoOjY?editors=1010

Reloading / Invalidating sectionData

Client side

Reloading customer-section-data can be done with the global reload-customer-section-data event.

Important

In contrast to Magento Luma themes, in Hyvä private content sections are not invalidated individually.

The whole section data is only reloaded from the server if the current data is older than 1 hour, or the private content version cookie is changed.

This can be either after a POST-request, or when the data is more than 1 hour old.

Reload the customer-section-data by dispatching the event

window.dispatchEvent(new CustomEvent("reload-customer-section-data"));

Dispatching the reload-customer-section-data event will cause the section data to be reloaded if it is expired and the private content version is changed. Then the private-content-loaded event will be triggered again.

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);