AlpineJS component store

Within AlpineJS, you could create a data store with Alpine.store() and then allow components to use the data within. It is a scoped alternative to global variables. The LokiCheckout uses this to create two stores: components and checkout - actually the checkout store extends upon the components store.

Components store

The components store is defined in the PHTML template Yireo_LokiComponents::script/components-store.phtml. Every time that a LokiComponent is created, it registers itself in the components store:

Alpine.store('components').add(this);

And thanks to this registration, one component is able to make a connection to another component via the store - provided you know the name of that component. Each LokiComponent has a unique id (which is actually based upon the Magento block name, turned into camelcase) which becomes the name in the store.

Alpine.store('components').get(componentName);

To list all components, we can do the following:

Alpine.store('components').getComponents();

This returns an array of all Alpine components. However, you should note that in AlpineJS, each component is actually an object with a Proxy in front of it. In other words, each entry in the getComponents() is a Proxy. To list all component IDs instead, you can use the following:

Alpine.store('components').getComponentIds();

Adding global messages

Following from this, we can add global messages via Alpine like so:

const globalMessageComponent = Alpine.store('components').get('LokiComponentsGlobalMessages');
globalMessageComponent.messages.push({
    type: 'notice',
    text: 'Hello World'
});

Checkout store

The checkout store is defined in the PHTML template Yireo_LokiComponents::script/components-store.phtml. The checkout store acts as a decorator upon the components store. The following calls are identical:

Alpine.store('components').getComponentIds();
Alpine.store('checkout').getComponentIds();

On top of this, the checkout store adds various additional methods that are handy in the checkout specifically. For instance, most LokiComponents in the checkout also have a step identifier and field name. And we can retrieve specific components by step and field name like so:

Alpine.store('checkout').getComponentByFieldNameAndStep('country_id', 'shipping').id;

The current step is fetched like so:

Alpine.store('checkout').currentStep;

Listing invalid components

In a similar way, the LokiCheckout adds validation to each field (component.valid). And this could be used again to fetch all AlpineJS component that are invalid (component.valid = false):

Object.values(Alpine.store('checkout').getInvalidComponents('shipping')).forEach(component => console.log(component.id));
Last modified: February 26, 2025