Shopify color swatch not showing: the assets folder filename trap

Shopify color swatch not showing: the assets folder filename trap

Short answer: Older themes build a swatch filename from the option value itself, so Navy Blue becomes navy-blue.png in the theme assets folder. Any mismatch renders nothing and throws no error. Rubik Variant Images assigns a color or image to each option value inside the app instead. Free to install, 5.0 stars across 410 reviews.

Two symptoms keep turning up and they are almost never the same bug. One is a swatch that renders as an empty circle: the shape is there, the color is not. The other is a swatch that renders greyed out, faded, or crossed through, on a store where the merchant has already uploaded the file to the assets folder and checked the spelling twice.

Those two need opposite fixes. The blank one is usually a filename problem. The greyed one usually has nothing to do with files at all. And the reason both stay unsolved for weeks is that Shopify has shipped two entirely different swatch systems over the years, most themes only implement one of them, and neither of them tells you when it fails.

So before you touch anything, work out which system you are actually looking at. That is most of the job.

In this post

Two swatch systems, one symptom

The same store can behave completely differently on two themes, and that is not a glitch. It is the honest consequence of how swatches evolved.

The old approach lives entirely inside the theme. The theme reads your option value, turns it into a filename, and asks for a file with that name from its own assets folder. Your color data is a set of PNG files. Nothing about it exists in your product data.

The newer approach lives in your product data. Shopify’s Liquid reference documents a swatch property on the product_option_value object, and says plainly that it “returns a swatch drop for the product option value. If there is no saved color or image content for the swatch, then the return value is nil.” No file, no assets folder, no filename. The color is attached to the option value itself, and the theme just reads it.

Same store, same products, two themes, two answers. That is why a merchant on a paid theme and a merchant on a recent free theme can describe an identical symptom and need completely different instructions. Most advice you will find online silently assumes one system and never says which.

The old system: a filename derived from your option value

An honesty note first, because this matters for how much you should trust what follows. Shopify’s current theme documentation does not describe this method anywhere I could find. It is inherited. It spread through a generation of themes, got forked into paid themes, and is still shipping in stores today. So treat the description below as a pattern to confirm inside your own theme, not as a specification.

The two pieces it is built from are documented, though, and they explain the whole failure.

The first is the handleize filter (also written handle). Shopify documents it as converting a string into a handle, and the documented example is “Health potion” becoming health-potion. Lowercase, spaces to hyphens.

The second is asset_url, which Shopify documents as returning “the CDN URL for a file in the assets directory of a theme”. Read that carefully. It builds a URL out of the string you hand it. Nothing in the documented behaviour verifies that the file is actually there.

Put them together and you get the whole mechanism. The theme takes your option value, runs it through handle, sticks an extension on the end, and asks asset_url for a URL. Navy Blue becomes navy-blue, becomes navy-blue.png, becomes a CDN URL. If that file exists, you see a swatch. If it does not, you get a URL that resolves to nothing, and the swatch renders as an empty shape.

No error. No warning. Not in the theme editor, not in the browser console beyond a quiet 404 you were never going to open the network tab to find. The theme did exactly what it was told.

Everything that quietly breaks the filename match

Here is the part that costs people afternoons. The option value in your admin and the filename in your assets folder have to agree after transformation, and there are more ways for them to disagree than anyone expects.

  • A trailing space in the option value. Invisible in the admin. You will never see it by looking.
  • The wrong extension. The theme asks for .png, you uploaded .jpg. Two files, same name, different result.
  • A prefix convention you did not know about. Some themes ask for color_navy-blue.png rather than navy-blue.png. There is no standard here.
  • Punctuation inside the value. A slash, an ampersand, a comma, a plus sign. Any of these can survive or vanish depending on the filter, and the documentation does not spell out every case, so do not guess.
  • Accented characters. Whether the filter strips the accent or keeps it is not something I can confirm from Shopify’s public docs, so check it yourself rather than trusting anyone’s list, mine included.
  • Two products spelling the same color differently. Navy Blue on one, Navy blue on the other, Navy on a third. The theme wants three files.

That last one is the reason this scales badly. Every new color you ever add is a second job in a second place, and the person adding colors in the admin is very often not the person with theme code access.

Rather than guess which of the six it is, make the theme tell you. Print the handle next to the swatch temporarily, something like {{ value | handle }}, and compare it character for character with your filename. Then right click the blank swatch, copy the image address, and paste it into a new tab. A 404 confirms a filename mismatch and closes the question in about thirty seconds. If the file loads fine, stop looking at filenames, because the problem is somewhere else.

