The architecture of the library is redesigned based on 1.5 years of hands-on experience with Liquid Ajax Cart v1.x.x.
You don’t need to migrate from Liquid Ajax Cart v1.x.x to v2.x.x for existing Shopify stores, unless you want to have the v2.x.x features. The maintenance of the library v1.x.x will be continued.
Meanwhile, it is recommended to use v2.x.x for new Shopify stores, as new features will be introduced to Liquid Ajax Cart v2.x.x only.
Liquid Ajax Cart v2.0.0 introduces the <ajax-cart-quantity> custom tag
and the attributes data-ajax-cart-quantity-plus,
data-ajax-cart-quantity-minus in order to ajaxify “Plus” and “Minus”
cart item quantity buttons.
The new “Plus” and “Minus” buttons don’t initiate a Shopify Cart API Ajax request immediately when clicked. Liquid Ajax Cart gives the user 300 ms time to click the button again before initiating the request (debounce). This approach lets the user change the quantity by more than one before sending the request and before the cart goes to the “processing requests” mode.
v1.x.x approach (still supported in v2.x.x but not recommended):
<a data-ajax-cart-request-button
href="{{ routes.cart_change_url }}?line={{ line_item_index }}&quantity={{ item.quantity | minus: 1 }}" >
Minus one
</a>
<input data-ajax-cart-quantity-input="{{ line_item_index }}"
name="updates[]"
value="{{ item.quantity }}"
type="number" />
<a data-ajax-cart-request-button
href="{{ routes.cart_change_url }}?line={{ line_item_index }}&quantity={{ item.quantity | plus: 1 }}">
Plus one
</a>
v2.x.x approach:
<ajax-cart-quantity>
<a data-ajax-cart-quantity-minus
href="{{ routes.cart_change_url }}?line={{ line_item_index }}&quantity={{ item.quantity | minus: 1 }}" >
Minus one
</a>
<input data-ajax-cart-quantity-input="{{ line_item_index }}"
name="updates[]"
value="{{ item.quantity }}"
type="number" />
<a data-ajax-cart-quantity-plus
href="{{ routes.cart_change_url }}?line={{ line_item_index }}&quantity={{ item.quantity | plus: 1 }}">
Plus one
</a>
</ajax-cart-quantity>
Liquid Ajax Cart v2.x.x doesn’t automatically ajaxifies all the Shopify product forms anymore as the v1.x.x did.
A Shopify product form should be wrapped in the <ajax-cart-product-form>
to be ajaxified:
<ajax-cart-product-form>
{% form 'product', product %}
<!-- form content -->
<button type="submit" name="add">
Add to cart
</button>
{% endform %}
</ajax-cart-product-form>
The js-ajax-cart-form-in-progress CSS class is removed.
Instead, the <ajax-cart-product-form> custom tag gets the loading attribute when in progress.
The js-ajax-cart-set CSS class is removed. Use the js-ajax-cart-init CSS class instead.
The js-ajax-cart-request-in-progress CSS class is renamed to js-ajax-cart-processing.
The js-ajax-cart-form-in-progress CSS class is removed.
Instead, the <ajax-cart-product-form> custom tag gets the loading attribute when in progress.
The js-ajax-cart-not-compatible CSS class is removed.
The data-ajax-cart-bind-state attribute is renamed to data-ajax-cart-bind.
The source of data for the attribute is the liquidAjaxCart.cart property
so there is no need to add the cart. prefix to the attribute’s value.
v1.x.x:
<div data-ajax-cart-bind-state="cart.item_count">
{{ cart.item_count }}
</div>
<div data-ajax-cart-bind-state="cart.total_price | money_with_currency">
{{ cart.total_price | money_with_currency }}
</div>
v2.x.x:
<div data-ajax-cart-bind="item_count">
{{ cart.item_count }}
</div>
<div data-ajax-cart-bind="total_price | money_with_currency">
{{ cart.total_price | money_with_currency }}
</div>
The data-ajax-cart-configuration attribute is removed.
The only way to set configuration parameters is the liquidAjaxCart.conf() method.
The data-ajax-cart-messages attribute is renamed to data-ajax-cart-errors,
as there is no plans anymore to display anything but error messages in it.
If you need to display custom messages based on request results,
use the liquid-ajax-cart:request-end event.
The data-ajax-cart-toggle-class-button attribute is removed.
Liquid Ajax Cart v2.x.x doesn’t export anything.
Access to the API is provided by the global liquidAjaxCart object only.
Most of the methods and properties of the liquidAjaxCart object
are available only after the initialization.
All the subscribeToCart*() functions are replaced with events that are fired at the document.
Therefore, you can subscribe to them even before Liquid Ajax Cart is loaded.
The subscribeToCartSectionsUpdate() is removed.
Subscribe to the liquid-ajax-cart:request-end event instead,
as sections are updated after a successful Shopify Cart API Ajax request.
The subscribeToCartAjaxRequests() function is removed.
Instead, subscribe to the events liquid-ajax-cart:request-start,
liquid-ajax-cart:request-end.
The subscribeToCartStateUpdate() function is removed.
The function let you subscribe to the update of the user’s cart state (state.cart) and
the state.status.requestInProgress properties.
In the v2.x.x the user’s cart state is stored in the liquidAjaxCart.cart property.
To subscribe to its update, use the liquid-ajax-cart:request-end event,
as the cart state is updated after a successful Shopify Cart API Ajax request:
// v1.x.x
liquidAjaxCart.subscribeToCartStateUpdate(( state, isCartUpdated ) => {
if (isCartUpdated) {
console.log("User's cart state is updated");
console.log("New cart state", state.cart);
console.log("Previous cart state", state.previousCart);
}
});
// v2.x.x
document.addEventListener("liquid-ajax-cart:request-end", function(event) {
const {cart, previousCart} = event.detail;
### Request cancellation support
v2 requests accept an optional `signal` in the options object to support aborting in-flight requests via `AbortController`. This helps build optimistic UIs that cancel superseded requests.
if (cart) {
console.log("User's cart state is updated");
console.log("New cart state", cart); // same as liquidAjaxCart.cart
console.log("Previous cart state", previousCart);
}
});
In v2.x.x the state.status.requestInProgress value is stored
in the liquidAjaxCart.processing property.
To subscribe to its update use the events the events liquid-ajax-cart:queue-start
and liquid-ajax-cart:queue-end:
/**
* Listen for Liquid Ajax Cart starts processing requests
*/
// v1.x.x
liquidAjaxCart.subscribeToCartStateUpdate(( state, isCartUpdated ) => {
if (!isCartUpdated && state.status.requestInProgress) {
console.log("Liquid Ajax Cart started processing requests");
}
});
// v2.x.x
document.addEventListener("liquid-ajax-cart:queue-start", function(event) {
console.log("Liquid Ajax Cart started processing requests");
});
/**
* Listen for Liquid Ajax Cart finishes processing requests
*/
// v1.x.x
liquidAjaxCart.subscribeToCartStateUpdate(( state, isCartUpdated ) => {
if (!isCartUpdated && !state.status.requestInProgress) {
console.log("No requests in progress anymore");
}
});
// v2.x.x
document.addEventListener("liquid-ajax-cart:queue-end", function(event) {
console.log("No requests in progress anymore");
});
If you want to run your JavaScript once Liquid Ajax Cart is initialized,
check the liquidAjaxCart.init property
and listen for the liquid-ajax-cart:init event:
function runWhenInit() {
console.log("The current cart state is: ", window.liquidAjaxCart.cart);
}
if (window.liquidAjaxCart?.init) {
// if Liquid Ajax Cart is already initialized
runWhenInit();
} else {
// wait for Liquid Ajax Cart to be initialized
document.addEventListener("liquid-ajax-cart:init", runWhenInit);
}
The detailed explanation on how to interact with Liquid Ajax Cart using JavaScript is in the “Lifecycle, events, API” guide.
The getCartState() function is removed. In order to get the same data,
use the properties of the liquidAjaxCart object.
The user’s cart state is stored in the liquidAjaxCart.cart property.
// v1.x.x
const cart = liquidAjaxCart.getCartState().cart;
// v2.x.x
const cart = liquidAjaxCart.cart
The state.previousCart isn’t stored anywhere.
it is returned by the liquid-ajax-cart:request-end event only.
// v1.x.x
liquidAjaxCart.subscribeToCartStateUpdate(( state, isCartUpdated ) => {
if (isCartUpdated) {
console.log("User's cart state is updated");
console.log("New cart state", state.cart);
console.log("Previous cart state", state.previousCart);
}
});
// v2.x.x
document.addEventListener("liquid-ajax-cart:request-end", function(event) {
const {cart, previousCart} = event.detail;
if (cart) {
console.log("User's cart state is updated");
console.log("New cart state: ", cart); // same as liquidAjaxCart.cart
console.log("Previous cart state: ", previousCart);
}
});
The state.status.requestInProgress value is stored in the liquidAjaxCart.processing property.
// v1.x.x
const isProcessing = liquidAjaxCart.getCartState().status.requestInProgress;
// v2.x.x
const isProcessing = liquidAjaxCart.processing;
The state.status.cartStateSet value is not stored anymore. If Liquid Ajax Cart is initialized, the cart state always exists.
All the function that send Shopify Cart API Ajax requests are replaced
with the methods of the liquidAjaxCart object:
cartRequestGet() → liquidAjaxCart.get();cartRequestAdd() → liquidAjaxCart.add();cartRequestChange() → liquidAjaxCart.change();cartRequestUpdate() → liquidAjaxCart.update();cartRequestClear() → liquidAjaxCart.clear().The firstComplete, lastComplete request parameters are renamed to firstCallback, lastCallback accordingly.
The newQueue parameter is replaced with the important parameter which works in the opposite way:
when the important is true, the request will be added to the beginning of the Queue of requests.
The default value for the important parameter is false.
The configureCart() method is renamed to conf().
The data-ajax-cart-configuration attribute is removed.
The only way to set configuration parameters is the liquidAjaxCart.conf() method.
The productFormsFilter configuration parameter is removed as Liquid Ajax Cart doesn’t ajaxify
Shopify product forms automatically.
The messageBuilder configuration parameter is removed.
If you need to display custom messages based on request results,
use the liquid-ajax-cart:request-end event.
The stateBinderFormatters is renamed to binderFormatters.
The addToCartCssClass configuration parameter is removed.
Use the liquid-ajax-cart:request-end event to append a CSS class
when a product is added to the cart.
The ready snippet: Open the Ajax-cart when a user adds a product to the cart.