Home
Wiki
Home
Wiki
  1. 3. Reusables
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ShoppingListsButton
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Shipping
      • ShoppingLists
      • ShoppingListsNavbar
      • Toast
      • Users
      • VariantContent
      • WishlistButton
      • Services
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • Overview
        • theme.js
      • Css / Scss
        • Overview
        • ThemeClasses
    • 5. SDK
      • Overview
      • LiquidGlobals
      • ServicesSDK
  1. 3. Reusables

ProductComparisonButton

Purpose#

The ProductComparisonButton reusable renders a toggle button that adds/removes a product from the comparison list. It also shows toast feedback and disables itself when the comparison list has reached the maximum size.

Where it's rendered#

This reusable is rendered from:
Reusables/ProductGridItem/Default.liquid
{% render 'Reusables\\ProductComparisonButton\\Default', id: product.id, title: product.title %}
Reusables/ProductListItem/Default.liquid
{% render 'Reusables\\ProductComparisonButton\\Default', id: product.id, title: product.title %}
Components/ProductSingle/Default.liquid
{% render 'Reusables\\ProductComparisonButton\\Default', id: product.id, title: product.title %}

Inputs (Liquid render parameters)#

Named parameters:
id
Product id used as the comparison list key.
title
Human-readable product title used for the button title / aria-label.

Template behavior (Liquid + Alpine)#

The button is rendered only when the feature flag is enabled:
GlobalData.Settings.ShowProductComparison
It binds Alpine using a factory:
x-data="productcomparisonbuttonreusabledefault.initComponent('{{ id }}')"
The button uses a toggled state class:
:class="` ${productExists ? 'active' : ''}`"
Disabled behavior:
The template binds :disabled="isDisabled".
The JS sets isDisabled when the list is full and the current product is not already in the list.
On click it calls handleClick(...) and passes translated strings (and an HTML snippet that links to /comparison).

Data contract (JS runtime)#

Model shape (storefront example)#

Example (from a real product model dump) keeping only the relevant fields used by this reusable:
{
  "id": "Product Id",
  "title": "Sample title"
}

Runtime data#

Comparison list
Stored in (and retrieved from) productcomparisondefault.
Maximum supported size is 8 items.
Events
The button listens for the comparisonListUpdated event to refresh its state.
It also listens for the storage event when the comparisonSync key changes.

JavaScript#

Global object#

Global object: productcomparisonbuttonreusabledefault
Liquid wiring:
x-data="productcomparisonbuttonreusabledefault.initComponent('<productId>')"

initComponent(id)#

What it does
Returns an Alpine component instance bound to a specific product id.
Key behaviors / edge cases
The returned object holds local state (productExists, isListFull, isDisabled) derived from the comparison list.
Advice
Keep the id stable (should be the product id). If you pass a variant id instead, you may end up comparing variants instead of products.

init()#

What it does
Loads the comparison list via productcomparisondefault.getList().
Calls updateState().
Subscribes to:
comparisonListUpdated (custom event)
storage event for cross-tab sync (comparisonSync)
Key behaviors / edge cases
If the list changes in another tab, the storage listener keeps the button state in sync.
Advice
Don’t remove the storage listener if you want comparison to work reliably across multiple tabs.

updateState()#

What it does
Computes:
productExists: whether the current id is in the list
isListFull: whether list length is >= 8
isDisabled: list is full AND the product is not in the list
Key behaviors / edge cases
A product that is already in the list stays enabled even when the list is full (so it can be removed).

handleClick(addedProduct, removedProduct, addedProductAndListFull, extraText)#

What it does
Toggles the product in the list.
Persists the updated list via productcomparisondefault.setList(this.list).
Dispatches comparisonListUpdated with a payload { id, timestamp }.
Displays toast feedback using $store.toast:
When removing: uses removedProduct.
When adding:
uses addedProductAndListFull if list becomes exactly 8
otherwise uses addedProduct
In most cases it includes extraText, which contains the link to /comparison.
Key behaviors / edge cases
When the list becomes empty after removing, it uses a toast call without extraText.
Advice
extraText is HTML (includes an <a>). Ensure it is escaped/sanitized at the point it is constructed in Liquid.

Global Alpine stores#

This reusable uses:
$store.toast
add(...) is called to show user feedback after add/remove.

Dependencies#

Liquid: Reusables/ProductComparisonButton/Default.liquid
JS: Reusables/ProductComparisonButton/Default.js
Translations: Reusables/ProductComparisonButton/Default.json
Global JS object: productcomparisondefault (list storage helpers)
Alpine store: $store.toast
Page route: /comparison (used in the toast extra text)

Notes#

Rendering is gated by GlobalData.Settings.ShowProductComparison.
The comparison limit is hard-coded to 8 in updateState().
The button title / aria-label includes title passed from Liquid, so send a human-readable product title.
Modified at 2026-04-14 13:18:56
Previous
ProductAttributes
Next
ProductComparisonFloatingButton
Built with