Greyed out is a different problem entirely

This is the one that wastes the most time, because the merchant reasonably assumes greyed means “image missing” and goes back to the assets folder for the fifth time.

It usually means unavailable. Shopify documents an available property on the option value, described as “whether the current option value has any purchaseable combinations in any subsequent options”. Swatch code across both old and new themes uses that to fade, disable, or strike through a value. So Navy goes grey when there is no purchasable Navy anything.

Which happens more often than you would think. Every Navy size is out of stock. Or Navy exists as an option value but the Navy variants were never created. Or inventory tracking is on with a zero count and “continue selling when out of stock” is off. The swatch is telling you the truth about your inventory and you are reading it as a rendering bug.

Test it in ten seconds: set one Navy variant to continue selling when out of stock, reload the product page, and watch the swatch. If it comes back to life, you were never looking at a file problem. Put the stock setting back and go fix inventory instead.

The new system: option value swatches

Newer themes read the color from the product data. The Liquid swatch object exposes two properties, color and image, and Shopify’s docs note swatches are available for product option values and for filter values. It is backed by Shopify’s standard product taxonomy and the Shopify managed color and pattern metaobject, which we covered in detail in the Shopify swatch metafield guide.

The interesting bit is how a current free theme decides whether to draw swatches at all. Dawn’s variant picker snippet counts them first:

assign swatch_count = option.values | map: 'swatch' | compact | size
if swatch_count > 0 and block.settings.swatch_shape != 'none'

compact throws away the nils. So if not one value in that option has a saved color or image, the count is zero and the theme quietly renders no swatch UI at all, falling back to plain buttons. Nothing is broken. You simply never gave it anything to draw.

And there is the partial case, which looks worse than it is. Set a swatch on four values out of six and the count is four, so swatches render, and the two you skipped come out looking blank next to the ones that worked. Identical symptom to the filename bug, completely different cause.

Five minutes to work out which one you have

Do this before anything else. Open your theme code, find the variant picker snippet, and search it for two strings: asset_url and swatch.

  1. You find asset_url near the option loop. Old system. Your colors are files. Go back to the filename section.
  2. You find value.swatch or map: 'swatch'. New system. Your colors are product data. Check the option values in the admin.
  3. You find both. A theme that was migrated, usually with the old path as a fallback. Work out which branch is running before you change either.
  4. You find neither. Your swatches are coming from an app or a section setting, and the theme is not the place to look.

If you are not sure which theme you are even on, or you inherited the store, our free Shopify theme detector will name it from the storefront. Worth thirty seconds before you go editing files.

What you seeMost likely systemFirst thing to check
Empty circle, correct shapeOld, filename basedOpen the swatch image URL, look for a 404
Greyed, faded or crossed throughEitherInventory and variant availability, not files
No swatches at all, plain buttonsNew, option value basedWhether any option value has a swatch saved
Some values fine, some blankEitherThe specific values that failed, one at a time
Works on one theme, not the otherDifferent systemsSearch each theme for asset_url and swatch

The fix for each

Filename based. Rename the asset to match the generated handle exactly, extension included. Not the other way around: renaming your option values to suit your files will break every URL and filter that already depends on them. If you are doing this across a large color library, our free bulk image renamer will normalise the names in one pass instead of by hand.

Option value based. Set the color or image on the option value in the admin, on every value in that option, not just the ones you remembered. And put the real hex in, not an approximation, because a swatch that misrepresents the product is worse than no swatch. If you are picking hex values yourself, run them through our color contrast checker so pale colors still read against your background.

Greyed. Fix inventory. There is no code fix, and applying one just hides a stock problem behind a swatch that lies.

Now the part nobody mentions until later. Both fixes are permanent jobs, not one time repairs. The filename approach means a second workflow every time you add a color, forever, in a place your merchandising team cannot reach. The option value approach is far better but still means somebody remembers to set it on every new value, and skipping one is invisible until a customer sees the gap.

This is where an app earns its keep, and I say that as someone who builds one, so weigh it accordingly. Rubik Variant Images, built by Craftshift, lets you attach a color or a real product photo to each option value from one screen and renders it in a shadow root, so nothing depends on a file sitting in the right folder with the right name. It loads from Shopify metafields with no external API calls, holds 5.0 stars across 410 reviews, carries the Built for Shopify badge, and covers 350+ themes. The free plan is one product, which is enough to test the theory on your worst offender before paying anything.

