- i only speak liquid
- Posts
- "i only speak liquid" #76: Global State with Alpine
"i only speak liquid" #76: Global State with Alpine
Written by Kenny (a Storetasker Expert)
Hey everyone,
Bittersweet moment! This is Kenny’s 4th and final edit of “i_only_speak_liquid” 🥹
Kenny: Thank you for your 4 incredible contributions. Revisit the past posts here:
#76: Global State with Alpine (you’re reading it!)
And to you dear reader: No need to worry! We have another incredible freelance Shopify developer who will take the pen next & share their unique perspectives.
Stay in touch with Kenny here and stay tuned for our new writer!
Let’s dive in 🤿
What I’ve been thinking about:
In my previous entry of I Only Speak Liquid, I explored how Alpine.js simplifies building accessible UI components. This time, I’d like to dive deeper into another powerful aspect of Alpine.js—managing global state within your Shopify themes. By leveraging Alpine’s global store functionality, you can effectively handle common UI states like menus, search bars, and shopping carts with minimal effort and complexity.
Let's begin by creating an Alpine store called global, where we'll initialize our shared state and define methods to update it.
Step 1: Creating a Global Alpine Store
Here's how you set up an Alpine global store:
document.addEventListener('alpine:init', () => {
Alpine.store('global', {
menuOpen: false,
searchOpen: false,
toggleMenu() {
this.menuOpen = !this.menuOpen;
this.searchOpen = false;
},
toggleSearch() {
this.searchOpen = !this.searchOpen;
this.menuOpen = false;
},
});
});
When Alpine initialized, Alpine.store() will run and set values for handling common state we might encounter in a Shopify theme. The benefit here is huge since any state changes are easily maintained from a single source, making our code much more manageable.
Step 2: Accessing Global Store in Liquid Markup
Once the store is set up, we can effortlessly access the global state across your Shopify theme using Alpine’s $store magic property:
<div>
<button
@click="$store.global.toggleMenu()"
:aria-expanded="$store.global.menuOpen"
aria-controls="main-menu"
class="transition-all duration-200 ease-in-out"
:class="$store.global.searchOpen ? 'text-black/50' : 'text-black'"
>
Menu
</button>
<button
@click="$store.global.toggleSearch()"
:aria-expanded="$store.global.searchOpen"
aria-controls="search"
class="transition-all duration-200 ease-in-out"
:class="$store.global.menuOpen ? 'text-black/50' : 'text-black'"
>
Search
</button>
<div
id="main-menu"
x-show="$store.global.menuOpen"
x-cloak
>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
<div
id="search"
x-show="$store.global.searchOpen"
x-cloak
>
<form @submit.prevent="alert('Search submitted!')">
<div>
<input
type="text"
placeholder="Search for products..."
name="search"
>
<button type="submit">Search</button>
</div>
</form>
</div>
</div>
Step 3: What’s Happening Here?
Event Listeners: The methods toggleMenu() and toggleSearch() from the store are used directly as click handlers, centralizing control.
Dynamic ARIA Attributes: Accessibility attributes (aria-expanded) dynamically reflect the UI state
Dynamic Styling: Using Tailwind CSS utility classes, button colors are dynamically adjusted to visually indicate when another element is active.
Conditional Rendering: x-show directives manage visibility based on the corresponding global state properties.
With Alpine’s global store, maintaining complex UI interactions becomes streamlined, reducing redundancy and making your Shopify theme development more efficient.
3 links you can’t miss:
📌 Getting Things Done: Tried and true methodology for task management and productivity.
📌 Liquid Weekly Podcast: A podcast for Shopify developers.
📌 Blindsight: Not related to Shopify, but for my last post I thought I’d share one of my favorite sci-fi novels.
1 app I like:
Alpine Dev Tools: This app is essential once you start using Alpine. It installs a new tab in the Chrome DevTools where you can detect, inspect and edit Alpine.js data and components.
One learning as a freelancer:
Invest in efficient tools and workflows. I’ve spent a lot of time figuring out what tools I like and how to properly incorporate them into my business so they add value and improve my efficiency. The process to get there is very personal and it takes time to figure out what works and what doesn’t. Early on, I experimented just about every task management app under the sun, but none of them felt right. I knew I wanted to loosely base my system on GTD (referenced above), and I ultimately landed on Notion because I was able to take the parts I from GTD that I liked and build a new system tailored to my specific needs.