<style>
/* Outer section spans full width */
#testimonial-slider-{{ section.id }} {
width: 100%;
text-align: center;
}
/* Container for heading and slider */
#testimonial-slider-{{ section.id }} .testimonial-slider-container {
margin: 0 auto;
}
#testimonial-slider-{{ section.id }} .testimonial-heading {
font-size: {% if section.settings.heading_size == 'small' %}24px{% elsif section.settings.heading_size == 'medium' %}32px{% elsif section.settings.heading_size == 'large' %}40px{% endif %};
text-align: {{ section.settings.heading_alignment }};
margin-bottom: 20px;
}
#testimonial-slider-{{ section.id }} .testimonial-slider-wrapper {
position: relative;
overflow: hidden;
}
#testimonial-slider-{{ section.id }} .testimonial-slider {
overflow: hidden;
position: relative;
}
#testimonial-slider-{{ section.id }} .slider-track {
display: flex;
transition: transform 0.5s ease-in-out;
will-change: transform;
}
/* Desktop: Each slide's width based on visible_slides setting */
#testimonial-slider-{{ section.id }} .testimonial-slide {
flex: 0 0 calc(100% / {{ section.settings.visible_slides }});
padding: 20px;
box-sizing: border-box;
}
/* Mobile override: use visible_mobile setting */
@media (max-width: 767px) {
#testimonial-slider-{{ section.id }} .testimonial-slide {
flex: 0 0 calc(100% / {{ section.settings.visible_mobile }});
}
}
#testimonial-slider-{{ section.id }} .testimonial-slide img {
width: 100%;
object-fit: cover;
{% if section.settings.image_shape == 'circle' %}
border-radius: 50%;
{% else %}
border-radius: 0;
{% endif %}
{% if section.settings.image_size == 'small' %}
width: 80px;
height: 80px;
{% else %}
width: 150px;
height: 150px;
{% endif %}
}
#testimonial-slider-{{ section.id }} .testimonial-name {
font-size: {{ section.settings.testimonial_name_size }}px;
margin-bottom: 10px;
}
#testimonial-slider-{{ section.id }} .testimonial-text {
font-size: 16px;
}
/* Arrow Buttons */
#testimonial-slider-{{ section.id }} .arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: {{ section.settings.arrow_bg_color }};
color: #fff;
border: none;
font-size: 24px;
padding: 10px;
cursor: pointer;
z-index: 10;
border-radius: {% if section.settings.arrow_shape == 'circle' %}50%{% else %}0{% endif %};
display: flex;
align-items: center;
justify-content: center;
padding: 0px 0px;
width: 50px;
height: 50px;
}
#testimonial-slider-{{ section.id }} .left-arrow {
left: 10px;
}
#testimonial-slider-{{ section.id }} .right-arrow {
right: 10px;
}
</style>
{%- comment -%}
Use the "visible_slides" setting as the number of slides to show (desktop) and "visible_mobile" for mobile.
Also, clone the last N testimonials at the beginning and first N at the end.
{%- endcomment -%}
{% assign cloneCount = section.settings.visible_slides %}
<div id="testimonial-slider-{{ section.id }}" class="page-width testimonial-slider-section" style="background-color: {{ section.settings.section_bg_color }}; padding-top: {{ section.settings.section_padding_top }}px; padding-bottom: {{ section.settings.section_padding_bottom }}px;">
<div class="testimonial-slider-container" style="width: {% if section.settings.full_width %}100%{% else %}80%{% endif %}; margin: 0 auto;">
{% if section.settings.section_heading != blank %}
<h2 class="testimonial-heading">{{ section.settings.section_heading }}</h2>
{% endif %}
<div class="testimonial-slider-wrapper">
{% if section.settings.show_arrows %}
<button class="arrow left-arrow">❮</button>
{% endif %}
<div class="testimonial-slider">
<div class="slider-track">
{% assign total = section.blocks.size %}
{% if total > 0 %}
{%- comment -%}
Clone the last {{ cloneCount }} testimonials at the beginning.
{%- endcomment -%}
{% assign offset_value = total | minus: cloneCount %}
{% for block in section.blocks limit: cloneCount offset: offset_value %}
<div class="testimonial-slide clone" {% if section.settings.card_shadow %}style="box-shadow: 0px 4px 8px rgba(0,0,0,0.2);" {% endif %}>
{% if block.settings.image != blank %}
<img class="testimonial-image" src="{{ block.settings.image | img_url: 'medium' }}" alt="{{ block.settings.name }}">
{% endif %}
<h3 class="testimonial-name">{{ block.settings.name }}</h3>
<p class="testimonial-text">{{ block.settings.description }}</p>
</div>
{% endfor %}
{%- comment -%}
Real testimonial slides.
{%- endcomment -%}
{% for block in section.blocks %}
<div class="testimonial-slide" {% if section.settings.card_shadow %}style="box-shadow: 0px 4px 8px rgba(0,0,0,0.2);" {% endif %}>
{% if block.settings.image != blank %}
<img class="testimonial-image" src="{{ block.settings.image | img_url: 'medium' }}" alt="{{ block.settings.name }}">
{% endif %}
<h3 class="testimonial-name">{{ block.settings.name }}</h3>
<p class="testimonial-text">{{ block.settings.description }}</p>
</div>
{% endfor %}
{%- comment -%}
Clone the first {{ cloneCount }} testimonials at the end.
{%- endcomment -%}
{% for block in section.blocks limit: cloneCount %}
<div class="testimonial-slide clone" {% if section.settings.card_shadow %}style="box-shadow: 0px 4px 8px rgba(0,0,0,0.2);" {% endif %}>
{% if block.settings.image != blank %}
<img class="testimonial-image" src="{{ block.settings.image | img_url: 'medium' }}" alt="{{ block.settings.name }}">
{% endif %}
<h3 class="testimonial-name">{{ block.settings.name }}</h3>
<p class="testimonial-text">{{ block.settings.description }}</p>
</div>
{% endfor %}
{% endif %}
</div>
</div>
{% if section.settings.show_arrows %}
<button class="arrow right-arrow">❯</button>
{% endif %}
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const container = document.getElementById("testimonial-slider-{{ section.id }}");
if (!container) return;
const sliderTrack = container.querySelector(".slider-track");
const slides = container.querySelectorAll(".testimonial-slide");
if (slides.length === 0) return;
// Define gap (if any gap is needed, adjust here; not used in calc() since we used 100%/visibleSlides)
const gap = 0;
// For desktop: get slide width based on visible_slides setting
let visibleSlides = {{ section.settings.visible_slides }};
let slideWidth = container.querySelector(".testimonial-slider").offsetWidth / visibleSlides;
function updateSlidePosition() {
sliderTrack.style.transform = "translateX(-" + (currentIndex * slideWidth) + "px)";
}
let currentIndex = {{ cloneCount }};
updateSlidePosition();
function nextSlide() {
currentIndex++;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
updateSlidePosition();
if (currentIndex >= slides.length - {{ cloneCount }}) {
setTimeout(() => {
sliderTrack.style.transition = "none";
currentIndex = {{ cloneCount }};
updateSlidePosition();
void sliderTrack.offsetWidth;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
}, 500);
}
}
function prevSlide() {
currentIndex--;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
updateSlidePosition();
if (currentIndex < {{ cloneCount }}) {
setTimeout(() => {
sliderTrack.style.transition = "none";
currentIndex = slides.length - {{ cloneCount }} - 1;
updateSlidePosition();
void sliderTrack.offsetWidth;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
}, 500);
}
}
const leftArrow = container.querySelector(".left-arrow");
const rightArrow = container.querySelector(".right-arrow");
if (leftArrow) leftArrow.addEventListener("click", prevSlide);
if (rightArrow) rightArrow.addEventListener("click", nextSlide);
const autoSlide = {{ section.settings.auto_slide | json }};
const autoSlideSpeed = {{ section.settings.auto_slide_speed | json }};
if (autoSlide) {
setInterval(nextSlide, autoSlideSpeed);
}
window.addEventListener("resize", () => {
// Recalculate slide width
visibleSlides = window.innerWidth <= 767 ? {{ section.settings.visible_mobile }} : {{ section.settings.visible_slides }};
slideWidth = container.querySelector(".testimonial-slider").offsetWidth / visibleSlides;
sliderTrack.style.transition = "none";
updateSlidePosition();
});
});
</script>
{% schema %}
{
"name": "Testimonial Slider",
"settings": [
{
"type": "text",
"id": "section_heading",
"label": "Section Heading",
"default": "Testimonials"
},
{
"type": "select",
"id": "heading_alignment",
"label": "Section Heading Alignment",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "center", "label": "Center" },
{ "value": "right", "label": "Right" }
],
"default": "center"
},
{
"type": "select",
"id": "heading_size",
"label": "Section Heading Size",
"options": [
{ "value": "small", "label": "Small" },
{ "value": "medium", "label": "Medium" },
{ "value": "large", "label": "Large" }
],
"default": "medium"
},
{
"type": "checkbox",
"id": "full_width",
"label": "Full Width Section",
"default": false
},
{
"type": "color",
"id": "section_bg_color",
"label": "Section Background Color",
"default": "#ffffff"
},
{
"type": "range",
"id": "section_padding_top",
"label": "Section Padding Top (px)",
"min": 0,
"max": 200,
"step": 5,
"default": 40
},
{
"type": "range",
"id": "section_padding_bottom",
"label": "Section Padding Bottom (px)",
"min": 0,
"max": 200,
"step": 5,
"default": 40
},
{
"type": "checkbox",
"id": "auto_slide",
"label": "Enable Auto Slide",
"default": true
},
{
"type": "range",
"id": "auto_slide_speed",
"label": "Auto Slide Speed (ms)",
"min": 100,
"max": 9000,
"step": 100,
"default": 6000
},
{
"type": "checkbox",
"id": "show_arrows",
"label": "Show Left/Right Arrows",
"default": true
},
{
"type": "select",
"id": "arrow_shape",
"label": "Arrow Shape",
"options": [
{ "value": "circle", "label": "Circle" },
{ "value": "square", "label": "Square" }
],
"default": "circle"
},
{
"type": "color",
"id": "arrow_bg_color",
"label": "Arrow Background Color",
"default": "#000000"
},
{
"type": "select",
"id": "image_shape",
"label": "Image Shape",
"options": [
{ "value": "circle", "label": "Circle" },
{ "value": "square", "label": "Square" }
],
"default": "circle"
},
{
"type": "select",
"id": "image_size",
"label": "Image Size",
"options": [
{ "value": "small", "label": "Small" },
{ "value": "big", "label": "Big" }
],
"default": "small"
},
{
"type": "range",
"id": "visible_slides",
"label": "Number of Visible Slides (Desktop)",
"min": 1,
"max": 5,
"step": 1,
"default": 1
},
{
"type": "range",
"id": "visible_mobile",
"label": "Number of Visible Slides (Mobile)",
"min": 1,
"max": 5,
"step": 1,
"default": 1
},
{
"type": "range",
"id": "testimonial_name_size",
"label": "Testimonial Name Font Size (px)",
"min": 12,
"max": 36,
"step": 1,
"default": 20
},
{
"type": "checkbox",
"id": "card_shadow",
"label": "Enable Testimonial Card Shadow",
"default": false
}
],
"blocks": [
{
"type": "testimonial",
"name": "Testimonial",
"settings": [
{
"type": "image_picker",
"id": "image",
"label": "Image"
},
{
"type": "text",
"id": "name",
"label": "Name"
},
{
"type": "textarea",
"id": "description",
"label": "Testimonial Text"
}
]
}
],
"max_blocks": 10,
"presets": [
{
"name": "Testimonial Slider"
}
]
}
{% endschema %}
The Power of Testimonial Sliders: 7 Reasons to Add One to Your Shopify Store
1. Builds Instant Trust & Credibility
A scrolling carousel of real customer feedback helps new visitors feel confident in your brand before they even browse your products.
💡 Pro Tip: Include photos, names, and locations (e.g., “Sarah K. – New York”) to make testimonials feel more authentic.
2. Increases Conversion Rates
Testimonial sliders reduce purchase hesitation by showing social proof directly on product pages.
📈 Example: A Shopify store saw a 15% increase in conversions after adding a testimonial slider to their checkout page.
3. Enhances User Experience (UX)
Instead of a static block of text, a dynamic slider keeps visitors engaged while saving space.
🎯 Best Placement:
- Homepage (above the fold)
- Product pages (near “Add to Cart”)
- Checkout page (to reduce cart abandonment)
4. Showcases Different Customer Perspectives
A slider lets you highlight:
- Product quality reviews
- Shipping/delivery experiences
- Customer service praise
📌 Example: Rotate between:
“Love this dress! Fits perfectly.”
“Fast shipping, great packaging!”
“Customer support was super helpful!”
5. Mobile-Friendly & Space-Efficient
Unlike long review sections, a slider fits beautifully on mobile devices—where 75% of Shopify traffic comes from.
📱 Optimization Tip: Use a touch-friendly swipe function for mobile users.
6. Encourages More Reviews
A visually appealing testimonial slider motivates happy customers to leave feedback—knowing it’ll be featured.
💬 How to Get More Reviews:
- Offer a discount for leaving a review
- Send post-purchase emails requesting feedback
7. Boosts SEO (Indirectly)
While testimonials themselves aren’t a direct ranking factor, they:
Encourage user-generated content (Google loves fresh content)
Increase dwell time (users stay longer reading reviews)
Reduce bounce rates (trust = more exploration)