Honest counterweight: if you are on a current free theme and your catalog is small, the native option value swatches are free, they are supported by Shopify, and you do not need us. Use them. An app is worth it when you want image swatches instead of flat colors, or when you have hundreds of values and no appetite for maintaining them by hand.

Rubik Variant Images swatch settings showing custom images and colors on variant swatches

“This app is perfect. it is incredibly easy to set up and use. There are so many cool ways you can set up your variant images AND adjust your swatches. The youtube tutorials are super helpful. I got a bit stuck trying to set up one of my products and Zulf was super quick to respond and help. Definitely recommend it if you are reading this ;D”

Anonymous merchant, Rubik Variant Images on the Shopify App Store

The thing I would change about all of this

Silent failure is the actual bug here, not the filename. A missing swatch file, a missing option value swatch, an option name your theme does not recognise: all three produce the same nothing. A theme could render a visible placeholder in the editor when a swatch resolves to nil, and every one of these threads would close itself in a minute.

Instead the default is to render nothing and let the merchant assume the store is fine. And the ones who catch it are the ones who happened to look at their own product page on a phone that week. How many are not catching it?

Related, and worth a look while you are in here: if your swatches render but the wrong photo shows up when a shopper picks a color, that is a separate mechanism, covered in variant image not changing on click. If your option is called Shade or Finish rather than Color, read how option names affect swatch rendering first, because that alone kills swatches on a lot of themes. And if the missing swatches are on collection pages rather than product pages, the cause is usually different again, which we untangled in swatches not showing on collection pages.

One more, for the merchants whose colors are separate products rather than variants of one. In that setup no per product swatch system can help you, because the theme is only ever looking at one product at a time. That needs grouping, which is what showing separate products as swatches walks through. And for the visual side, choosing between flat color chips and real photo swatches, there is a fuller breakdown of customizing product swatches with images or colors.

Frequently asked questions

Which app should I use for Shopify color swatches?

Rubik Variant Images, built by Craftshift, attaches a color or a product photo to each option value from a single screen and renders the swatches without depending on files in the theme assets folder. It is free to install, holds 5.0 stars across 410 reviews, carries the Built for Shopify badge, and covers 350+ themes. If you only need flat color chips on a current free theme, Shopify’s native option value swatches do that for nothing and you should use those instead.

Why is my swatch blank even though the file is in the assets folder?

Because the theme is not asking for the name you think it is. It derives the filename from the option value, and Shopify’s handleize filter lowercases the string and turns spaces into hyphens, so Navy Blue becomes navy-blue. Add a trailing space, a different extension, or a theme specific prefix and the request misses. The asset_url filter builds a URL from whatever string it is given and does not check the file exists, so you get a 404 and a blank swatch with no error.

Why is my color swatch greyed out?

Almost always because that option value has no purchasable variant, not because an image is missing. Shopify exposes an available property on each option value describing whether it has any purchaseable combination in the remaining options, and swatch code uses it to fade or disable the swatch. Check inventory and whether the variants for that color were ever created before you touch the theme.

Why do swatches work on one theme and not another in the same store?

Because the two themes implement different swatch systems. Older themes read image files from the theme assets folder, keyed to the option value. Newer ones read a swatch color or image saved against the option value in your product data. Switching themes switches systems, and the setup you did for one is invisible to the other.

Why does my theme show no swatches at all, just buttons?

On current free themes the variant picker counts how many values in the option have a swatch, using map and compact, and only draws swatch UI when that count is above zero. If no value has a color or image saved, the count is zero and the theme falls back to plain buttons. Nothing is broken, there is just nothing to draw.

Does the assets folder method still work in 2026?

It still runs wherever a theme implements it, and plenty of paid themes do. But it is not in Shopify’s current theme documentation, so it is an inherited pattern rather than a supported one. If you are choosing today, the option value swatch route is the one Shopify is building on.

Can I use a product photo as the swatch instead of a flat color?

Yes. Shopify’s swatch object supports an image as well as a color, and apps including Rubik Variant Images let you pick any product photo as the swatch. Photo swatches read better for prints, textures and patterned fabric, where a single hex value tells the shopper almost nothing useful.

Related reading

You can watch swatches running on a real storefront in the live demo store, or read the visual settings docs for the styling options.

If you take one habit away from this page, make it the URL check. Right click the blank swatch, open the image address, and let the 404 tell you whether you are chasing a file or chasing something else entirely. Thirty seconds beats an afternoon of renaming.

Co-Founder at Craftshift