Looking at your Shopify Liquid code, I can see the issue with the color swatches not displaying correctly. The problem is in how the code is trying to access the color metafields and find the correct variants. Here is the updated code that you can use.
{% doc %}
@prompt
duplicate the other AI section "product grid variants" and ensure that all the color variants are linking directly to the color category metafield for each product. There should be three color variants for the tie-front textured one piece, and five color variants for the tie-front bikini top and the staple high rise bottom. Ensure that the color swatches are displaying correctly. , fix the variant display to show the color not size variant
{% enddoc %}
{% assign ai_gen_id = block.id | replace: '_', '' | downcase %}
{% style %}
.ai-product-grid-variants-{{ ai_gen_id }} {
padding: {{ block.settings.section_padding_top }}px 0 {{ block.settings.section_padding_bottom }}px;
}
.ai-product-grid-variants__container-{{ ai_gen_id }} {
max-width: {{ settings.page_width }}px;
margin: 0 auto;
padding: 0 {{ settings.spacing_grid_horizontal }}px;
}
.ai-product-grid-variants__heading-{{ ai_gen_id }} {
text-align: {{ block.settings.heading_alignment }};
margin-bottom: {{ block.settings.heading_margin }}px;
font-size: {{ block.settings.heading_size }}px;
color: rgb(var(--color-foreground));
}
.ai-product-grid-variants__grid-{{ ai_gen_id }} {
display: grid;
grid-template-columns: repeat({{ block.settings.columns_desktop }}, 1fr);
gap: {{ settings.spacing_grid_vertical }}px {{ settings.spacing_grid_horizontal }}px;
margin-bottom: 40px;
}
@media screen and (max-width: 749px) {
.ai-product-grid-variants__grid-{{ ai_gen_id }} {
grid-template-columns: repeat({{ block.settings.columns_mobile }}, 1fr);
}
}
.ai-product-card-{{ ai_gen_id }} {
position: relative;
background: rgb(var(--color-background));
border-radius: {{ settings.card_corner_radius }}px;
{% if settings.card_border_thickness > 0 %}
border: {{ settings.card_border_thickness }}px solid rgba(var(--color-foreground), {{ settings.card_border_opacity | divided_by: 100.0 }});
{% endif %}
{% if settings.card_shadow_opacity > 0 %}
box-shadow: {{ settings.card_shadow_horizontal_offset }}px {{ settings.card_shadow_vertical_offset }}px {{ settings.card_shadow_blur }}px rgba(var(--color-shadow), {{ settings.card_shadow_opacity | divided_by: 100.0 }});
{% endif %}
overflow: hidden;
transition: transform 0.3s ease;
}
.ai-product-card-{{ ai_gen_id }}:hover {
{% if settings.animations_hover_elements == 'vertical-lift' %}
transform: translateY(-5px);
{% elsif settings.animations_hover_elements == '3d-lift' %}
transform: translateY(-5px) scale(1.02);
{% endif %}
}
.ai-product-card__image-wrapper-{{ ai_gen_id }} {
position: relative;
width: 100%;
aspect-ratio: {{ block.settings.image_ratio }};
overflow: hidden;
padding: {{ settings.card_image_padding }}px;
}
.ai-product-card__image-{{ ai_gen_id }} {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: {{ settings.media_radius }}px;
transition: transform 0.3s ease;
}
.ai-product-card-{{ ai_gen_id }}:hover .ai-product-card__image-{{ ai_gen_id }} {
transform: scale(1.05);
}
.ai-product-card__image-placeholder-{{ ai_gen_id }} {
width: 100%;
height: 100%;
background-color: rgba(var(--color-foreground), 0.04);
display: flex;
align-items: center;
justify-content: center;
border-radius: {{ settings.media_radius }}px;
}
.ai-product-card__image-placeholder-{{ ai_gen_id }} svg {
width: 60%;
height: 60%;
opacity: 0.3;
}
.ai-product-card__content-{{ ai_gen_id }} {
padding: 20px;
text-align: {{ settings.card_text_alignment }};
}
.ai-product-card__title-{{ ai_gen_id }} {
font-size: 16px;
font-weight: 500;
margin: 0 0 8px;
color: rgb(var(--color-foreground));
}
.ai-product-card__title-link-{{ ai_gen_id }} {
text-decoration: none;
color: inherit;
}
.ai-product-card__title-link-{{ ai_gen_id }}:hover {
color: rgb(var(--color-button));
}
.ai-product-card__price-{{ ai_gen_id }} {
font-size: 14px;
margin-bottom: 12px;
color: rgb(var(--color-foreground));
}
.ai-product-card__price--sale-{{ ai_gen_id }} {
color: rgb(var(--color-button));
}
.ai-product-card__price--compare-{{ ai_gen_id }} {
text-decoration: line-through;
opacity: 0.7;
margin-left: 8px;
}
.ai-product-card__variants-{{ ai_gen_id }} {
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: {{ settings.card_text_alignment }};
}
.ai-color-swatch-{{ ai_gen_id }} {
position: relative;
width: {{ block.settings.swatch_size }}px;
height: {{ block.settings.swatch_size }}px;
border-radius: 50%;
border: 2px solid rgba(var(--color-foreground), 0.1);
cursor: pointer;
transition: all 0.3s ease;
overflow: hidden;
}
.ai-color-swatch-{{ ai_gen_id }}:hover {
transform: scale(1.1);
border-color: rgb(var(--color-button));
}
.ai-color-swatch__inner-{{ ai_gen_id }} {
width: 100%;
height: 100%;
border-radius: 50%;
background-size: cover;
background-position: center;
}
.ai-color-swatch__tooltip-{{ ai_gen_id }} {
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
background: rgb(var(--color-foreground));
color: rgb(var(--color-background));
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
z-index: 10;
}
.ai-color-swatch-{{ ai_gen_id }}:hover .ai-color-swatch__tooltip-{{ ai_gen_id }} {
opacity: 1;
visibility: visible;
}
.ai-product-grid-variants__empty-state-{{ ai_gen_id }} {
text-align: center;
padding: 60px 20px;
color: rgba(var(--color-foreground), 0.6);
}
.ai-product-grid-variants__empty-state-{{ ai_gen_id }} h3 {
margin: 0 0 8px;
font-size: 18px;
}
.ai-product-grid-variants__empty-state-{{ ai_gen_id }} p {
margin: 0;
font-size: 14px;
}
@media screen and (max-width: 749px) {
.ai-product-grid-variants__container-{{ ai_gen_id }} {
padding: 0 {{ settings.spacing_grid_horizontal | divided_by: 2 }}px;
}
.ai-product-card__content-{{ ai_gen_id }} {
padding: 16px;
}
.ai-color-swatch-{{ ai_gen_id }} {
width: {{ block.settings.swatch_size | times: 0.8 }}px;
height: {{ block.settings.swatch_size | times: 0.8 }}px;
}
}
{% endstyle %}
<product-grid-variants-{{ ai_gen_id }}
class="ai-product-grid-variants-{{ ai_gen_id }} color-{{ block.settings.color_scheme }}"
{{ block.shopify_attributes }}
>
<div class="ai-product-grid-variants__container-{{ ai_gen_id }}">
{% if block.settings.heading != blank %}
<h2 class="ai-product-grid-variants__heading-{{ ai_gen_id }}">
{{ block.settings.heading }}
</h2>
{% endif %}
{% if block.settings.collection != blank and block.settings.collection.products.size > 0 %}
<div class="ai-product-grid-variants__grid-{{ ai_gen_id }}">
{% for product in block.settings.collection.products limit: block.settings.products_to_show %}
<div class="ai-product-card-{{ ai_gen_id }}">
<div class="ai-product-card__image-wrapper-{{ ai_gen_id }}">
{% if product.featured_image %}
<img
src="{{ product.featured_image | image_url: width: 600 }}"
alt="{{ product.featured_image.alt | escape }}"
class="ai-product-card__image-{{ ai_gen_id }}"
loading="lazy"
width="600"
height="{{ 600 | divided_by: product.featured_image.aspect_ratio | round }}"
>
{% else %}
<div class="ai-product-card__image-placeholder-{{ ai_gen_id }}">
{{ 'product-1' | placeholder_svg_tag }}
</div>
{% endif %}
</div>
<div class="ai-product-card__content-{{ ai_gen_id }}">
<h3 class="ai-product-card__title-{{ ai_gen_id }}">
<a href="{{ product.url }}" class="ai-product-card__title-link-{{ ai_gen_id }}">
{{ product.title }}
</a>
</h3>
<div class="ai-product-card__price-{{ ai_gen_id }}">
{% if product.compare_at_price > product.price %}
<span class="ai-product-card__price--sale-{{ ai_gen_id }}">
{{ product.price | money }}
</span>
<span class="ai-product-card__price--compare-{{ ai_gen_id }}">
{{ product.compare_at_price | money }}
</span>
{% else %}
{{ product.price | money }}
{% endif %}
</div>
{% comment %}Color variants only - improved logic{% endcomment %}
{% if block.settings.show_color_variants %}
<div class="ai-product-card__variants-{{ ai_gen_id }}">
{% liquid
assign color_option_index = -1
# Find the color option index
for option in product.options_with_values
assign option_name_lower = option.name | downcase
if option_name_lower contains 'color' or option_name_lower contains 'colour'
assign color_option_index = forloop.index0
break
endif
endfor
# If we found a color option, get unique color variants
if color_option_index >= 0
assign unique_colors = ''
assign color_variants_array = ''
for variant in product.variants
if variant.available
assign variant_color = variant.options[color_option_index] | strip
unless unique_colors contains variant_color
assign unique_colors = unique_colors | append: variant_color | append: '|'
assign color_variants_array = color_variants_array | append: variant.id | append: ','
endunless
endif
endfor
assign color_variant_ids = color_variants_array | split: ','
endif
%}
{% if color_option_index >= 0 and color_variant_ids.size > 0 %}
{% for variant_id_str in color_variant_ids limit: 5 %}
{% if variant_id_str != blank %}
{% assign variant_id = variant_id_str | plus: 0 %}
{% assign current_variant = null %}
{% comment %}Find the actual variant object{% endcomment %}
{% for variant in product.variants %}
{% if variant.id == variant_id %}
{% assign current_variant = variant %}
{% break %}
{% endif %}
{% endfor %}
{% if current_variant %}
{% liquid
assign color_name = current_variant.options[color_option_index] | strip
assign color_hex = current_variant.metafields.custom.color_hex.value
assign color_category = current_variant.metafields.custom.color_category.value
assign variant_image = current_variant.image
# Use color_category if available, otherwise use the variant option
if color_category != blank
assign display_color_name = color_category
else
assign display_color_name = color_name
endif
# If no hex color is set, try to determine from name
if color_hex == blank
assign color_name_lower = display_color_name | downcase
case color_name_lower
when 'black'
assign color_hex = '#000000'
when 'white'
assign color_hex = '#ffffff'
when 'red'
assign color_hex = '#dc2626'
when 'blue'
assign color_hex = '#2563eb'
when 'navy'
assign color_hex = '#1e3a8a'
when 'green'
assign color_hex = '#16a34a'
when 'pink'
assign color_hex = '#ec4899'
when 'purple'
assign color_hex = '#9333ea'
when 'yellow'
assign color_hex = '#eab308'
when 'orange'
assign color_hex = '#ea580c'
when 'brown'
assign color_hex = '#a16207'
when 'grey', 'gray'
assign color_hex = '#6b7280'
when 'beige'
assign color_hex = '#f5f5dc'
when 'tan'
assign color_hex = '#d2b48c'
when 'cream'
assign color_hex = '#fffdd0'
else
assign color_hex = '#9ca3af'
endcase
endif
assign variant_url = product.url | append: '?variant=' | append: current_variant.id
%}
<a
href="{{ variant_url }}"
class="ai-color-swatch-{{ ai_gen_id }}"
title="{{ display_color_name | escape }}"
data-variant-id="{{ current_variant.id }}"
data-color="{{ display_color_name | escape }}"
>
<div
class="ai-color-swatch__inner-{{ ai_gen_id }}"
style="
{% if variant_image %}
background-image: url('{{ variant_image | image_url: width: 100 }}');
{% else %}
background-color: {{ color_hex }};
{% endif %}
"
></div>
<div class="ai-color-swatch__tooltip-{{ ai_gen_id }}">
{{ display_color_name }}
</div>
</a>
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="ai-product-grid-variants__empty-state-{{ ai_gen_id }}">
<h3>No products found</h3>
<p>Select a collection to display products with color variants</p>
</div>
{% endif %}
</div>
</product-grid-variants-{{ ai_gen_id }}>
<script>
(function() {
class ProductGridVariants{{ ai_gen_id }} extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.setupColorSwatches();
}
setupColorSwatches() {
const swatches = this.querySelectorAll('.ai-color-swatch-{{ ai_gen_id }}');
swatches.forEach(swatch => {
swatch.addEventListener('click', (e) => {
e.preventDefault();
const url = swatch.getAttribute('href');
if (url) {
window.location.href = url;
}
});
swatch.addEventListener('mouseenter', () => {
const productCard = swatch.closest('.ai-product-card-{{ ai_gen_id }}');
const variantId = swatch.dataset.variantId;
if (productCard && variantId) {
this.updateProductImage(productCard, variantId);
}
});
});
}
updateProductImage(productCard, variantId) {
const image = productCard.querySelector('.ai-product-card__image-{{ ai_gen_id }}');
const swatch = productCard.querySelector(`[data-variant-id="${variantId}"]`);
if (image && swatch) {
const swatchInner = swatch.querySelector('.ai-color-swatch__inner-{{ ai_gen_id }}');
const backgroundImage = swatchInner.style.backgroundImage;
if (backgroundImage && backgroundImage.includes('url(')) {
const imageUrl = backgroundImage.match(/url\(['"]?([^'"]+)['"]?\)/)[1];
if (imageUrl) {
const newImageUrl = imageUrl.replace(/width=\d+/, 'width=600');
image.src = newImageUrl;
}
}
}
}
}
customElements.define('product-grid-variants-{{ ai_gen_id }}', ProductGridVariants{{ ai_gen_id }});
})();
</script>
{% schema %}
{
"name": "Product grid variants",
"tag": null,
"settings": [
{
"type": "header",
"content": "Content"
},
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "Featured products"
},
{
"type": "select",
"id": "heading_alignment",
"label": "Heading alignment",
"options": [
{
"value": "left",
"label": "Left"
},
{
"value": "center",
"label": "Center"
},
{
"value": "right",
"label": "Right"
}
],
"default": "center"
},
{
"type": "collection",
"id": "collection",
"label": "Collection"
},
{
"type": "range",
"id": "products_to_show",
"min": 2,
"max": 12,
"step": 1,
"label": "Products to show",
"default": 6
},
{
"type": "checkbox",
"id": "show_color_variants",
"label": "Show color variants",
"default": true
},
{
"type": "header",
"content": "Layout"
},
{
"type": "range",
"id": "columns_desktop",
"min": 2,
"max": 4,
"step": 1,
"label": "Columns on desktop",
"default": 3
},
{
"type": "select",
"id": "columns_mobile",
"label": "Columns on mobile",
"options": [
{
"value": "1",
"label": "1"
},
{
"value": "2",
"label": "2"
}
],
"default": "2"
},
{
"type": "select",
"id": "image_ratio",
"label": "Image ratio",
"options": [
{
"value": "1/1",
"label": "Square"
},
{
"value": "3/4",
"label": "Portrait"
},
{
"value": "4/3",
"label": "Landscape"
}
],
"default": "3/4"
},
{
"type": "header",
"content": "Color swatches"
},
{
"type": "range",
"id": "swatch_size",
"min": 20,
"max": 40,
"step": 2,
"unit": "px",
"label": "Swatch size",
"default": 28
},
{
"type": "header",
"content": "Style"
},
{
"type": "color_scheme",
"id": "color_scheme",
"label": "Color scheme",
"default": "background-1"
},
{
"type": "range",
"id": "heading_size",
"min": 16,
"max": 48,
"step": 2,
"unit": "px",
"label": "Heading size",
"default": 32
},
{
"type": "range",
"id": "heading_margin",
"min": 0,
"max": 60,
"step": 4,
"unit": "px",
"label": "Heading margin bottom",
"default": 32
},
{
"type": "header",
"content": "Section padding"
},
{
"type": "range",
"id": "section_padding_top",
"min": 0,
"max": 100,
"step": 4,
"unit": "px",
"label": "Top padding",
"default": 40
},
{
"type": "range",
"id": "section_padding_bottom",
"min": 0,
"max": 100,
"step": 4,
"unit": "px",
"label": "Bottom padding",
"default": 40
}
],
"presets": [
{
"name": "Product grid variants"
}
]
}
{% endschema %}
What to Check in Your Shopify Admin:
-
Metafield Names: Ensure your metafields are named exactly:
-
Metafield Scope: Make sure these metafields are set on Product Variants, not just products.
-
Product Options: Verify your products have a “Color” option (case-insensitive).
Please let me know if this works for you!.
Best,
Daniel