"Add To Wishlist Button" Snippet v2

Read this article to learn more about the snippet usage.

Usage:

{% render 'wl-add-button-v2' %}

Code:

{% comment %}
  wl-add-button-v2
  Heart button that adds or removes a product from the wishlist.

  Requires
    - Wishlist app installed
    - App embeds → Wishlist helper enabled (handles clicks; no JS in this file)
    Styles ship inside this snippet, so the button looks correct even if the
    helper is off — but clicks will not work without the helper.

  Setup
    1. Online Store → Themes → Edit code → Snippets → Add a new snippet.
    2. Name it wl-add-button-v2 and paste this file.
    3. Render it on the product page or inside a product card.

  Examples
    Product page (tracks the selected variant):
      {% render 'wl-add-button-v2' %}

    Collection / search / product card (always pass the card product):
      {% render 'wl-add-button-v2', wish_product: card_product, button_position: 'absolute' %}

    Logged-in customers only:
      {% render 'wl-add-button-v2', wish_product: card_product, visibility: 'logged_in_only' %}

  Parameters
    wish_product         Product for cards. Omit on the product page (uses `product`).
    visibility           everyone (default) | logged_in_only
    view                 icon_only (default) | icon_and_text | text_only
    button_position      static (default) | absolute
    content_align        left | center | right (default)
    show_popup           Toast after add/remove. Default: true
    icon_color           Default: #000000
    icon_size            Desktop icon size, px. Default: 20
    icon_size_mobile     Mobile icon size, px. Default: 20
    text_color           Default: #000000
    text_size            Desktop label size, px. Default: 14
    text_size_mobile     Mobile label size, px. Default: 14
    icon_text_gap        Gap between icon and label, px. Default: 6
    margin_top           px. Default: 0
    margin_right         px. Default: 0
    margin_bottom        px. Default: 0
    margin_left          px. Default: 0
    max_width            px. 0 = no limit. Default: 0
    button_border        Show border. Default: false
    button_border_color  Default: #000000
    button_border_width  px. Default: 1
    button_border_radius px. Default: 0
    button_padding_x     px. Default: 0
    button_padding_y     px. Default: 0

  Notes
    - Labels use theme translations (English fallback if missing):
      wishlist.add_to_wishlist
      wishlist.remove
{% endcomment %}

{% liquid
  assign is_blocked = shop.metafields.wishlist.app_blocked
  assign product = wish_product | default: product

  assign visibility = visibility | default: 'everyone'
  assign show_snippet = true
  unless request.design_mode or customer
    if visibility == 'logged_in_only'
      assign show_snippet = false
    endif
  endunless

  assign view = view | default: 'icon_only'
  assign button_position = button_position | default: 'static'
  assign content_align = content_align | default: 'right'
  assign show_popup = show_popup | default: true

  assign icon_color = icon_color | default: '#000000'
  assign icon_size = icon_size | default: 20
  assign icon_size_mobile = icon_size_mobile | default: 20

  assign text_color = text_color | default: '#000000'
  assign text_size = text_size | default: 14
  assign text_size_mobile = text_size_mobile | default: 14
  assign icon_text_gap = icon_text_gap | default: 6

  assign margin_top = margin_top | default: 0
  assign margin_right = margin_right | default: 0
  assign margin_bottom = margin_bottom | default: 0
  assign margin_left = margin_left | default: 0
  assign max_width = max_width | default: 0

  assign button_border = button_border | default: false
  assign button_border_color = button_border_color | default: '#000000'
  assign button_border_width = button_border_width | default: 1
  assign button_border_radius = button_border_radius | default: 0
  assign button_padding_x = button_padding_x | default: 0
  assign button_padding_y = button_padding_y | default: 0

  assign show_icon = true
  assign show_text = false
  if view == 'icon_and_text'
    assign show_text = true
  elsif view == 'text_only'
    assign show_icon = false
    assign show_text = true
  endif

  assign align_class = 'wl-add--align-right'
  if content_align == 'left'
    assign align_class = 'wl-add--align-left'
  elsif content_align == 'center'
    assign align_class = 'wl-add--align-center'
  endif

  assign locale_code = request.locale.iso_code | split: '-' | first | strip
  assign dir_value = 'ltr'
  if locale_code == 'ar' or locale_code == 'he' or locale_code == 'fa' or locale_code == 'ur'
    assign dir_value = 'rtl'
  endif

  assign initial_variant = product.selected_or_first_available_variant
  assign product_image = product.featured_image | default: initial_variant.image

  assign text_add = 'wishlist.add_to_wishlist' | t
  if text_add == 'wishlist.add_to_wishlist'
    assign text_add = 'Add to wishlist'
  endif

  assign text_remove = 'wishlist.remove' | t
  if text_remove == 'wishlist.remove'
    assign text_remove = 'Remove from wishlist'
  endif
%}

