Ayan Ali.
9 min readUpdated

How to Make Shopify Color Swatches Link to Separate Product Pages

A swatch that opens a different product page needs one product per color, a metaobject that groups them, and a short Liquid snippet. Here is the full build, and when not to bother.

ShopifyLiquidProduct Pages
Five matte spheres in a row, each linked by a thin lime line to its own separate product panel below, with the Shopify logo on a plinth in the foreground.

Short answer: make one product per color, put those products in a metaobject that holds a list of product references, and render that list as plain links in your product template. Each swatch is an <a href> to a sibling product, so it needs no JavaScript and no app. The full build takes about 20 lines of Liquid and a one-time data setup. Steps, code and the failure cases are below. Checked against Shopify's developer docs, October 2026.

Use separate products when each color needs its own URL, its own photos, its own reviews or its own description. A color that is a variant shares one URL with every other color, so a search for "olive linen shirt" can only land on a page that is mostly about the whole shirt. A color that is its own product can be the page that ranks for that query.

Stay with native variants when your colors share everything except the swatch. A store with four colors, one set of photos per color and no color-specific search demand gains little from the extra products. Shopify's Liquid product_option_value object already returns a swatch for native options, so that case needs no custom work.

Isn't the 100-variant limit the reason to do this?

It used to be, and it no longer is. Shopify announced on October 15, 2025 that all merchants can create products with up to 2,048 variants, up from the historical limit of 100. Older guides, and many app-vendor pages, still describe the cap as a blocker.

The limit that still matters is options. A product has at most three options, so color, size and material fill it. The reasons left to split colors into separate products are URLs, content and merchandising, which are the three reasons this article is built around.

There are four routes, and the right one depends on your plan and how many colors you manage. The table compares them on cost, plan requirement and control.

