In this customization, we’re linking products together like variants.
While Shopify recently announced extended products options such as combined listings and support for up to 2000 variants, these options aren't yet available. And even when they become available, they are only for Shopify Plus and API users.
This is the an alternative solution that you can use today.
Compatible Themes: This code should work on all free Shopify themes (Dawn, Refresh, Craft, Studio, Publisher, Crave, Origin, Taste, Colorblock, Sense, Ride, Spotlight).
Create Metaobject and Metafield
Repeat these steps for each Option Type desired. Below is an example.
Create a metaobject
Name: Product Grouping Option 1 Entries
Fields:
- Type: Single line text
- Name: Grouping Name
- Type: List of products
- Name: Product Grouping
Create Product Metafield with type Metaobject above
Name: Product Grouping Option 1
Type: Metaobject (Product Grouping Option 1 Entries)
Create Product Metafield with type Single Line Text
Name: Product Grouping Option 1 Value
Type: Single Line Text
Edit Theme Code
Create new snippet product-grouping-picker-custom.liquid
{%- if product.metafields.custom[block.settings.option_type_metafield_key] -%}
{% if product.has_only_default_variant %}
{{ 'component-product-variant-picker.css' | asset_url | stylesheet_tag }}
{% endif %}
{% assign related_products_metaobject = product.metafields.custom[block.settings.option_type_metafield_key].value %}
{% assign related_products = related_products_metaobject.product_grouping.value %}
{%- if block.settings.picker_type == 'button' -%}
<fieldset class="js product-form__input product-form__input--pill">
<legend class="form__label">{{ block.settings.grouping_label }}</legend>
{% for related_product in related_products %}
<input
type="radio"
id="related_product-{{ related_product.id }}-{{ block.id }}"
name="related_product_{{ block.id }}"
value="{{ related_product.url }}"
onchange="window.location.href=this.value;"
{% if product.handle == related_product.handle %}
checked="checked"
{% endif %}
>
<label for="related_product-{{ related_product.id }}-{{ block.id }}">{{ related_product.metafields.custom[block.settings.option_value_metafield_key].value }}</label>
{% endfor %}
</fieldset>
{%- elsif block.settings.picker_type == 'dropdown' -%}
<div class="product-form__input product-form__input--dropdown">
<label for="ProductSelect-related-{{ section.id }}" class="form__label">{{ block.settings.grouping_label }}</label>
<div class="select">
<select
id="ProductSelect-related-{{ section.id }}-{{ block.id }}"
class="select__select"
onchange="window.location.href=this.value;"
>
{% for related_product in related_products %}
<option
value="{{ related_product.url }}"
{% if product.handle == related_product.handle %}
selected="selected"
{% endif %}
>
{{ related_product.metafields.custom[block.settings.option_value_metafield_key].value }}
</option>
{% endfor %}
</select>
{% render 'icon-caret' %}
</div>
</div>
{%- endif -%}
{%- endif -%}
Edit main-product.liquid
Add the option to select product grouping picker as a block
{%- when 'product_grouping_picker' -%}
{% render 'product-grouping-picker-custom', product: product, block: block %}
Add block options in the settings schema
{
"type": "product_grouping_picker",
"name": "Product Grouping Picker",
"limit": 3,
"settings": [
{
"type": "text",
"id": "heading",
"default": "Product Grouping Picker",
"label": "Product Grouping Picker Option"
},
{
"type": "select",
"id": "picker_type",
"options": [
{
"value": "dropdown",
"label": "t:sections.main-product.blocks.variant_picker.settings.picker_type.options__1.label"
},
{
"value": "button",
"label": "t:sections.main-product.blocks.variant_picker.settings.picker_type.options__2.label"
}
],
"default": "button",
"label": "t:sections.main-product.blocks.variant_picker.settings.picker_type.label"
},
{
"type": "text",
"id": "grouping_label",
"default": "Grouping 1",
"label": "Product Grouping Label"
},
{
"type": "text",
"id": "option_type_metafield_key",
"label": "Option Metafield Key",
"info": "Used for the grouping option",
"default": "product_grouping_option_1"
},
{
"type": "text",
"id": "option_value_metafield_key",
"label": "Option Value Metafield Key",
"info": "Used for the grouping option value text",
"default": "product_grouping_option_1_value"
}
]
},