Shopify Swatches & Custom Sort Order: Unlocking Advanced Product Options with Metaobjects

Hey fellow store owners! As a Shopify migration expert, I spend a lot of time digging through the community forums, and let me tell you, some of the most insightful discussions happen when someone hits a wall with a seemingly simple task that turns out to be surprisingly complex. Today, I want to share a fantastic breakdown of a recent thread that perfectly illustrates this: getting custom color swatches to display correctly and, even trickier, sorting them consistently across all products.

Our story starts with Leanne_Jane, a made-to-order brand owner with 20 different color options for her products. She faced a common headache: managing product variant order. Initially, colors were added randomly, and she desperately needed a consistent "rainbow order" across her entire catalog. Shopify support pointed her towards creating a custom color metaobject with an integer sort number, which made perfect sense for centralizing the sort order. She set it all up – images, hex codes, sort numbers – but hit a snag: her Atelier theme just wouldn't show the custom swatches, only plain text labels. Four hours with Shopify AI assistant later, and still no fix!

The Core Problem: Why Custom Swatches Weren't Showing

This is where the community really shone. Several experts, including @devcoders, @cartergray, and @Mustafa_Ali, quickly identified the root cause: theme limitation. Most modern Shopify themes, especially those based on Dawn (like Atelier often behaves), have their swatch rendering logic hardcoded to look for Shopify’s native "Color" category metafield, not a custom metaobject you’ve created. As @Moeed brilliantly pointed out, Atelier specifically reads product_option_value.swatch. A custom metaobject simply doesn't populate this native property, so the theme falls back to text. No amount of AI prompting will fix that if the underlying theme code isn't looking in the right place!

Part 1: Getting Your Swatches to Appear (The No-Code Way!)

Before diving into code, let's tackle the swatch display itself. @gotinker and @PixelForge007 both highlighted that you can get swatches working with zero code by leveraging Shopify's native functionality. This is often the best first step because it ensures your swatches will continue to work through theme updates without breaking.

Here’s how to do it:

  1. Assign a Product Category: Open your product and set a Product category that includes the "Color" property. "Apparel" is a common choice.
  2. Connect Your Color Option: In the product editor, go to your Variants section. Next to your "Color" option, you'll see a dynamic source icon (a little stack of cylinders). Click this and connect your color option to the native "Color" category metafield.
  3. Map Colors & Add Swatches: Map your existing color names to the corresponding color entries. For each entry, you can then assign a hex code or upload a swatch image.
  4. Check Theme Editor Settings: Head to your Theme Editor, navigate to a product page, click on the Variant picker block, and ensure that "Swatch shape" isn't set to "None."

This approach makes your theme automatically recognize and render the swatches because the data is now where the theme expects it.

Part 2: Mastering Custom Sort Order with Metaobjects (Code Required)

While the native Color category metafield handles swatches beautifully, it doesn't offer a built-in integer sort field. This is precisely why Leanne_Jane (and many others!) needed a custom solution. As she explained to @Maximus3, dragging and re-ordering 20 colors on every single product is a nightmare, especially when introducing new colors. A central sort field is a game-changer for consistency.

Setting Up Your Metaobject for Sorting

You've likely already done this part, but it's worth reiterating the structure for clarity:

  1. Create a Custom Metaobject Definition: For example, name it "Color Sort Order" with a handle like colour_sort.
  2. Add Fields: Include a "Text" field for the color name (this will be used to match your variant option names) and an "Integer" field for your sort order.
  3. Enable Storefront Access: This is a critical step that @PixelForge007 highlighted. In your metaobject definition settings, ensure "Storefront access" is enabled. Without it, your theme code won't be able to retrieve the data, even if everything else looks perfect in the admin.
  4. Populate Entries: Create an entry for each of your colors. The entry's handle should be the handleized version of your color name (e.g., "Sky Blue" becomes "sky-blue"). Assign your desired integer sort order to each.

Here are Leanne_Jane's screenshots for reference on how her metaobject was set up:

The Code Fix: Sorting Your Swatches

Now for the part that genuinely requires theme code. You'll need to edit the Liquid snippet responsible for rendering your variant options. For Atelier, this is often found in snippets/variant-swatches.liquid or a similar file. The goal is to replace the standard loop that iterates through variant option values with one that first sorts them based on your custom metaobject's integer field. @PixelForge007 provided an excellent code snippet for this:

{%- liquid
  assign keyed = ''
  for value in option.values
    assign h = value.name | handleize
    assign entry = metaobjects.colour_sort[h]
    assign n = 9999
    if entry.sort_order != blank
      assign n = entry.sort_order.value
    endif
    assign pad = n | prepend: '0000' | slice: -4, 4
    assign keyed = keyed | append: pad | append: ':' | append: forloop.index0 | append: ','
  endfor
  assign keyed = keyed | split: ',' | sort
-%}

{%- for row in keyed -%}
  {%- assign i = row | split: ':' | last | times: 1 -%}
  {%- assign value = option.values[i] -%}

    your existing swatch markup goes here, unchanged, still using `value`

{%- endfor -%}

A few crucial notes on this code:

  • Metaobject Handle: Remember to swap colour_sort with the actual handle of your custom metaobject type.
  • Zero-Padding: The prepend: '0000' | slice: -4, 4 part is vital. Liquid sorts strings alphabetically, so without this, "10" would sort before "2." Zero-padding ensures correct numerical sorting.
  • Default Sort: If a color doesn't have a matching metaobject entry, it will default to a high sort number (9999 in this example), pushing it to the end of the list rather than making it disappear. This is a great failsafe.
  • .value for Integers: @PixelForge007 correctly pointed out that for integer fields in metaobjects, you need to use .value (e.g., entry.sort_order.value) to get the number itself, not the field object.
  • Deprecated shop.metaobjects: If you've been working with AI or older tutorials, be aware that shop.metaobjects is deprecated and might return nothing. The global metaobjects object is the correct one to use.
  • Placement: This code replaces the loop that iterates over option.values. Your existing swatch rendering HTML (the part that actually creates the swatch circles or images) goes inside the new for row in keyed loop, still referencing the value variable.

Leanne_Jane's success story, where @devcoders helped her implement this with "an extra 300 lines of code," really underscores that while the principles are clear, getting the exact implementation right in your specific theme can take time and expertise. But the result – swatches and sort order in her custom color list, with the flexibility to easily adjust her color list when needed – is absolutely worth it.

This whole discussion is a fantastic reminder that sometimes, the best solution is a hybrid: using native Shopify features where they excel (like basic swatch rendering) and extending them with custom metaobjects and a bit of Liquid code where you need more control (like a centralized sort order). It saves you from constantly battling the admin interface and ensures a consistent, professional look for your products. If you're tackling something similar, remember to break it down, leverage native features first, and don't be afraid to seek expert help for those trickier code customizations. It truly makes a difference!

Share:

Use cases

Explore use cases

Agencies, store owners, enterprise — find the migration path that fits.

Explore use cases