Alpine structure of LokiComponents

LokiComponents can be seen as a composition of various files - PHP classes, PHTML templates, XML snippets ... and an AlpineJS component. Because the AlpineJS component - by definition - inherits from a parent object LokiComponentType, there are various pieces of functionality that automatically can be used.

AJAX calls and targets

The very essence of LokiComponents is that they allow you to make an AJAX call to the Magento backend to change some state (for instance, add an attribute value to the current quote or set some flag in the customer session): The component update. This is done via the post() method in LokiComponentType.

Built into this post() method is a mechanism of targets. The AlpineJS component receives an array of targets (which resembles a listing of DOM IDs which then again correspond with layout-based block names), so that - once the component update is done - the layout-based blocks are rendered and their HTML is sent back within the same AJAX call. Next, the relevant DOM areas are updated.

Loading state

Various additional tricks come in play here: For instance, there is an Alpine component property loading that is automatically toggled via the post() method. This could lead to a loader icon or a loader overlay to be displayed while loading is true. However, the loading is only shown if the AJAX call takes longer than showLoaderTimeout: Because of this, the flag showLoader is used in the HTML instead.

In a similar way, the HTML attribute aria-busy is applied to the DOM element as well.

Abort controllers

When subsequent AJAX request is sent, while an existing AJAX request is still pending, the previous request is canceled via the browser abortController technology.

initMethods and destroyMethods

In an Alpine component, you could use the init() method when initializing things and you could undo things again with destroy(). An example for this is an initial AJAX call that is required once the Alpine component is loaded. Or a Web Component that needs to be unmounted again when destroying the Alpine component.

However, because Loki Components are made very extensible (as a Loki Component is composed out of parent objects, component partials and custom implementations), it is not uncommon to add your own initialization on top of the core logic. However, the recommendation is not to touch upon the init() and destroy() method at all.

Instead, the parent behaviour of Loki Components guarantees that any method that starts with the word init is run via init(). And likewise, any method that starts with the word destroy is run via destroy().

The following example component illustrates this: The initExample() method and the destroyExample() are automatically called.

document.addEventListener('alpine:init', () => {
    Alpine.data('Example', () => ({
        ...LokiComponentType,
        initExample() {
            ...
        },
        destroyExample() {
            ...
        }
    }));
});
Last modified: August 11, 2025