| Option | Plan needed | Cost | Limits | Control | |---|---|---|---|---| | Native variants with swatches | Any | Free | One URL for all colors; 3 options | Low | | Combined Listings (Shopify's app) | Plus only | Free app | 60 child products per parent; online store only | Medium | | Swatch app | Any | Monthly fee, varies by app | Adds app code to every product page | Medium | | Metaobject + Liquid snippet | Any | One-time build | You maintain it | Full |

Combined Listings is the cleanest option if you are on Plus, since it is built into the platform. Shopify's documentation limits it to Plus stores, the online store channel, 60 child products and three options on the parent. For a deeper comparison of the app route against custom code, see swatch app vs custom Liquid.

How do I set up the data for linked swatches?

The data model is one metaobject that groups the products, plus three metafields on each product. Setting it up once means adding a new color later is a two-minute job.

1. Create the metaobject definition. In Settings → Custom data → Metaobjects, add a definition called Color group with one field: products, type Product, set to list of products.

2. Add three product metafields. In Settings → Custom data → Products, define:

  • custom.color_group: type Metaobject reference, pointing at Color group
  • custom.swatch_color: type Color
  • custom.color_name: type Single line text

3. Create one product per color. Each product keeps its own images, handle, price and size variants. Size stays a normal variant, so the size picker and inventory work exactly as before.

4. Create one `Color group` entry per garment or style. Add every color product to its products list, including each product itself. A swatch row shows the current color as selected, so the list has to contain it.

5. Point each product at its group. Set custom.color_group on every color product to that entry, then fill in swatch_color and color_name.

What Liquid code renders the swatches?

The snippet loops over the group's product list and prints a link per product. Save it as snippets/color-swatches.liquid and render it near the variant picker with {% render 'color-swatches' %}.

{%- assign group = product.metafields.custom.color_group.value -%}
{%- assign siblings = group.products.value -%}

{%- if siblings.size > 1 -%}
  <nav class="swatches" aria-label="Color">
    <p class="swatches__label">
      Color: {{ product.metafields.custom.color_name.value }}
    </p>
    <ul class="swatches__list">
      {%- for sibling in siblings -%}
        {%- assign is_current = false -%}
        {%- if sibling.id == product.id -%}{%- assign is_current = true -%}{%- endif -%}
        <li>
          <a
            href="{{ sibling.url }}"
            class="swatch{% if is_current %} is-current{% endif %}{% unless sibling.available %} is-sold-out{% endunless %}"
            style="--swatch: {{ sibling.metafields.custom.swatch_color.value }}"
            {% if is_current %}aria-current="page"{% endif %}
          >
            <span class="visually-hidden">
              {{ sibling.metafields.custom.color_name.value }}
              {%- unless sibling.available %} (sold out){% endunless -%}
            </span>
          </a>
        </li>
      {%- endfor -%}
    </ul>
  </nav>
{%- endif -%}

The list metafield's .value returns an array of product objects, and the Liquid metafield documentation covers reading list references this way. The swatch_color metafield of type Color returns a hex string, which the inline --swatch custom property passes to CSS.

.swatches__list { display: flex; flex-wrap: wrap; gap: .5rem; list-style: none; margin: 0; padding: 0; }
.swatch { display: block; width: 2.25rem; height: 2.25rem; border-radius: 50%;
  background: var(--swatch); box-shadow: inset 0 0 0 1px rgb(0 0 0 / .2); }
.swatch.is-current,
.swatch:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.swatch.is-sold-out { opacity: .45; }

The 36px swatch size clears the 24px minimum target size in WCAG 2.2, and the visually hidden text gives screen readers the color name, because a color circle alone has no accessible name. Define .visually-hidden once in your theme CSS if it does not already exist.

Give every color product a unique title, meta description and first paragraph. Near-identical descriptions across a color group are the real SEO risk of this setup, not the extra URLs. A title like "Linen Shirt, Olive" and another like "Linen Shirt, Sand" is enough to separate them.

Keep each product's canonical URL pointing at itself. Do not canonicalize colors to a single "main" product, because that removes the ranking advantage that justified the split. The color swatches are ordinary crawlable links, which also helps Google find every sibling from any one of them.

For structured data, Google's product variants guidance describes ProductGroup markup with a shared productGroupID. Check the current documentation before adding it, since it is optional and your theme may already output product schema.

What goes wrong with linked swatches, and how do I fix it?

Five failure cases cover most of the support issues. Test each before launch.

A product is missing from the group. If a color product is not in the Color group list, the other colors never show it, and its own page shows no row. Add it to the list and reload.

A sibling is unpublished or draft. Unpublish one color on the Online Store channel and confirm the swatch row still renders cleanly without a broken link. Do this test on a staging theme.

A color is sold out. Keep the swatch, link it to the sold-out page and mark it. Hiding the swatch removes the shopper's path to a back-in-stock notification.

Collection pages show every color as a card. Each color product is a separate product, so a collection lists them separately. Decide whether that suits the store. If it does not, add a boolean metafield such as custom.show_in_collections and filter on it.

Reviews split across colors. Each product collects its own reviews. A group-level review count needs custom code or a reviews app that supports product grouping.

Rendering cost is the other watch-out. Shopify's own performance guidance warns that rendering full data for 20 to 60 child products in a combined listing can add seconds to server response time. A swatch row that reads two metafields per sibling is much lighter, but keep groups to the colors you actually sell and check server response time after launch.

What did this look like on real client stores?

The same pattern, fully custom coded, ran on two stores I built it for. For BAOBAB, the client wanted a variant picker where clicking a color swatch opens that color's own product page. The build, testing and adjustments took around two weeks, and it had to work on two stores, a local one for Colombia and an international one. Some product upload errors came up during rollout, and they were fixed within hours.

For Curet, the brief was the same idea in a custom variant selector: clicking a color opens the product that was added as that variant. See the BAOBAB case study and the Curet case study for screenshots.

When should I hire someone for this?

Hire help if your theme's product template is heavily customized, if you run more than one store, or if you need group-level reviews and collection rules on top of the swatches. The base build above is a few hours of work for a developer comfortable with Liquid, and the rest is data entry per product group.

If you want this built on your store, see my Shopify development services or get in touch with your store URL and a sample product group.

  • Shopify variants vs separate products for SEO
  • Swatch app vs custom Liquid: speed, cost and control
  • What is Shopify Combined Listings, and do you need Plus?
  • Splitting products past 100 variants without breaking the picker

Frequently asked questions

Can a Shopify color swatch link to a different product page?

Yes. Create one product per color, group them in a metaobject that holds a list of product references, then loop over that list in Liquid and output each product's URL as a plain link. No app is needed.

Do I need Shopify Plus for swatches that open separate products?

No. Shopify's native Combined Listings feature is Plus-only, but a metaobject plus a Liquid snippet works on every plan.

Is the 100-variant limit the reason to use separate products?

Not anymore. Shopify raised the limit to 2,048 variants per product for all merchants on October 15, 2025. The remaining reasons are a separate URL, separate images and reviews per color, and ranking for color-specific searches.

Will separate product pages per color hurt SEO?

It can help. Each color gets its own indexable URL, title and images, so it can rank for searches like 'black linen shirt'. The risk is near-duplicate descriptions, so write a color-specific title and meta description for each product.

What happens when one color sells out?

The swatch should stay visible and link to the sold-out page, marked as sold out. Hiding it makes the color look discontinued and removes the back-in-stock path.

Want this built on your store?

This is the kind of thing I build — custom-coded into your existing theme, no app and no monthly fee. Tell me what you need and I'll tell you what it takes, honestly, before you commit to anything.

Read next

How to Add an AI Chatbot to Shopify Grounded in Your Product Catalogue
A frosted speech-bubble form above a grid of product boxes, connected by thin lime lines, with the Shopify logo set into the floor and the OpenAI logo on the bubble.
Shopify

How to Add an AI Chatbot to Shopify Grounded in Your Product Catalogue

A Shopify chatbot that does not invent products needs four parts: a synced catalogue index, retrieval, a grounded prompt, and a Liquid section that talks to your backend. Here is each part.

Read
How to Build an AI Product Finder Section for Shopify
A wide field of dark cubes receding into shadow with a narrow lime light picking out exactly three, and the Shopify logo on a plate in the foreground.
Shopify

How to Build an AI Product Finder Section for Shopify

A product finder takes 'a waterproof jacket for light hiking under $150' and returns matching products. It needs vector search and filters, and it does not need a chat model.

Read
How to Speed Up a Shopify Store Without Apps
A stack of heavy compressed slabs on the left resolving into a single weightless lime-edged plate on the right, with the Shopify logo embossed on the leading slab.
Shopify

How to Speed Up a Shopify Store Without Apps

Most Shopify speed problems come from images, scripts and installed apps, and none of them need another app to fix. Here is the order to work in, with the Liquid to do it.

Read

Got a store or a build in mind?

Tell me what you're trying to ship — a Shopify section, a full storefront, a chatbot, or a web app. I'll tell you what it takes, honestly, before you commit.

ayanrjpoot@gmail.com