Logic based Icons for product card badges?

Topic summary

Goal: add logic-driven icon badges (e.g., Soil Association logo for “Organic”) to Shopify product cards, with conditions to hide when sold out and show when on sale.

Current implementation: card-product.liquid renders a Sold out or On sale badge using Liquid:

  • Sold out when card_product.available == false.
  • On sale when card_product.compare_at_price > card_product.price and available.

Tag-based badges: additional spans render text badges when product tags include:

  • “Organic”
  • “Gluten free”
  • “Alt Meat”
    These are currently text-only and not conditioned to hide on sold-out products.

Key mechanics: Liquid checks for product availability (card_product.available), sale state (compare_at_price > price), and tag presence (card_product.tags contains ‘…’). Icons/logos are not yet implemented (no or SVGs), only text spans.

Attachments: a screenshot and the code snippet are central to understanding the setup.

Status: requester asks how to implement icon badges with the specified logic; no solution posted yet, discussion open.

Summarized with AI on December 12. AI used: gpt-5.

I’ve

added some badges to my product images based on Shopify tags.
I’d like them to be:

  • an icon: IE for organic, the Soil Association logo
  • based on logic, so they don’t show if the product is sold out, but will show if the product is on sale

How can I achieve this?

Here’s my card-product.liquid where I render the badges:

      <div class="card__information">
<h3

class=“card__heading”

{% if card_product.featured_media == null and settings.card_style == ‘standard’ %}

id=“title-{{ section_id }}-{{ card_product.id }}”

{% endif %}

>

<a

href=“{{ card_product.url }}”

id=“StandardCardNoMediaLink-{{ section_id }}-{{ card_product.id }}”

class=“full-unstyled-link”

aria-labelledby=“StandardCardNoMediaLink-{{ section_id }}-{{ card_product.id }} NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}”

>

{{ card_product.title | escape }}

{%- if card_product.available == false -%}

<span

id=“NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}”

class=“badge badge–bottom-left color-{{ settings.sold_out_badge_color_scheme }}”

>

{{- ‘products.product.sold_out’ | t -}}

{%- elsif card_product.compare_at_price > card_product.price and card_product.available -%}

<span

id=“NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}”

class=“badge badge–bottom-left color-{{ settings.sale_badge_color_scheme }}”

>

{{- ‘products.product.on_sale’ | t -}}

{%- endif -%}

{% if card_product.tags contains ‘Organic’ %}

Organic

{% if card_product.tags contains ‘Gluten free’ %}

Gluten free

{% if card_product.tags contains ‘Alt Meat’ %}

Alt Meat

Alt Meat

{% endif %}

The part you need to change is here

{% if card_product.tags contains ‘Organic’ %}

Organic

{% if card_product.tags contains ‘Gluten free’ %}

Gluten free

{% if card_product.tags contains ‘Alt Meat’ %}

Alt Meat
{% endif %}

You can either use an svg or display an image there directly. In the case of the svg the code would end up looking like this

{% if card_product.tags contains ‘Organic’ %}

<svg> <!-- rest of the svg of the Organic icon --> </svg>

{% if card_product.tags contains ‘Gluten free’ %}

<svg> <!-- rest of the svg of the Gluten icon --> </svg>

{% if card_product.tags contains ‘Alt Meat’ %}

<svg> <!-- rest of the svg of the Alt Meat icon --> </svg>

{% endif %}

Or if you just want to use an image you can do the following:

{% if card_product.tags contains ‘Organic’ %}

<img src="{{ 'organic-icon.png' | asset_url }}" alt="Organic" width="24" height"24" loading="lazy">

{% if card_product.tags contains ‘Gluten free’ %}

<img src="{{ 'gluten-icon.png' | asset_url }}" alt="Gluten" width="24" height"24" loading="lazy">

{% if card_product.tags contains ‘Alt Meat’ %}

<img src="{{ 'alt-meat-icon.png' | asset_url }}" alt="Alt Meat" width="24" height"24" loading="lazy">

{% endif %}

In this case the code assumes you have the files organic-icon.png, gluten-icon.png, and alt-meat-icon.png in your theme’s assets folder. If your icons have a different name make sure to update the code accordingly.

Super helpful!

And any thoughts on the logic @StackingContext ?

How can i get the icon badge to show only if the product is in stock? ie out of stock badge replaces all other badges?

You would need to wrap this part in a conditional as follows:

{% if product.available %}
  {% if card_product.tags contains ‘Organic’ %}

    <img src="{{ 'organic-icon.png' | asset_url }}" alt="Organic" width="24" height"24" loading="lazy">
    
    {% if card_product.tags contains ‘Gluten free’ %}
    
    <img src="{{ 'gluten-icon.png' | asset_url }}" alt="Gluten" width="24" height"24" loading="lazy">
    
    {% if card_product.tags contains ‘Alt Meat’ %}
    
    <img src="{{ 'alt-meat-icon.png' | asset_url }}" alt="Alt Meat" width="24" height"24" loading="lazy">
    
    {% endif %}
{% else %}
  {% comment %} Render your out of stock badge here {% endcomment %}
{% endif %}

I am using product.available which can generally be used to check if a product is in stock or not, see more details on its behavior here.