Description: Manage application-wide state (e.g., user auth, theme) using centralized, reactive data stores accessible from any component via $store.
Alpine.store(): This is the primary function used to define a global store. You provide a name for your store and an object containing its initial state (data properties) and methods to manipulate that state.
document.addEventListener('alpine:init', () => {
Alpine.store('myStore', {
message: 'Hello from store!',
updateMessage(newMessage) {
this.message = newMessage;
}
});
});
$store.storeName.property: Once a store is defined, any Alpine component can access its properties using the magic $store object. For the example above, you could display the message in your HTML like this:
<div x-data>
<p x-text="$store.myStore.message"></p>
</div>
Methods within store to modify state: Stores can (and should) contain methods that encapsulate the logic for changing their state. This promotes better organization and makes state changes predictable. These methods are also accessed via $store.
<div x-data>
<button @click="$store.myStore.updateMessage('New message!')">
Update Message
</button>
</div>
When a method updates a property in the store, Alpine's reactivity system ensures that any part of your UI using that property will automatically update.
alpine:init event: This browser event is crucial. It fires after Alpine.js has fully initialized itself but *before* it initializes components on the page. This is the correct place to define your global stores using Alpine.store(). This ensures stores are available when components try to access them.
document.addEventListener('alpine:init', () => {
// Define all your Alpine.store() and Alpine.data() here
Alpine.store('user', { loggedIn: false });
Alpine.store('settings', { theme: 'light' });
});
Stores must be defined before components access them: Python developers are used to modules being importable anywhere. In AlpineJS, Alpine.store() definitions must execute *before* any component (x-data) that tries to use $store.yourStore is initialized. The standard and safest way to ensure this is by defining all stores within an event listener for alpine:init. If you define a store after a component has initialized and tried to access it, you'll encounter errors like "$store.yourStore is undefined".
Avoid monolithic stores for complex apps: While it might be tempting to put all global state into one giant store, this can become unwieldy in larger applications, similar to having a single massive global dictionary in Python. It's often better to create multiple, focused stores (e.g., Alpine.store('user', ...), Alpine.store('cart', ...), Alpine.store('ui', ...)). This improves organization, makes state easier to reason about, and reduces the chance of naming conflicts. Think of them as specialized modules for your frontend state.
Total Items:
Total Price:
Items in cart:
Subtotal: