How Shopify variant images actually work
Every product in Shopify has a media gallery, up to 250 items. Every variant of that product can point at exactly one item in that gallery. That single pointer is the entire variant image system. There is no per-variant gallery, no "these five photos belong to Navy" grouping in the core data model. A variant either has a featured image or it does not.
Three consequences fall out of that model, and most assignment mistakes are a failure to internalise one of them:
- One image can be shared by many variants. Navy / S, Navy / M and Navy / L can all point at the same navy photo. This is the correct setup for any option, like size, that does not change how the product looks.
- Images not linked to any variant are just gallery images. Your lifestyle shot, your detail shot and your size chart can sit in the gallery unlinked. They still appear; they just never get promoted when an option changes.
- The product's featured image and a variant's image are different things. Position 1 in the gallery is the product featured image, used in collections and search. A variant's image is what the product page switches to when that variant is selected. They can be the same photo, but nothing forces them to be.
| Concept | Where it lives | What it controls |
|---|---|---|
| Product featured image | Gallery position 1 | Collection grids, search results, social previews |
| Variant image | Pointer on each variant | Main image when that variant is selected |
| Gallery image (unlinked) | Gallery, any position | Thumbnails; shown but never auto-selected |
| Option swatch | Option value (colour swatch / metafield) | The little chip in the selector, not the main image |
The swatch row deserves a note. Since Shopify introduced category-linked colour swatches, the chip that a shopper clicks is driven by the option value, not by the variant image. Assigning a variant image does not make a swatch appear, and adding a swatch does not change what the main image does. Treat them as two separate fields to fill. For the swatch side, variant swatch images that convert covers the specs.
What the theme does when a shopper changes an option
Assignment only matters because themes act on it. In Dawn and every Online Store 2.0 theme built on the same pattern, the behaviour on option change is:
- Resolve the newly selected combination of options to a variant.
- If that variant has a featured image, scroll or swap the main media to it.
- Otherwise, leave the gallery where it is.
Step 3 is why "the image didn't change when I picked Navy" happens. Nothing is broken; the Navy variant simply has no pointer, so the theme has nothing to jump to. The same logic explains the opposite complaint: "picking Large jumped to a random photo." Someone assigned an image to Large but not to Medium, so the size selector behaves inconsistently.
Newer versions of Dawn add an optional setting to hide media that belongs to other variants. With it on, selecting Navy shows only the images linked to Navy plus any unlinked gallery images. That is closer to what merchants expect, but it raises the stakes: any image you forgot to link to the right variant disappears from that variant's gallery entirely, and any image you linked to the wrong one shows up under the wrong colour. The setting is a good idea for colour-led catalogues and a bad idea for catalogues with sloppy assignment.
Before enabling per-variant media filtering in your theme, export products to CSV and sort by the Variant Image column. Every variant with an empty cell is a variant whose gallery will collapse to the unlinked images only. Fix the empties first.
The three assignment mistakes on real catalogues
Across apparel and accessories stores, variant image problems fall into a small number of patterns. The fix is different for each, so it is worth diagnosing which one you have.
1. Sizes assigned like colours
The most common mistake. A merchant photographs a beanie once, then uploads the same file three times, once for S, M and L, and links each copy to its size. The gallery now has three identical images, the product featured image is ambiguous, and every colour multiplies the duplication. Sizes should share one pointer, not own one copy each. The rule: assign per visual option, share per non-visual option. Colour, pattern and material get their own image; size, length and quantity share the image of whatever colour they belong to.
2. Half-assigned options
Navy and Black are linked, Forest is not, because Forest was added later by a different person. Shoppers picking Forest see Black. This is a process problem: variant assignment is not part of the "add a new colourway" checklist, so it gets skipped. It is invisible in the admin, which lists the product as having images, and only shows up on the storefront.
3. Right image, wrong pointer
The photos are all present and the number of links is correct, but the navy variant points at the black photo. This usually comes from CSV imports where the Variant Image column was filled by row order rather than by matching the filename to the colour, or from a bulk-editor session where rows were sorted after the images were pasted. It is the hardest to spot because every variant does switch the image; it just switches to the wrong one.
What shoppers see when assignment is wrong
- Image does not change when they pick a colour
- Gallery jumps between unrelated photos on size change
- Duplicate thumbnails of the same shot
- Wrong colour shown as "selected"
What they see when it is right
- Every colour swaps to its own hero shot
- Size changes leave the gallery alone
- One thumbnail per distinct image
- Filtered gallery shows only that colour's photos
A naming and ordering scheme that makes assignment mechanical
Variant assignment stops being error-prone when you stop making it a judgement call. Two conventions get you there.
Encode the option value in the filename. beanie-rib-navy-front.jpg tells you, and any script or bulk tool, exactly which variant it belongs to. IMG_4821.jpg tells you nothing, and beanie-1.jpg tells you only the order. When you push a finished image into Shopify, set the filename at push time rather than renaming afterwards; the same push should carry alt text that names the colour too ("Ribbed knit beanie in navy, front view"), because alt text is what screen readers announce when the variant changes and what image search indexes per colour. The Shopify image metadata guide covers how those fields travel together.
Order the gallery by option value, then by view. All navy images together, front first; then all black images together, front first; then unlinked lifestyle and detail shots at the end. This does two things. On themes without per-variant filtering, a shopper who picks Navy lands on the navy front shot and the next thumbnails are the other navy views, which is the browsing behaviour you want. And in the admin, an image out of sequence is visually obvious, which is the cheapest QA you will ever get.
| Position | Filename | Linked variants | Alt text |
|---|---|---|---|
| 1 | beanie-rib-navy-front.jpg | Navy / S, M, L | Ribbed knit beanie in navy, front view |
| 2 | beanie-rib-navy-side.jpg | none | Ribbed knit beanie in navy, side view showing cuff |
| 3 | beanie-rib-black-front.jpg | Black / S, M, L | Ribbed knit beanie in black, front view |
| 4 | beanie-rib-black-side.jpg | none | Ribbed knit beanie in black, side view showing cuff |
| 5 | beanie-rib-lifestyle.jpg | none | Model wearing ribbed knit beanie outdoors |
Notice that only the front view of each colour is linked. The side views are deliberately unlinked so they behave as gallery images on standard themes and as colour-filtered images on themes with filtering enabled. If your theme filters by variant, link the side views to the same colour's variants too, so they survive the filter.
Assigning in bulk: admin, CSV and API compared
Doing this one product at a time in the admin is fine for a ten-product store and unworkable for a catalogue. Three routes scale differently.
| Method | Good for | Where it breaks |
|---|---|---|
| Product admin, variant edit | Fixing one product, verifying the result | Anything over ~20 products |
| Bulk editor | Sharing one image across sizes on a few products | Cannot upload; images must already be in the gallery |
| CSV import (Variant Image column) | Catalogue-wide relinks, new colourways | Matches by exact image URL; a re-upload changes the URL and silently unlinks |
| Admin API / app push | Continuous workflows, image tools writing back | Needs rate-limit handling; each app handles variants differently |
The CSV route deserves a specific warning. The Variant Image column must contain the exact CDN URL of an image already on the product, or a URL Shopify can fetch. If you replace an image, its URL changes, and a CSV that references the old URL will import cleanly but leave the variant unlinked. Always re-export after any image replacement before building a relink sheet.
The API route is where image tools plug in. When Retouchable pushes a finished image to a Shopify product, the push sets the filename, alt text and gallery position in the same call, so the image lands named for its colour and, if you choose, as the featured image. The variant pointer itself is then a one-click step in the product admin or a row in your relink CSV, which is much easier when the file is already called beanie-rib-navy-front.jpg and sitting in the right place than when it arrives as export-1788568779.png at the end of the gallery. The same push workflow is described in the Shopify product image push workflow.
Upload and name all images for a product first, arrange gallery order second, assign variant pointers third, and only then enable per-variant media filtering in the theme. Doing the theme setting first means every unfinished product looks broken during the migration.
Variant images beyond the product page
Variant assignment is usually discussed as a product-page concern, but the pointer feeds two other surfaces that quietly depend on it.
Google Shopping and the Shop app. Shopify's Google & YouTube channel syncs each variant as its own offer, and the offer's image is the variant image where one exists, falling back to the product featured image. A merchant with Navy, Black and Forest beanies who has only linked Black will have three Shopping listings all showing the black hat. Shoppers who click the "Forest" listing land on a page that also shows black, because the variant selection via URL resolves to an unlinked variant. Correct assignment is what makes colour-specific ads honest.
Collection filtering by colour. Search & Discovery's colour filter can show variant images in collection grids when a shopper filters by a colour. If Forest has no variant image, the grid shows the product featured image, which is Navy, next to a "Forest" filter chip. This is the collection-level version of the product page problem, and it is more damaging because the shopper has not yet committed to the product.
Both surfaces mean variant assignment is a merchandising task, not just a tidy-up. A catalogue where every visual option has its own linked, correctly named image is one where every channel can show the right colour without human intervention. That is also why AI-generated colourways need the same discipline: if you generate five colours from one base photo (see product photography for multiple colour variants), each generated file needs its own filename, alt text and variant pointer, or the extra colourways are invisible everywhere except the gallery thumbnails.
A variant image audit you can run in an hour
You do not need a script to find where assignment is broken. Export products to CSV with the default columns and work through four checks.
- Empty Variant Image cells. Filter the column for blanks. Every blank row is a variant that will not switch the image on selection and will fall back to the featured image in Shopping. Prioritise products with more than one colour option.
- Distinct image count vs. distinct colour count. For each product, count unique Variant Image URLs and unique values of the colour option. Fewer URLs than colours means half-assignment. More URLs than colours means sizes were assigned as colours.
- Filename says one thing, option says another. Where filenames encode the colour, compare the colour token in the Variant Image URL to the Option value on that row. A mismatch is a wrong pointer.
- Position 1 is a linked image. The featured image should normally be the image linked to the default (first) variant, so the collection grid and the initial product page state agree. Where it is not, decide which is wrong.
Fix the wrong pointers first because they actively mislead, then the empties, then the duplicates. Re-export after each pass, because the CSV is the only place that shows the pointer for every variant on one screen. Once the audit comes back clean, add "link the variant image" to the checklist for every new colourway, and the problem stays fixed.