Hello,
How to link products as varinats in Focal theme?
Is it possible to acceve this without coding or can anyone help with the code?
A user seeks to link separate products as variants on the Focal theme product page. Shopify lacks a native feature for this, so workarounds are needed.
Proposed Solutions:
Code-based approach: Add custom Liquid code to main-product.liquid that displays related products using metafields. One responder provided a code snippet utilizing product.metafields.custom.related_products to render linked product thumbnails and titles.
App-based approach: Install apps like “SA Variants: Combined Listings” or “LinkedOption Combined Listings” for a no-code solution, though these require monthly fees.
Current Status:
The user successfully added product options to the page but encounters a new issue: the links apply globally to all products rather than being product-specific. They need guidance on making the links unique per product, likely requiring proper metafield configuration so each product references its own set of related items.
Hello,
How to link products as varinats in Focal theme?
Is it possible to acceve this without coding or can anyone help with the code?
Unfortunately, Shopify doesn’t have a built-in way to “link” separate products together so they behave like variants. You have a couple of options though:
In your theme code, go to:
Online Store → Themes → Edit code → Sections → main-product.liquid
Find where product options/variants are displayed. Then, add something like this:
{% if product.metafields.custom.related_products != blank %}
<div class="linked-products">
<h4>Other Options</h4>
<ul class="linked-products__list">
{% for related in product.metafields.custom.related_products.value %}
<li class="linked-products__item">
<a href="{{ related.url }}" title="{{ related.title }}">
{% if related.featured_image %}
<img src="{{ related.featured_image | img_url: '100x100' }}"
alt="{{ related.title }}" />
{% endif %}
<span>{{ related.title }}</span>
</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
On the product page, customers will see small swatches (thumbnails + titles) that link to the related products, making them behave like “variants.”
Let me know if this helps or not?
problem is that i dont know where to paste it in. here below you can find my code main-product.liquid
<style>
#shopify-section-{{ section.id }} {
{%- assign buy_buttons_block = section.blocks | where: 'type', 'buy_buttons' | first -%}
{%- if buy_buttons_block.settings.show_payment_button -%}
{%- if buy_buttons_block.settings.atc_button_background == 'rgba(0,0,0,0)' -%}
{%- assign secondary_button_background = settings.secondary_button_background -%}
{%- else -%}
{%- assign secondary_button_background = buy_buttons_block.settings.atc_button_background -%}
{%- endif -%}
{%- if buy_buttons_block.settings.atc_button_text_color == 'rgba(0,0,0,0)' -%}
{%- assign secondary_button_text_color = settings.secondary_button_text_color -%}
{%- else -%}
{%- assign secondary_button_text_color = buy_buttons_block.settings.atc_button_text_color -%}
{%- endif -%}
{%- if buy_buttons_block.settings.buy_now_button_background == 'rgba(0,0,0,0)' -%}
{%- assign primary_button_background = settings.primary_button_background -%}
{%- else -%}
{%- assign primary_button_background = buy_buttons_block.settings.buy_now_button_background -%}
{%- endif -%}
{%- if buy_buttons_block.settings.buy_now_button_text_color == 'rgba(0,0,0,0)' -%}
{%- assign primary_button_text_color = settings.primary_button_text_color -%}
{%- else -%}
{%- assign primary_button_text_color = buy_buttons_block.settings.buy_now_button_text_color -%}
{%- endif -%}
{%- else -%}
{%- if buy_buttons_block.settings.atc_button_background == 'rgba(0,0,0,0)' -%}
{%- assign primary_button_background = settings.primary_button_background -%}
{%- else -%}
{%- assign primary_button_background = buy_buttons_block.settings.atc_button_background -%}
{%- endif -%}
{%- if buy_buttons_block.settings.atc_button_text_color == 'rgba(0,0,0,0)' -%}
{%- assign primary_button_text_color = settings.primary_button_text_color -%}
{%- else -%}
{%- assign primary_button_text_color = buy_buttons_block.settings.atc_button_text_color -%}
{%- endif -%}
{%- endif -%}
--primary-button-background: {{ primary_button_background.red }}, {{ primary_button_background.green }}, {{ primary_button_background.blue }};
--primary-button-text-color: {{ primary_button_text_color.red }}, {{ primary_button_text_color.green }}, {{ primary_button_text_color.blue }};
--secondary-button-background: {{ secondary_button_background.red }}, {{ secondary_button_background.green }}, {{ secondary_button_background.blue }};
--secondary-button-text-color: {{ secondary_button_text_color.red }}, {{ secondary_button_text_color.green }}, {{ secondary_button_text_color.blue }};
}
</style>
{%- capture product_form_id -%}product-form-main-{{ product.id }}-{{ section.id }}{%- endcapture -%}
<section>
{%- if section.settings.show_sticky_add_to_cart and product.available -%}
{%- render 'product-sticky-form', product: product, product_form_id: product_form_id -%}
{%- endif -%}
<div class="container">
<nav aria-label="{{ 'general.breadcrumb.title' | t }}" class="breadcrumb text--xsmall text--subdued hidden-phone">
<ol class="breadcrumb__list" role="list">
<li class="breadcrumb__item">
<a class="breadcrumb__link" href="{{ routes.root_url }}">{{ 'general.breadcrumb.home' | t }}</a>
</li>
{%- if collection -%}
<li class="breadcrumb__item">
<a class="breadcrumb__link" href="{{ collection.url }}">{{- collection.title -}}</a>
</li>
{%- endif -%}
<li class="breadcrumb__item">
<span class="breadcrumb__link" aria-current="page">{{ product.title }}</span>
</li>
</ol>
</nav>
<!-- PRODUCT TOP PART -->
<product-rerender id="product-info-{{ product.id }}-{{ section.id }}" observe-form="{{ product_form_id }}" allow-partial-rerender>
<div class="product product--thumbnails-{{ section.settings.desktop_thumbnails_position }}">
{%- render 'product-media', product: product, product_form_id: product_form_id -%}
{%- render 'product-info', product: product, product_form_id: product_form_id, update_url: true -%}
</div>
</product-rerender>
</div>
</section>
{%- comment -%}
The quick shop HTML being very different, we render it here. On mobile and tablet/desktop, the product renders also
quite differently, as it is in a drawer on tablet/desktop, and a popover on mobile.
{%- endcomment -%}
{%- render 'product-quick-buy', product: product -%}
{% schema %}
{
"name": "Product page",
"class": "shopify-section--main-product",
"blocks": [
{
"type": "@app"
},
{
"type": "variant_picker",
"name": "Variant picker",
"limit": 1,
"settings": [
{
"type": "checkbox",
"id": "hide_sold_out_variants",
"label": "Hide sold out variants",
"default": false
},
{
"type": "select",
"id": "selector_mode",
"label": "Selector type",
"options": [
{
"value": "block",
"label": "Block"
},
{
"value": "dropdown",
"label": "Dropdown"
}
],
"default": "block"
},
{
"type": "select",
"id": "color_mode",
"label": "Color selector type",
"info": "Enable [swatches](https://help.shopify.com/en/manual/online-store/themes/theme-structure/theme-settings#options-with-swatches) on product options.",
"options": [
{
"value": "swatch",
"label": "Swatch"
},
{
"value": "none",
"label": "None"
}
],
"default": "swatch"
},
{
"type": "text",
"id": "variant_image_options",
"label": "Show variant image for options"
},
{
"type": "page",
"id": "size_chart_page",
"label": "Size chart page",
"info": "Feature a page for size option"
}
]
},
{
"type": "quantity_selector",
"name": "Quantity selector",
"limit": 1
},
{
"type": "volume_pricing",
"name": "Volume pricing table",
"limit": 1,
"settings": [
{
"type": "paragraph",
"content": "Volume pricing is only available to Shopify Plus merchants. [Learn more](https://help.shopify.com/en/manual/b2b/catalogs/quantity-pricing#volume-pricing)"
}
]
},
{
"type": "buy_buttons",
"name": "Buy buttons",
"limit": 1,
"settings": [
{
"type": "checkbox",
"id": "show_payment_button",
"label": "Show dynamic checkout button",
"info": "Each customer will see their preferred payment method from those available on your store, such as PayPal or Apple Pay. [Learn more](https://help.shopify.com/manual/using-themes/change-the-layout/dynamic-checkout)",
"default": true
},
{
"type": "checkbox",
"id": "show_gift_card_recipient",
"label": "Show recipient information form for gift card products",
"info": "Gift card products can optionally be sent directly to a recipient along with a personal message. [Learn more](https://help.shopify.com/manual/online-store/themes/customizing-themes/add-gift-card-recipient-fields)",
"default": true
},
{
"type": "color",
"id": "atc_button_background",
"label": "Add to cart background",
"default": "rgba(0,0,0,0)"
},
{
"type": "color",
"id": "atc_button_text_color",
"label": "Add to cart color",
"default": "rgba(0,0,0,0)"
},
{
"type": "color",
"id": "buy_now_button_background",
"label": "Buy now background",
"default": "rgba(0,0,0,0)"
},
{
"type": "color",
"id": "buy_now_button_text_color",
"label": "Buy now color",
"default": "rgba(0,0,0,0)"
}
]
},
{
"type": "description",
"name": "Description",
"limit": 1
},
{
"type": "inventory",
"name": "Inventory",
"limit": 1,
"settings": [
{
"type": "range",
"id": "low_inventory_threshold",
"label": "Low inventory threshold",
"info": "Use low stock color when quantity is below the threshold. Choose 0 to always show in stock.",
"min": 0,
"max": 100,
"step": 1,
"default": 0
}
]
},
{
"type": "text",
"name": "Text",
"settings": [
{
"type": "richtext",
"id": "text",
"label": "Text"
}
]
},
{
"type": "image",
"name": "Image",
"settings": [
{
"type": "image_picker",
"id": "image",
"label": "Image"
},
{
"type": "select",
"id": "image_alignment",
"label": "Alignment",
"options": [
{
"value": "left",
"label": "Left"
},
{
"value": "center",
"label": "Center"
},
{
"value": "right",
"label": "Right"
}
],
"default": "left"
},
{
"type": "range",
"id": "image_width",
"min": 50,
"max": 500,
"step": 10,
"unit": "px",
"label": "Width",
"default": 150
}
]
},
{
"type": "button",
"name": "Button",
"settings": [
{
"type": "paragraph",
"content": "Create link to your contact page, external marketplace..."
},
{
"type": "url",
"id": "link",
"label": "Link"
},
{
"type": "text",
"id": "text",
"label": "Text"
},
{
"type": "checkbox",
"id": "stretch",
"label": "Stretch button",
"default": true
},
{
"type": "color",
"id": "background",
"label": "Background",
"default": "rgba(0,0,0,0)"
},
{
"type": "color",
"id": "text_color",
"label": "Text color",
"default": "rgba(0,0,0,0)"
}
]
},
{
"type": "liquid",
"name": "Custom Liquid",
"settings": [
{
"type": "liquid",
"id": "liquid",
"label": "Liquid",
"info": "Add app snippets or other Liquid code to create advanced customizations."
}
]
},
{
"type": "line_item_property",
"name": "Line item property",
"settings": [
{
"type": "paragraph",
"content": "Line item properties are used to collect customization information for an item added to the cart."
},
{
"type": "text",
"id": "label",
"label": "Label",
"default": "Your label"
},
{
"type": "select",
"id": "type",
"label": "Type",
"options": [
{
"value": "text",
"label": "Text"
},
{
"value": "checkbox",
"label": "Checkbox"
}
],
"default": "text"
},
{
"type": "header",
"content": "Text",
"visible_if": "{{ block.settings.type == 'text' }}"
},
{
"type": "checkbox",
"id": "required",
"label": "Required",
"default": false,
"visible_if": "{{ block.settings.type == 'text' }}"
},
{
"type": "checkbox",
"id": "allow_long_text",
"label": "Allow long text",
"default": false,
"visible_if": "{{ block.settings.type == 'text' }}"
},
{
"type": "header",
"content": "Checkbox",
"visible_if": "{{ block.settings.type == 'checkbox' }}"
},
{
"type": "text",
"id": "checked_value",
"label": "Checked value",
"default": "Yes",
"visible_if": "{{ block.settings.type == 'checkbox' }}"
},
{
"type": "text",
"id": "unchecked_value",
"label": "Unchecked value",
"default": "No",
"visible_if": "{{ block.settings.type == 'checkbox' }}"
}
]
}
],
"settings": [
{
"type": "checkbox",
"id": "show_vendor",
"label": "Show vendor",
"default": true
},
{
"type": "checkbox",
"id": "show_sku",
"label": "Show SKU",
"default": false
},
{
"type": "checkbox",
"id": "show_badges",
"label": "Show badges",
"default": false
},
{
"type": "checkbox",
"id": "show_taxes_included",
"label": "Show taxes included",
"default": false
},
{
"type": "checkbox",
"id": "show_product_rating",
"label": "Show product rating",
"info": "To display a rating, add a product rating app. [Learn more](https://help.shopify.com/en/manual/products/product-reviews/installation)",
"default": false
},
{
"type": "checkbox",
"id": "show_sticky_add_to_cart",
"label": "Show sticky add to cart",
"info": "Will be hidden if no Buy buttons block is added onto the page.",
"default": true
},
{
"type": "checkbox",
"id": "show_share_buttons",
"label": "Show share buttons",
"default": true
},
{
"type": "page",
"id": "help_page",
"label": "Help page",
"info": "Feature a page to help your customers"
},
{
"type": "header",
"content": "Media"
},
{
"type": "paragraph",
"content": "Learn more about [media types](https://help.shopify.com/en/manual/products/product-media)"
},
{
"type": "checkbox",
"id": "enable_video_autoplay",
"label": "Enable video autoplay",
"info": "Video are muted automatically to allow autoplay",
"default": true
},
{
"type": "checkbox",
"id": "enable_video_looping",
"label": "Enable video looping",
"default": false
},
{
"type": "checkbox",
"id": "enable_image_zoom",
"label": "Enable image zoom",
"info": "Zoom does not show video nor 3D models.",
"default": true
},
{
"type": "checkbox",
"id": "show_thumbnails_on_mobile",
"label": "Show thumbnails on mobile",
"default": false
},
{
"type": "select",
"id": "desktop_thumbnails_position",
"label": "Desktop thumbnails position",
"options": [
{
"value": "left",
"label": "Left"
},
{
"value": "bottom",
"label": "Bottom"
}
],
"default": "bottom"
},
{
"type": "select",
"id": "transition_effect",
"label": "Transition effect",
"options": [
{
"value": "slide",
"label": "Slide"
},
{
"value": "fade",
"label": "Fade"
}
],
"default": "slide"
}
]
}
{% endschema %}
If you want to show linked products as “variants” in Focal, you can place a small code snippet in your main-product.liquid. Here’s the cleanest spot:
Steps:
Open Online Store > Themes > Edit code.
In Sections, open main-product.liquid.
Find this part of your file:
<product-rerender id="product-info-{{ product.id }}-{{ section.id }}" observe-form="{{ product_form_id }}" allow-partial-rerender>
<div class="product ...
{%- render 'product-media', ... -%}
{%- render 'product-info', ... -%}
Just above {%- render 'product-info' ... -%}, paste your linked product code. For example:
<div class="linked-products">
<a href="/products/product-1">Option 1</a>
<a href="/products/product-2">Option 2</a>
</div>
Save, then style those links as swatches or buttons with CSS.
Let me know if this helps
Hi @user1747,
There will be 2 options for you:
Hope it is clear to you !
Best,
NamPhan
Hello,
Thank you.
We have succeeded to place options on product page.
Right now, if we place a link, it applies to all products, not just the particular product we want.
How can we link different products to different products?
Hi user1747 ![]()
It seems like you’re having trouble with the fact that if you place a link, it will apply to all products, not just the specific one you want. So you want to be able to link different products together. No worries — Easify Product Options makes this simple. You can use the URL type option to connect separate products.
For example, if you have a product available in Black, Dark Blue, and Pink, each color can have its own product page. On each page, simply add options for the other colors and link them to their respective product URLs. That way, when a customer visits the “Black” product page and clicks “Dark Blue”, they’ll be redirected to the correct page and inventory — ensuring a smooth and consistent shopping experience.
In the final step - Assign product, make sure that all three colors are properly assigned.
This app is simple to use, and I’m confident it’ll work great for you! If you need any help, feel free to reach out to the Easify team - we’re always happy to assist! ![]()
Just seek out a product variants app, or combined listings type of app.
Doing this properly in theme code is advanced work beyond the scope of the forums.
You will miss things if you DIY without theme experience.
Hi @user1747,
Yes — you can absolutely link separate products to behave like variants, even without coding.
If you’d like a no-code solution, check out the Grouptify – Combined Listings & Variant app. It’s designed exactly for this use case: letting you group multiple related products (like different colors or styles) into one unified product view while still keeping individual product URLs for SEO and tracking.
For example, if you sell different phone models (iPhone 14 case, iPhone 15 case, iPhone 15 Pro case) but each one is listed as its own product. The app lets you group standalone products and display them as selectable options on the product page — without merging their inventories or URLs.
So when a customer lands on the “iPhone 15 Case” page and clicks “iPhone 14 Case,” they’ll be redirected to the correct product page while keeping a smooth variant-switching experience.
The app also lets you customize variant styles beautifully with buttons, color swatches, or even image thumbnails, making the UX much more engaging ![]()
Hope this helps!
Sophia,
The Tapita team.