CartDrawer Web Component
assets/component-cart-drawer.js registers <cart-drawer>, a tiny helper element that listens for Liquid Ajax Cart events and tells Alpine.js to open the cart drawer whenever an item is added.
Source: assets/component-cart-drawer.js
What It Does
- Extends
HTMLElementto define<cart-drawer>. - Subscribes to
liquid-ajax-cart:request-endondocument. - When an add-to-cart request succeeds, dispatches a global
cart-openevent. - Relies on the header/layout Alpine instance to listen for
cart-openand togglecartOpen = true.
API Overview
| Method / Lifecycle | Purpose |
|---|---|
constructor() | Binds onCartRequestEnd to the instance. |
connectedCallback() | Adds the document-level event listener. |
disconnectedCallback() | Removes the listener to avoid leaks when detached. |
onCartRequestEnd(e) | Checks request metadata and fires the cart-open event |
Detailed Methods
constructor()
- Calls
super(). - Binds
this.onCartRequestEnd = this.onCartRequestEnd.bind(this);so the handler can be added/removed cleanly.
connectedCallback()
js
connectedCallback() {
document.addEventListener('liquid-ajax-cart:request-end', this.onCartRequestEnd);
}- Runs when the element enters the DOM (usually when the snippet renders).
- Enables global listening without polluting other parts of the app.
disconnectedCallback()
js
disconnectedCallback() {
document.removeEventListener('liquid-ajax-cart:request-end', this.onCartRequestEnd);
}- Cleans up when the element is removed (e.g., snippet unmounted).
onCartRequestEnd(event)
js
onCartRequestEnd(event) {
const { requestState } = event.detail || {};
if (requestState?.requestType === 'add' && requestState?.responseData?.ok) {
window.dispatchEvent(new CustomEvent('cart-open'));
}
}- Guard clauses ensure only successful
addrequests trigger the drawer. cart-openis a simpleCustomEventthat other scripts (Alpine, theme JS) can listen for.
Registration
js
if (!customElements.get('cart-drawer')) {
customElements.define('cart-drawer', CartDrawer);
}- The guard prevents redefinition during hot reloads or multiple imports.
Integration with Alpine / Theme
In component-cart-drawer.liquid, the <cart-drawer> element typically sits inside an Alpine component that defines cartOpen:
html
<div x-data="{ cartOpen: false }" x-on:cart-open.window="cartOpen = true">
{% render 'component-cart-drawer' %}
</div>- When
component-cart-drawer.jsdispatchescart-open, Alpine updatescartOpenand the drawer slides in. - The same Alpine scope usually toggles the drawer overlay buttons via
@click="cartOpen = !cartOpen".
Implementation Notes
- Ensure Liquid Ajax Cart is enabled so
liquid-ajax-cart:request-endfires; otherwise the component does nothing. - Only one
<cart-drawer>should exist per page; multiple instances could open conflicting UI states. - If you need to close the drawer programmatically after checkout, dispatch a parallel event (e.g.,
window.dispatchEvent(new CustomEvent('cart-close'))) and handle it in Alpine. - Wrapper uses
color-\{\{ settings.cart_color_scheme \}\}for theme integration.