Want personalized guidance adding this to your store?
Check out our Insiders community: https://www.skool.com/the-prompted
Members of The Prompted community receive a detailed store audit, 1-on-1 guidance for implementing new features, and access to an exclusive theme. You'll also get marketing support, the same tactics we use to spend over $100k/mo on Meta Ads.
---
In this customization we’re adding icons to your Shopify store.
You can use them in all sorts of ways, but ultimately, these icons tell your customers what’s great about your product or brand.
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
Create Metaobject for Icon With Text
Name: Icon With Text
Type: icon_with_text
Fields:
- Name
- Type: Single line text
- Regular expression:
^[a-zA-Z0-9_-]+$
(alphanumeric with - and _)
- Icons
- Type: List of files (Images)
- Text
- Type: List of Single line text
Create Product Metafield with the Icon With Text Metaobject
Name: Icons
Namespace and key: custom.icons
Type: Metaobject: Icon With Text
Edit Theme Code
Create new liquid snippet icon-with-text-custom.liquid
{% comment %}
Renders icons with text blocks using a metaobject/metafield for dynamic icon count and ordering.
{% endcomment %}
{% if icon_source == 'product_metafield' %}
{% assign page_icons = product.metafields.custom.icons.value %}
{% elsif icon_source == 'metaobject_entry' %}
{% assign page_icons = nil %}
{% for entry in shop.metaobjects.icon_with_text.values %}
{% if entry.name == metaobject_entry_name %}
{% assign page_icons = entry %}
{% break %}
{% endif %}
{% endfor %}
{% endif %}
<ul
class="icon-with-text icon-with-text-custom--{{ block_or_section_id }} icon-with-text--{{ layout }} list-unstyled"
style="--icons-per-line: {{ icons_per_line }}; --columns: {{ num_columns }};"
>
{% for icon_path in page_icons.icons.value %}
{% assign image_url = icon_path | img_url: 'master' %}
{% assign icon_index = forloop.index0 %}
{% assign icon_text = page_icons.text.value[icon_index] %}
<li class="icon-with-text__item">
<img src="{{ image_url }}" alt="{{ icon_text | escape }}" height="auto" width="auto" loading="lazy">
<span class="{{ heading_size }} inline-richtext icon-with-text-custom--{{ block_or_section_id }}">{{ icon_text }}</span>
</li>
{% endfor %}
</ul>
<style>
.icon-with-text.icon-with-text-custom--{{ block_or_section_id }} {
--icon-size: calc(var(--font-heading-scale) * {{ icon_size }}rem);
}
.icon-with-text--horizontal.icon-with-text-custom--{{ block_or_section_id }} {
display: flex;
flex-wrap: wrap;
gap: 2rem;
padding-left: {{ icons_horiz_padding_left }}%;
padding-right: {{ icons_horiz_padding_right }}%;
}
.icon-with-text--horizontal.icon-with-text-custom--{{ block_or_section_id }} .icon-with-text__item {
flex: 1 0 calc((100% / var(--icons-per-line)) - 2rem);
text-align: center;
}
.icon-with-text--vertical.icon-with-text-custom--{{ block_or_section_id }} {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
gap: 2rem;
}
.icon-with-text--vertical.icon-with-text-custom--{{ block_or_section_id }} .icon-with-text__item {
text-align: center;
margin-bottom: 0rem;
}
/* Icon with text (needed styles if not on a product page) */
.icon-with-text {
--icon-size: calc(var(--font-heading-scale) * 3rem);
--icon-spacing: calc(var(--font-heading-scale) * 1rem);
}
.icon-with-text--horizontal {
display: flex;
justify-content: center;
column-gap: 3rem;
flex-direction: row;
}
.icon-with-text--vertical {
--icon-size: calc(var(--font-heading-scale) * 2rem);
}
.icon-with-text .icon {
fill: rgb(var(--color-foreground));
height: var(--icon-size);
width: var(--icon-size);
}
.icon-with-text--horizontal .icon,
.icon-with-text--horizontal img {
margin-bottom: var(--icon-spacing);
}
.icon-with-text--vertical .icon {
min-height: var(--icon-size);
min-width: var(--icon-size);
margin-right: var(--icon-spacing);
}
.icon-with-text img {
height: var(--icon-size);
width: var(--icon-size);
object-fit: contain;
}
.icon-with-text--vertical img {
margin-right: var(--icon-spacing);
}
.icon-with-text--horizontal .h4 {
padding-top: calc(var(--icon-size) + var(--icon-spacing));
text-align: center;
}
.icon-with-text--horizontal svg + .h4,
.icon-with-text--horizontal img + .h4,
.icon-with-text--horizontal.icon-with-text--text-only .h4 {
padding-top: 0;
}
.icon-with-text__item {
display: flex;
align-items: center;
}
.icon-with-text--horizontal .icon-with-text__item {
flex-direction: column;
width: 33%;
}
.icon-with-text--vertical .icon-with-text__item {
margin-bottom: var(--icon-size);
}
</style>
Update the code in main-product.liquid to add the block to the Product Information section
{%- when 'icon-with-text-custom' -%}
{% render 'icon-with-text-custom',
block_or_section_id: block.id,
icon_source: block.settings.icon_source,
metaobject_entry_name: block.settings.metaobject_entry_name,
layout: block.settings.layout,
icons_per_line: block.settings.icons_per_line,
num_columns: block.settings.num_columns,
icon_size: block.settings.icon_size,
heading_size: block.settings.heading_size,
icons_horiz_padding_left: block.settings.icons_horiz_padding_left,
icons_horiz_padding_right: block.settings.icons_horiz_padding_right
%}
Add the block settings at bottom
{
"type": "icon-with-text-custom",
"name": "Icon With Text Custom",
"settings": [
{
"type": "select",
"id": "icon_source",
"label": "Icon Source",
"options": [
{
"value": "product_metafield",
"label": "Product Metafield"
},
{
"value": "metaobject_entry",
"label": "Metaobject Entry"
}
],
"default": "product_metafield"
},
{
"type": "text",
"id": "metaobject_entry_name",
"label": "Metaobject Entry Name"
},
{
"type": "select",
"id": "layout",
"options": [
{
"value": "horizontal",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.options__1.label"
},
{
"value": "vertical",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.options__2.label"
}
],
"default": "horizontal",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.label"
},
{
"type": "range",
"id": "icons_per_line",
"label": "Icons per Line (horizontal layout)",
"default": 3,
"min": 1,
"max": 5
},
{
"type": "range",
"id": "icons_horiz_padding_left",
"label": "Icons Left Padding (horizontal layout)",
"min": 0,
"step": 1,
"max": 100,
"default": 0
},
{
"type": "range",
"id": "icons_horiz_padding_right",
"label": "Icons Right Padding (horizontal layout)",
"min": 0,
"step": 1,
"max": 100,
"default": 0
},
{
"type": "range",
"id": "num_columns",
"label": "Number of Columns (vertical layout)",
"default": 1,
"min": 1,
"max": 3
},
{
"type": "range",
"id": "icon_size",
"label": "Icon Size",
"min": 1,
"max": 10,
"step": 0.5,
"default": 4,
"unit": "rem"
},
{
"type": "select",
"id": "heading_size",
"label": "Heading Size",
"options": [
{
"value": "h3",
"label": "H3"
},
{
"value": "h4",
"label": "H4"
},
{
"value": "h5",
"label": "H5"
}
],
"default": "h4"
}
]
}
Create new liquid section icon-with-text-custom.liquid
<div class="page-width">
{% render 'icon-with-text-custom',
block_or_section_id: section.id,
icon_source: section.settings.icon_source,
metaobject_entry_name: section.settings.metaobject_entry_name,
layout: section.settings.layout,
icons_per_line: section.settings.icons_per_line,
num_columns: section.settings.num_columns,
icon_size: section.settings.icon_size,
heading_size: section.settings.heading_size,
icons_horiz_padding_left: section.settings.icons_horiz_padding_left,
icons_horiz_padding_right: section.settings.icons_horiz_padding_right
%}
</div>
{% schema %}
{
"name": "Icon with Text Custom",
"settings": [
{
"type": "select",
"id": "icon_source",
"label": "Icon Source",
"options": [
{
"value": "product_metafield",
"label": "Product Metafield"
},
{
"value": "metaobject_entry",
"label": "Metaobject Entry"
}
],
"default": "metaobject_entry"
},
{
"type": "text",
"id": "metaobject_entry_name",
"label": "Metaobject Entry Name"
},
{
"type": "select",
"id": "layout",
"options": [
{
"value": "horizontal",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.options__1.label"
},
{
"value": "vertical",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.options__2.label"
}
],
"default": "horizontal",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.label"
},
{
"type": "range",
"id": "icons_per_line",
"label": "Icons per Line (horizontal layout)",
"default": 5,
"min": 1,
"max": 8
},
{
"type": "range",
"id": "icons_horiz_padding_left",
"label": "Icons Left Padding (horizontal layout)",
"min": 0,
"step": 1,
"max": 100,
"default": 0
},
{
"type": "range",
"id": "icons_horiz_padding_right",
"label": "Icons Right Padding (horizontal layout)",
"min": 0,
"step": 1,
"max": 100,
"default": 0
},
{
"type": "range",
"id": "num_columns",
"label": "Number of Columns (vertical layout)",
"default": 2,
"min": 1,
"max": 5
},
{
"type": "range",
"id": "icon_size",
"label": "Icon Size",
"min": 3,
"max": 15,
"step": 0.5,
"default": 7,
"unit": "rem"
},
{
"type": "select",
"id": "heading_size",
"label": "Heading Size",
"options": [
{
"value": "h2",
"label": "H2"
},
{
"value": "h3",
"label": "H3"
},
{
"value": "h4",
"label": "H4"
},
{
"value": "h5",
"label": "H5"
}
],
"default": "h4"
}
],
"presets": [
{
"name": "Icon With Text Custom",
"category": "Image"
}
]
}
{% endschema %}
Add The Icons To The Cart Drawer
This follow-up customization was created to add this badge customization to the cart drawer.
Update cart-drawer by rendering icon-with-text.liquid where you want it to appear
{% if settings.enable_cart_drawer_icons %}
<style>
.icon-with-text__drawer {
border-top: .1rem solid rgba(var(--color-foreground), .2);
padding: 1.5rem 0;
}
</style>
<div class="icon-with-text__drawer" >
{% render 'icon-with-text-custom',
block_or_section_id: block.id,
icon_source: settings.icon_source,
metaobject_entry_name: settings.metaobject_entry_name,
layout: settings.layout,
icons_per_line: settings.icons_per_line,
num_columns: settings.num_columns,
icon_size: settings.icon_size,
heading_size: settings.heading_size,
icons_horiz_padding_left: settings.icons_horiz_padding_left,
icons_horiz_padding_right: settings.icons_horiz_padding_right
%}
</div>
{% endif %}
OPTIONAL: Make the icon bar collapsible
If you want to make the icon block a collapsible tab instead, then modify the cod for main-product.liquid so that it is instead the following:
Render the new file and comment out or delete the original code
{%- when 'icon-with-text-custom' -%}
<div class="product__accordion accordion quick-add-hidden" {{ block.shopify_attributes }}>
<details id="Details-{{ block.id }}-{{ section.id }}">
<summary>
<div class="summary__title">
{% render 'icon-accordion', icon: block.settings.icon %}
<h2 class="h4 accordion__title inline-richtext">
{{ block.settings.heading }}
</h2>
</div>
{% render 'icon-caret' %}
</summary>
<div class="accordion__content rte" id="ProductAccordion-{{ block.id }}-{{ section.id }}">
{% render 'icon-with-text-custom',
block_or_section_id: block.id,
icon_source: block.settings.icon_source,
metaobject_entry_name: block.settings.metaobject_entry_name,
layout: block.settings.layout,
icons_per_line: block.settings.icons_per_line,
num_columns: block.settings.num_columns,
icon_size: block.settings.icon_size,
heading_size: block.settings.heading_size
%}
</div>
</details>
</div>
Add the block settings at bottom
{
"type": "icon-with-text-custom",
"name": "Icon With Text Custom",
"settings": [
{
"type": "text",
"id": "heading",
"default": "Collapsible row",
"info": "t:sections.main-product.blocks.collapsible_tab.settings.heading.info",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.heading.label"
},
{
"type": "select",
"id": "icon",
"options": [
{
"value": "none",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__1.label"
},
{
"value": "apple",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__2.label"
},
{
"value": "banana",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__3.label"
},
{
"value": "bottle",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__4.label"
},
{
"value": "box",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__5.label"
},
{
"value": "carrot",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__6.label"
},
{
"value": "chat_bubble",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__7.label"
},
{
"value": "check_mark",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__8.label"
},
{
"value": "clipboard",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__9.label"
},
{
"value": "dairy",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__10.label"
},
{
"value": "dairy_free",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__11.label"
},
{
"value": "dryer",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__12.label"
},
{
"value": "eye",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__13.label"
},
{
"value": "fire",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__14.label"
},
{
"value": "gluten_free",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__15.label"
},
{
"value": "heart",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__16.label"
},
{
"value": "iron",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__17.label"
},
{
"value": "leaf",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__18.label"
},
{
"value": "leather",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__19.label"
},
{
"value": "lightning_bolt",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__20.label"
},
{
"value": "lipstick",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__21.label"
},
{
"value": "lock",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__22.label"
},
{
"value": "map_pin",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__23.label"
},
{
"value": "nut_free",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__24.label"
},
{
"value": "pants",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__25.label"
},
{
"value": "paw_print",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__26.label"
},
{
"value": "pepper",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__27.label"
},
{
"value": "perfume",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__28.label"
},
{
"value": "plane",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__29.label"
},
{
"value": "plant",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__30.label"
},
{
"value": "price_tag",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__31.label"
},
{
"value": "question_mark",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__32.label"
},
{
"value": "recycle",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__33.label"
},
{
"value": "return",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__34.label"
},
{
"value": "ruler",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__35.label"
},
{
"value": "serving_dish",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__36.label"
},
{
"value": "shirt",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__37.label"
},
{
"value": "shoe",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__38.label"
},
{
"value": "silhouette",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__39.label"
},
{
"value": "snowflake",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__40.label"
},
{
"value": "star",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__41.label"
},
{
"value": "stopwatch",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__42.label"
},
{
"value": "truck",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__43.label"
},
{
"value": "washing",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__44.label"
}
],
"default": "check_mark",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.label"
},
{
"type": "select",
"id": "icon_source",
"label": "Icon Source",
"options": [
{
"value": "product_metafield",
"label": "Product Metafield"
},
{
"value": "metaobject_entry",
"label": "Metaobject Entry"
}
],
"default": "product_metafield"
},
{
"type": "text",
"id": "metaobject_entry_name",
"label": "Metaobject Entry Name"
},
{
"type": "select",
"id": "layout",
"options": [
{
"value": "horizontal",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.options__1.label"
},
{
"value": "vertical",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.options__2.label"
}
],
"default": "horizontal",
"label": "t:sections.main-product.blocks.icon_with_text.settings.layout.label"
},
{
"type": "range",
"id": "icons_per_line",
"label": "Icons per Line (horizontal layout)",
"default": 3,
"min": 1,
"max": 5
},
{
"type": "range",
"id": "num_columns",
"label": "Number of Columns (vertical layout)",
"default": 1,
"min": 1,
"max": 3
},
{
"type": "range",
"id": "icon_size",
"label": "Icon Size",
"min": 1,
"max": 10,
"step": 0.5,
"default": 4,
"unit": "rem"
},
{
"type": "select",
"id": "heading_size",
"label": "Heading Size",
"options": [
{
"value": "h3",
"label": "H3"
},
{
"value": "h4",
"label": "H4"
},
{
"value": "h5",
"label": "H5"
}
],
"default": "h4"
}
]
}