SkuWatch AI Visibility Agent Install on Shopify

Shopify theme development

Read Shopify Product Variant Data in Liquid (With Code)

Core answer

Copy a Shopify Liquid pattern for the selected variant's ID, SKU, price, availability, URL, and options, then verify the picker stays in sync.

By skuwatch editor

Difficulty
Intermediate
Time
45 minutes
Risk
Theme changes
Last tested
September 9, 2026
SkuWatch AI Visibility Agent loopFix

Direct answer

On a Shopify product template, read the initial purchasable variant from product.selected_or_first_available_variant. Shopify selects the variant from the ?variant=ID URL parameter when it is present; otherwise it returns the first available variant, or the first variant if none are available. Read SKU, price, availability, barcode, options, and the variant-specific URL from that variant object—not from one shared product field.

The Liquid below produces the initial server-rendered facts. Your theme’s variant-picker JavaScript must update the same visible facts after a shopper changes an option. Shopify documents both product.selected_or_first_available_variant and the available variant properties.

What you will verify

You will distinguish product-level facts from sellable variant facts and render a small inspectable fact block that stays synchronized with the selected variant.

Rhode Glazing Milk illustrates the requirement: 4.2 oz and 1.7 oz sizes had separate $32 and $20 offers. Treating the first offer as the whole product would answer a size-specific question incorrectly.

Product facts versus variant facts

Product-level Variant-level
title SKU
vendor or brand context barcode
description option values
product type and category price and compare-at price
shared ingredients availability
shared compatibility inventory-linked state

A bundle may need a third layer for included items.

Exact Shopify Admin path

Online StoreThemes → duplicate live theme → Edit code

Open the main product section used by the product template. In current theme structures this is often under sections/, but the exact filename varies.

Resolve the current variant

{% assign current_variant = product.selected_or_first_available_variant %}

{% if current_variant %}
<dl class="product-facts" data-product-id="{{ product.id }}">
  <div>
    <dt>Product</dt>
    <dd>{{ product.title | escape }}</dd>
  </div>
  <div>
    <dt>Variant</dt>
    <dd>
      {% if current_variant.title == 'Default Title' %}
        Standard
      {% else %}
        {{ current_variant.title | escape }}
      {% endif %}
    </dd>
  </div>
  {% if current_variant.sku != blank %}
  <div>
    <dt>SKU</dt>
    <dd>{{ current_variant.sku | escape }}</dd>
  </div>
  {% endif %}
  <div>
    <dt>Price</dt>
    <dd>{{ current_variant.price | money_with_currency }}</dd>
  </div>
  <div>
    <dt>Availability</dt>
    <dd>{% if current_variant.available %}In stock{% else %}Sold out{% endif %}</dd>
  </div>
  <div>
    <dt>Variant link</dt>
    <dd><a href="{{ current_variant.url }}">View this option</a></dd>
  </div>
</dl>
{% else %}
  <p>This option combination is unavailable.</p>
{% endif %}

This is the initial server-rendered state. The guard handles an unavailable option-value combination in themes that support high-variant products. A variant picker must update the same visible values after selection. Do not replace the theme’s existing picker logic without testing subscriptions, selling plans, quantity rules, and add-to-cart behavior.

Expose a controlled variant payload

Do not serialize the entire product object into arbitrary attributes. Emit only fields the product UI needs.

<script type="application/json" data-product-variants>
[
  {% for variant in product.variants %}
    {
      "id": {{ variant.id | json }},
      "title": {{ variant.title | json }},
      "sku": {{ variant.sku | json }},
      "available": {{ variant.available | json }},
      "price": {{ variant.price | json }},
      "url": {{ variant.url | json }},
      "options": {{ variant.options | json }}
    }{% unless forloop.last %},{% endunless %}
  {% endfor %}
]
</script>

Use a theme component to update price, SKU, availability, the recoverable variant URL, and add-to-cart controls from one selected variant. Do not automatically make every ?variant= URL canonical: keep the theme’s existing canonical strategy unless a deliberate duplicate-URL review supports changing it.

Use the variant object’s url value when you render a link, or add the variant ID as the product URL’s variant parameter. A recoverable URL lets a buyer or catalog record return to the same selection:

<a href="{{ current_variant.url }}">
  {{ product.title | escape }} — {{ current_variant.title | escape }}
</a>

Shopify’s theme guidance for product variants explains deep-linked selection and option availability. The link preserves selection; it does not by itself keep visible price, stock, or the buy button synchronized after an in-page option change.

Real failure patterns

Shared SKU across sizes

The observed Rhode entities used one SKU for two sizes. If Shopify variant records have unique SKUs, ensure the rendered graph reads variant.sku, not a product metafield copied to every variant.

Default Title in public name

The observed HexClad entity exposed Default Title. Suppress that label for a simple product without pretending that all products lack variants.

Offer range versus selected price

Puffy’s Product graph exposed a $449–$1,749 range. That supports discovery, but the selected Queen variant still needs its exact current price when the buyer asks for Queen.

Expected result

Change variants and confirm:

  • option label changes
  • SKU changes where expected
  • price and currency change correctly
  • availability and buy button agree
  • URL or variant parameter remains recoverable
  • structured offer is not stuck on the first variant

Verification

Test with JavaScript enabled and disabled. Save initial HTML for direct retrieval, then inspect the rendered DOM after switching variants. Check at least one in-stock variant, one sold-out variant, and a direct ?variant=ID visit. If you are also fixing the page’s product markup, continue with inspect and fix Shopify Product JSON-LD and compare the selected offer with the visible facts.

Rollback

Keep changes in a duplicate theme. Restore the previous product section if variant picker, analytics, subscriptions, or add-to-cart behavior changes unexpectedly.

Community discussion

Add to the article

Ask a technical question, share a storefront result, or challenge a conclusion with evidence.

Comments are public. Do not post customer data, credentials, private store information, promotional spam, or unsupported accusations. Comments may be moderated.