{% unless is_blocked or product == blank or show_snippet == false %}
  <style>
    wishlist-add-button:not(:defined) {
      visibility: visible !important;
    }

    .wl-add {
      --wl-add-margin-top: 0;
      --wl-add-margin-right: 0;
      --wl-add-margin-bottom: 0;
      --wl-add-margin-left: 0;
      --wl-add-max-width: none;
      --wl-add-position: static;
      --wl-add-z-index: 100;
      --wl-icon-label-gap: 8px;
      --wl-icon-label-font-size: 14px;
      --wl-icon-label-font-size-md: 16px;
      --wl-icon-label-text-color: currentColor;
      --wl-icon-label-icon-color: currentColor;
      --wl-icon-label-icon-size: 18px;
      --wl-icon-label-icon-size-md: 20px;
      display: flex;
      position: var(--wl-add-position);
      z-index: var(--wl-add-z-index);
      margin: 0;
      width: 100%;
      max-width: var(--wl-add-max-width);
      user-select: none;
    }

    .wl-add--align-left {
      justify-content: flex-start;
    }

    .wl-add--align-center {
      justify-content: center;
    }

    .wl-add--align-right {
      justify-content: flex-end;
    }

    .wl-add__trigger {
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      margin: var(--wl-add-margin-top) var(--wl-add-margin-right)
        var(--wl-add-margin-bottom) var(--wl-add-margin-left);
      width: auto;
    }

    .wl-add .wl-add__trigger:not(.wl-fab) {
      border: none;
      background: none;
      padding: 0;
    }

    .wl-add--snippet .wl-add__trigger:not(.wl-fab) {
      gap: var(--wl-icon-label-gap, 6px);
      border: var(--wl-add-btn-border, none);
      border-radius: var(--wl-add-btn-radius, 0);
      background: none;
      padding: var(--wl-add-btn-padding, 0);
      color: inherit;
      font: inherit;
    }

    .wl-add .wl-icon-label {
      display: inline-flex;
      flex-wrap: nowrap;
      align-items: center;
      gap: var(--wl-icon-label-gap);
      color: var(--wl-icon-label-text-color);
      font-size: var(--wl-icon-label-font-size);
      line-height: 1.2;
    }

    @media screen and (min-width: 768px) {
      .wl-add .wl-icon-label {
        font-size: var(--wl-icon-label-font-size-md);
      }
    }

    .wl-add .wl-icon-label__media {
      display: inline-flex;
      flex-shrink: 0;
      justify-content: center;
      align-items: center;
      width: var(--wl-icon-label-icon-size);
      height: var(--wl-icon-label-icon-size);
      color: var(--wl-icon-label-icon-color);
    }

    @media screen and (min-width: 768px) {
      .wl-add .wl-icon-label__media {
        width: var(--wl-icon-label-icon-size-md);
        height: var(--wl-icon-label-icon-size-md);
      }
    }

    .wl-add .wl-icon-label__media svg,
    .wl-add .wl-icon-label__icon svg {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }

    .wl-add .wl-icon-label__icon {
      display: block;
      width: 100%;
      height: 100%;
    }

    .wl-add .wl-icon-label__icon--filled {
      display: none;
    }

    .wl-add.wl-add--active .wl-icon-label__media .icon-heart {
      fill: currentColor;
    }

    .wl-add.wl-add--active .wl-icon-label__icon--empty {
      display: none;
    }

    .wl-add.wl-add--active .wl-icon-label__icon--filled {
      display: block;
    }

    .wl-add .wl-icon-label__label {
      min-width: 0;
      text-align: inherit;
    }
  </style>

  <wishlist-add-button
    class='wl-add wl-add--snippet {{ align_class }}'
    data-wl-product-id='{{ product.id }}'
    data-wl-variant-id='{{ initial_variant.id }}'
    data-wl-handle='{{ product.handle | escape }}'
    data-wl-product-title='{{ product.title | escape }}'
    {% if product_image != blank %}
      data-wl-product-image='{{ product_image | image_url: width: 120 }}'
    {% endif %}
    {% unless show_popup %}
      data-wl-skip-notification='true'
    {% endunless %}
    dir='{{ dir_value }}'
    style='
      --wl-add-position: {{ button_position }};
      --wl-icon-label-icon-color: {{ icon_color }};
      --wl-icon-label-icon-size: {{ icon_size_mobile }}px;
      --wl-icon-label-icon-size-md: {{ icon_size }}px;
      --wl-icon-label-text-color: {{ text_color }};
      --wl-icon-label-font-size: {{ text_size_mobile }}px;
      --wl-icon-label-font-size-md: {{ text_size }}px;
      --wl-icon-label-gap: {{ icon_text_gap }}px;
      --wl-add-margin-top: {{ margin_top }}px;
      --wl-add-margin-right: {{ margin_right }}px;
      --wl-add-margin-bottom: {{ margin_bottom }}px;
      --wl-add-margin-left: {{ margin_left }}px;
      --wl-add-btn-padding: {{ button_padding_y }}px {{ button_padding_x }}px;
      {% if max_width > 0 %}--wl-add-max-width: {{ max_width }}px;{% endif %}
      {% if button_border %}--wl-add-btn-border: {{ button_border_width }}px solid {{ button_border_color }}; --wl-add-btn-radius: {{ button_border_radius }}px;{% endif %}
    '
  >
    <button
      type='button'
      class='wl-add__trigger'
      aria-pressed='false'
      aria-label='{{ text_add | escape }}'
      data-wl-label-add='{{ text_add | escape }}'
      data-wl-label-remove='{{ text_remove | escape }}'
      data-wl-trigger
    >
      <span class='wl-icon-label' dir='{{ dir_value }}'>
        {% if show_icon %}
          <span class='wl-icon-label__media' aria-hidden='true'>
            <span class='wl-icon-label__icon wl-icon-label__icon--empty'>
              <svg
                class='icon-heart'
                xmlns='http://www.w3.org/2000/svg'
                fill='none'
                viewBox='0 0 24 24'
                aria-hidden='true'
                focusable='false'
              >
                <path
                  stroke='currentColor'
                  stroke-linecap='round'
                  stroke-linejoin='round'
                  stroke-width='1.5'
                  d='M7.87891 3.75c.67013.00152 1.33423.14051 1.9541.40918.61989.26872 1.18439.66253 1.66019 1.16016.1399.14633.3336.22972.5361.23144.2024.00163.3967-.07878.5391-.22266.9658-.9764 2.2584-1.51357 3.5957-1.50488 1.3372.00873 2.6231.5627 3.5771 1.55176.955.98998 1.5 2.33576 1.5088 3.74707.0087 1.41133-.52 2.76473-1.4629 3.76753l-6.6318 6.877c-.3018.3128-.7055.4834-1.1201.4834-.4146-.0001-.8175-.1707-1.1192-.4834l-6.63963-6.8828-.00196-.0029-.17578-.1885c-.3984-.452-.71987-.9742-.94922-1.543-.26198-.6498-.39789-1.34784-.39941-2.0537-.0015-.70608.13124-1.40537.39062-2.05664.25939-.6512.64026-1.24084 1.11817-1.73633.47787-.49543 1.04403-.88648 1.66504-1.15234.62086-.26578 1.28506-.40188 1.95508-.40039'
                />
              </svg>
            </span>
            <span class='wl-icon-label__icon wl-icon-label__icon--filled'>
              <svg
                class='icon-heart'
                xmlns='http://www.w3.org/2000/svg'
                fill='currentColor'
                viewBox='0 0 24 24'
                aria-hidden='true'
                focusable='false'
              >
                <path
                  stroke='currentColor'
                  stroke-linecap='round'
                  stroke-linejoin='round'
                  stroke-width='1.5'
                  d='M7.87891 3.75c.67013.00152 1.33423.14051 1.9541.40918.61989.26872 1.18439.66253 1.66019 1.16016.1399.14633.3336.22972.5361.23144.2024.00163.3967-.07878.5391-.22266.9658-.9764 2.2584-1.51357 3.5957-1.50488 1.3372.00873 2.6231.5627 3.5771 1.55176.955.98998 1.5 2.33576 1.5088 3.74707.0087 1.41133-.52 2.76473-1.4629 3.76753l-6.6318 6.877c-.3018.3128-.7055.4834-1.1201.4834-.4146-.0001-.8175-.1707-1.1192-.4834l-6.63963-6.8828-.00196-.0029-.17578-.1885c-.3984-.452-.71987-.9742-.94922-1.543-.26198-.6498-.39789-1.34784-.39941-2.0537-.0015-.70608.13124-1.40537.39062-2.05664.25939-.6512.64026-1.24084 1.11817-1.73633.47787-.49543 1.04403-.88648 1.66504-1.15234.62086-.26578 1.28506-.40188 1.95508-.40039'
                />
              </svg>
            </span>
          </span>
        {% endif %}
        {% if show_text %}
          <span class='wl-icon-label__label' data-wl-icon-label-text>
            {{- text_add | escape -}}
          </span>
        {% endif %}
      </span>
    </button>
  </wishlist-add-button>
{% endunless %}
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us