Are you looking to enhance your Shopify product page by showing collapsible rows with icons, images, and even videos—all without using a paid app?
In this tutorial, we’ll walk you through how to build collapsible (accordion-style) rows on your Shopify product page using metaobjects, making it dynamic and clean. Plus, we’ll show you how to convert multiple collapsible rows into a slider, saving space and improving user experience.
đź§ Why Use Collapsible Rows?
Collapsible rows are perfect for:
- Displaying FAQs related to a product
- Organizing large amounts of product information
- Keeping your product page clean and user-friendly
- Adding icons, images, and even videos in a compact way
Step-by-Step Guide: No App Needed
1. Create a Metaobject
Go to your Shopify admin and:
- Navigate to Settings > Custom data > Metaobjects
- Create a new metaobject calledÂ
Collapsible Row (or your preferred name) - Add the following fields:
- Heading (text)
- Content (rich text)
- Image URL (file or text)
- Video URL (text)
- Icon (text or image)
✅ Once created, assign this metaobject to the Product resource using the “List of entries” field.
2. Go to Your Theme Code
Open your theme’s code editor and:
- Search forÂ
main-product.liquid (or similar in your theme) - Locate the default collapsible row/accordion code and remove or comment it out
3. Create a New Snippet
- Go to theÂ
Snippets folder and create a new file, e.g.,Âcollapsible-rows-metaobject.liquid - Paste the custom code that will loop through your metaobject entries
<link rel=”stylesheet” href=”https://unpkg.com/swiper/swiper-bundle.min.css” />
<div class=”swiper-container” style=”max-width: 1200px; margin: 0 auto; overflow: hidden;”>
<div class=”swiper-wrapper”>
{% assign _item_data = product.metafields.custom.field_coll.value %}
{% for item_data in _item_data %}
<div class=”swiper-slide”>
<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 %}
{% if item_data.icon %}
<span class=”_icon_img”>
<img src=”{{ item_data.icon | img_url }}” alt=”Icon” />
</span>
{% endif %}
<h2 class=”h4 accordion__title inline-richtext”>
{{ item_data.head }}
</h2>
</div>
{{- ‘icon-caret.svg’ | inline_asset_content -}}
</summary>
<div class=”flex_image”>
<div class=”accordion__content rte” id=”ProductAccordion-{{ block.id }}-{{ section.id }}”>
{{ item_data.coll_content | metafield_tag }}
</div>
<div class=”coll-image-video”>
{% if item_data.image_url %}
<img src=”{{ item_data.image_url | img_url: ‘800x’ }}” alt=”{{ item_data.head | escape }}”>
{% endif %}
{% if item_data.video_url %}
<video autoplay loop controls>
<source src=”{{ item_data.video_url }}” type=”video/mp4″>
Your browser does not support the video tag.
</video>
{% endif %}
</div>
</div>
</details>
</div>
</div>
{% endfor %}
</div>
<div class=”swiper-pagination”></div>
<div class=”swiper-button-next”></div>
<div class=”swiper-button-prev”></div>
</div>
<script src=”https://unpkg.com/swiper/swiper-bundle.min.js”></script>
<script>
var swiper = new Swiper(‘.swiper-container’, {
slidesPerView: 1,
spaceBetween: 10,
navigation: {
nextEl: ‘.swiper-button-next’,
prevEl: ‘.swiper-button-prev’,
},
pagination: {
el: ‘.swiper-pagination’,
clickable: true,
},
});
</script>
<style>
.accordion {
background-color: #1c1c1c;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
margin-bottom: 20px;
transition: all 0.3s ease;
border: 1px solid #333;
}
.summary__title {
display: flex;
align-items: center;
padding: 15px;
cursor: pointer;
border-bottom: 1px solid #444;
background-color: #2b2b2b;
transition: background-color 0.3s ease, color 0.3s ease;
}
.summary__title h2 {
margin: 0;
font-size: 1.2rem;
font-weight: normal;
color: #ddd; /* Light text color */
flex: 1;
transition: color 0.3s ease;
}
.accordion details[open] .summary__title h2 {
font-weight: bold;
color: #fff; /* White for active state */
}
.accordion details[open] {
background-color: #2b2b2b; /* Dark background for open state */
border: 1px solid #555;
}
.summary__title:hover {
background-color: #333; /* Darker on hover */
}
._icon_img {
margin-right: 10px;
}
._icon_img img {
width: 20px;
height: 20px;
}
summary::after {
content: url({{ ‘icon-caret.svg’ | inline_asset_content }});
filter: brightness(0) invert(1); /* Invert caret for dark mode */
transition: transform 0.3s ease;
}
details[open] summary::after {
transform: rotate(180deg);
}
.accordion__content {
padding: 15px;
line-height: 1.6;
color: #ccc; /* Lighter text color */
background-color: #1c1c1c; /* Dark background */
}
.coll-image-video {
margin-top: 10px;
text-align: center;
}
.coll-image-video img {
max-width: 90%;
height: auto;
border-radius: 6px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); /* Stronger shadow for dark mode */
}
.coll-image-video video {
width: 90%;
height: auto;
border-radius: 6px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); /* Stronger shadow */
margin-top: 10px;
}
@media (max-width: 768px) {
.summary__title {
padding: 10px;
flex-direction: column;
align-items: flex-start;
}
.summary__title h2 {
font-size: 1rem;
}
._icon_img {
margin-bottom: 5px;
}
._icon_img img {
width: 18px;
height: 18px;
}
.accordion__content {
padding: 10px;
font-size: 0.95rem;
}
.coll-image-video img,
.coll-image-video video {
max-width: 85%;
margin: 0 auto;
}
.coll-image-video video {
height: auto;
max-height: 200px;
}
}
.swiper-pagination.swiper-pagination-clickable.swiper-pagination-bullets.swiper-pagination-horizontal {
margin: -12px;
}
</style>
- The code will:
- Render each entry’s heading, content
- Show the image and video if present
- Display the icon
4. Render the Snippet in the Product File
Back in your main-product.liquid, render your new snippet like this:
{% render ‘collapsible-rows-metaobject’ %}
5. Customize in Theme Editor
After implementing the snippet, go to your Theme Editor:
- Add the “Custom Liquid” section or a custom block for rendering collapsible rows
- Ensure your newly added metaobject entries are connected to each product
- You’ll now see collapsible rows show dynamically on the frontend
If you add multiple metaobject entries, they will automatically display in a horizontal slider format, making the layout compact and professional. This avoids long pages that scroll endlessly and keeps the content organized.
âś… Features of This Setup
- No external app required
- Fully dynamic using metaobjects
- Works with text, icons, images, and videos
- Automatically turns into a slider when multiple entries are added
- Easy to manage from Shopify admin
- Mobile responsive
🎯 Use Cases
- Product Q&A
- Technical specifications
- Tutorials or video guides
- Size charts with visuals
- Feature highlights
Have questions or facing issues with the Horizon theme? Drop a comment or reach out — we’re here to help!

