Shopify Theme Traps

Your Variant Has One Image, Your Product Has Twenty: Filtering the Gallery by Selected Variant

A merchant on the Horizon theme asked the question Shopify store owners have asked for a decade: when a shopper picks Black, show only the black images — no paid app, no Plus. Within 24 hours the thread collected every classic failure mode: a layout setting sold as filtering, the one-image-per-variant confusion, a service pitch, and a working-but-fragile code snippet the OP could not get running. This is the answer that thread never got.

TL;DR: “Show only the selected variant’s images” is two different problems wearing one name. Case A — one representative image per color — is native and free on every plan: assign each variant its featured image in the product admin, and on Horizon additionally enable the “Hide other variants’ media after selecting a variant” setting in the Media Gallery block (field report, community-verified in topic 659928; it hides down to the one assigned image per variant). Case B — a whole gallery per color — has no native support at all: product.media is a flat pool shared by every variant, and no Horizon setting changes that. The free, non-Plus, no-app route for Case B is alt-text tagging plus a Custom Liquid/JS filter on product.media; on Plus, Shopify Combined Listings is the zero-code answer. Grid vs. carousel is a layout choice, never a filter.

This is part 1 of our Shopify theme production traps series. The demand evidence is a live Shopify Community thread (topic 659928, a field report we label as such throughout): 13 posts in 24 hours, two follow-ups from the OP, and no accepted answer.

The problem

On August 2, 2026, a merchant posted the question (community topic 659928, Shopify Discussion):

Horizon theme — show only images of the selected color variant. If they click Black, only black images should appear. If they click White, only white images should appear. I don’t want to use any paid app.

Within 24 hours the thread collected 13 posts and every classic failure mode of this question:

The thread ends with no accepted answer and an OP who still doesn’t have a filtered gallery. A second poster linked a parallel Horizon thread (v4.1.3, different store, same symptom) — this is a crowd-level confusion, not one merchant’s bad day.

Root cause

The confusion exists because Shopify’s data model gives you two different things that look alike:

  1. A variant can carry its own media — exposed in Liquid as variant.featured_image / variant.featured_media, and in the Admin GraphQL API as ProductVariant.media. This is what you set when you click a variant in the product admin and assign an image. Exactly one of these is “featured” for the variant, and themes (Horizon included) swap it into the main gallery slot when a shopper selects that variant. This is native, free, and works on every plan.
  2. The product’s media setproduct.media in Liquid — is a flat pool shared by all variants. Any image not assigned to a variant belongs to every color simultaneously. There is no native data structure for “this group of five images belongs to Black.”

So “show only the selected variant’s images” decomposes into two completely different problems:

Case What you want Native support
A One representative image per color, swapped on selection Yes — variant featured image, every theme
B A gallery per color (3–8 shots each), filtered on selection No — not in the data model, not a Horizon setting

Everything that follows is about Case B. If you are in Case A, stop reading: assign each variant its featured image in Products → your product → Variants, and on Horizon additionally enable the “Hide other variants’ media after selecting a variant” setting in the Media Gallery block (theme editor → product template → Media Gallery block settings). Field report, community-verified by three independent posters in topic 659928 (#5, #10 with screenshot, #11); it hides down to the one assigned image per variant, not a multi-image set.

Minimal reproduction

You can reproduce the exact problem in five minutes on a development store:

  1. Create a product “Test Tee” with option Color: values Black, White.
  2. Upload 6 images: 3 black shots, 3 white shots. Assign the first black image as the Black variant’s featured image, first white image as White’s.
  3. Publish with Horizon, product template, Media Gallery in grid mode (Horizon’s default).
  4. On the storefront, select Black: the main image swaps to the black shot — and the other 5 images, including all 3 white shots, remain in the gallery. Select White: same story in reverse.

That is the ceiling of native behavior. No toggle changes it.

Solution

Three routes, in order of preference for a non-Plus store that refuses apps.

Tag every color image with its color in Alt text (Products → product → click image → Alt text → type Black, White, …; leave shared images like size charts untagged). Then filter the gallery on the selected option value. The Liquid half, in a Custom Liquid block or section on the product template:

{% assign current_variant = product.selected_or_first_available_variant %}
{% assign selected_color = current_variant.options.first %}

{% for media in product.media %}
  {% if media.media_type == 'image' %}
    {% if media.alt == blank or media.alt == selected_color %}
      <img
        src="{{ media | image_url: width: 800 }}"
        alt="{{ media.alt | escape }}"
        loading="lazy">
    {% endif %}
  {% endif %}
{% endfor %}

Notes that make or break this in production:

Route 2 — Shopify Combined Listings (free, first-party, Plus only)

If each color genuinely deserves its own full media set — and its own URL for ads and SEO — the first-party answer is Shopify Combined Listings: each color is a separate product with its own images, and the combined listing displays all child products on one product page. Zero code. The catch is hard: Combined Listings are available only to stores on a Shopify Plus plan (shopify.dev, verified 2026-08-05). For the OP, who explicitly excluded both apps and Plus, this route is out — but it is the correct answer for Plus stores and worth knowing before you write any Liquid.

Route 3 — Apps

Exist, work, out of scope: the OP’s constraint was “no paid app,” and Routes 1–2 cover the free space completely.

Decision tree

One image per color?            → Variant featured image (+ Horizon's
                                  "hide other variants' media" toggle). Done.
Multiple images per color?
  ├─ On Plus?                   → Combined Listings. No code.
  └─ Not on Plus?               → Alt-text tagging + Custom Liquid/JS filter.
                                   Match alt text to option names exactly.

Checklist

Where an agent fits

Picking a route is a one-time decision. The ongoing work is everything around it: keeping alt-text tags in sync as new product photos are uploaded, spotting variants whose featured image was never assigned, re-testing the gallery after every theme update, and catching the “it stopped working after we changed the option name” class of regressions before a customer does. That is a scheduled store-hygiene loop — exactly the kind of thing a store operations agent can own: check, compare against the rules, flag the exception to a human with the receipts. We build ready-to-use agents for loops like this; if that’s the hole in your week, they’re worth a look.


Verified against Shopify’s official documentation (Liquid variant.featured_image/featured_media, media.alt and the product.media where-filter pattern, Admin GraphQL ProductVariant.media, Combined Listings availability and behavior) as of August 2026. Community thread content (the Horizon “Hide other variants’ media” setting, the tested alt-text solution, the OP’s failed implementation, the parallel Horizon thread) is a field report from Shopify Community topic 659928 and is labeled as such wherever it appears above.