In this tutorial, we are adding a custom theme block for dynamic product descriptions that change with your product variants.
Compatible Themes: This code should work on all free Shopify themes (Dawn, Refresh, Craft, Studio, Publisher, Crave, Origin, Taste, Colorblock, Sense, Ride, Spotlight).
Create variant metafields
- Create a new variant metafield for your variant descriptions.
- Can be either type rich text or type page
- Ex 1:
- Name: Variant Description Rich Text
- Type: Rich Text
- Namespace and key: custom.variant_description_rich_text
- Ex 2:
- Name: Variant Description Page
- Type: Page
- Namespace and key: custom.variant_description_page
- Place your created variant metafield namespace and key into the variant description theme editor settings.
Update theme code
Update main-product.liquid file
Add new block for variant description:
{%- when 'variant_description' -%}
<div class="product__description variant__description rte quick-add-hidden" {{ block.shopify_attributes }}>
{% assign namespace = block.settings.variant_description_namespace %}
{% assign key = block.settings.variant_description_key %}
{% if namespace != blank and key != blank %}
{% assign variant_description_metafield = product.selected_or_first_available_variant.metafields[namespace][key] %}
{% if variant_description_metafield.type == 'rich_text_field' %}
{% assign variant_description_text = variant_description_metafield | metafield_tag %}
{% elsif variant_description_metafield.type == 'page_reference' %}
{% assign variant_description_page_handle = variant_description_metafield.value.handle %}
{% assign variant_description_page = pages[variant_description_page_handle] %}
{% if variant_description_page %}
{% assign variant_description_text = variant_description_page.content %}
{% endif %}
{% endif %}
{% endif %}
<div class="variant-description__content">
{%- if variant_description_text != blank -%}
{{ variant_description_text }}
{% else %}
{% case block.settings.default_description_type %}
{% when 'product_description' %}
{%- if product.description != blank -%}
{{ product.description }}
{%- endif -%}
{% when 'richtext_description' %}
{%- if block.settings.richtext_description != blank -%}
{{ block.settings.richtext_description }}
{%- endif -%}
{% when 'page_description' %}
{%- if block.settings.page_description != blank -%}
{{ pages[block.settings.page_description].content }}
{%- endif -%}
{% when 'none' %}
<!-- Intentionally left empty -->
{% endcase %}
{% endif %}
</div>
</div>
Add settings for variant description
{
"type": "variant_description",
"name": "Variant Description",
"limit": 1,
"settings": [
{
"type": "text",
"id": "heading",
"default": "Variant Description",
"label": "Variant Description Name"
},
{
"type": "text",
"id": "variant_description_namespace",
"label": "Variant Description Metafield Namespace",
"default": "custom"
},
{
"type": "text",
"id": "variant_description_key",
"label": "Variant Description Metafield Key",
"default": "variant_description"
},
{
"type": "select",
"id": "default_description_type",
"options": [
{
"value": "product_description",
"label": "Product Description"
},
{
"value": "richtext_description",
"label": "Rich Text"
},
{
"value": "page_description",
"label": "Page"
},
{
"value": "none",
"label": "None"
}
],
"default": "product_description",
"label": "Fallback Variant Description",
"info": "Fallback source if variant description is empty"
},
{
"type": "richtext",
"id": "richtext_description",
"label": "Fallback Rich Text Variant Description"
},
{
"type": "page",
"id": "page_description",
"label": "Fallback Page Variant Description"
}
]
},
Update product-info.js file
Add new method updateDescription
updateDescription(html) {
const newDescriptionContainer = html.querySelector('.variant__description');
const currentDescriptionContainer = this.querySelector('.variant__description');
if (newDescriptionContainer && currentDescriptionContainer) {
const newContent = newDescriptionContainer.innerHTML.trim();
if (newContent === '') {
// Hide the container if there's no content
currentDescriptionContainer.classList.add('hidden');
currentDescriptionContainer.innerHTML = '';
} else {
// Show and update the container if there's content
currentDescriptionContainer.classList.remove('hidden');
currentDescriptionContainer.innerHTML = newContent;
}
}
}
Call new method from method handleUpdateProductInfo
this.updateDescription(html);