Shopify Reviews Section

Shopify Liquid July 23, 2026
Create a new section in theme code and add the code provided below:
{% schema %}
{
  "name": "Reviews Grid",
  "settings": [
    { "type": "image_picker", "id": "business_logo", "label": "Logo" },
    { "type": "range", "id": "logo_width", "label": "Logo Width (px)", "min": 40, "max": 300, "step": 5, "default": 140 },
    { "type": "text", "id": "business_name", "label": "Heading", "default": "Trusted Customer Reviews" },
    { "type": "text", "id": "rating_text", "label": "Rating Text", "default": "5.0 ★★★★★" },
    { "type": "text", "id": "review_count", "label": "Sub Text", "default": "Verified Clients" },
    { "type": "url", "id": "review_link", "label": "Button Link" },
    { "type": "text", "id": "review_button_text", "label": "Button Text", "default": "Leave a Review" },
    { "type": "color", "id": "card_bg", "label": "Card Background", "default": "#ffffff" },
    { "type": "checkbox", "id": "enable_shadow", "label": "Enable Card Shadow", "default": true },
    { "type": "checkbox", "id": "enable_border", "label": "Enable Card Border", "default": false },
    { "type": "color", "id": "border_color", "label": "Border Color", "default": "#e5e5e5" },
    { "type": "range", "id": "padding_top_desktop", "label": "Desktop Top Padding", "min": 0, "max": 200, "step": 5, "default": 60 },
    { "type": "range", "id": "padding_bottom_desktop", "label": "Desktop Bottom Padding", "min": 0, "max": 200, "step": 5, "default": 60 },
    { "type": "range", "id": "padding_left_desktop", "label": "Desktop Left Padding", "min": 0, "max": 100, "step": 5, "default": 20 },
    { "type": "range", "id": "padding_right_desktop", "label": "Desktop Right Padding", "min": 0, "max": 100, "step": 5, "default": 20 },
    { "type": "range", "id": "padding_top_mobile", "label": "Mobile Top Padding", "min": 0, "max": 150, "step": 5, "default": 30 },
    { "type": "range", "id": "padding_bottom_mobile", "label": "Mobile Bottom Padding", "min": 0, "max": 150, "step": 5, "default": 30 },
    { "type": "range", "id": "padding_left_mobile", "label": "Mobile Left Padding", "min": 0, "max": 50, "step": 5, "default": 15 },
    { "type": "range", "id": "padding_right_mobile", "label": "Mobile Right Padding", "min": 0, "max": 50, "step": 5, "default": 15 }
  ],
  "blocks": [
    {
      "type": "testimonial",
      "name": "Testimonial",
      "settings": [
        { "type": "image_picker", "id": "client_image", "label": "Client Image" },
        { "type": "text", "id": "client_name", "label": "Client Name" },
        { "type": "text", "id": "client_subtext", "label": "Text Under Name" },
        { "type": "textarea", "id": "testimonial", "label": "Testimonial Content" },
        { "type": "image_picker", "id": "icon_image", "label": "Top Right Icon (Optional)" }
      ]
    }
  ],
  "presets": [
    { "name": "Reviews Grid" }
  ]
}
{% endschema %}
<div class="rf-widget-{{ section.id }}">
  <div class="header-section">
    <div class="business-info">
      {% if section.settings.business_logo %}
        <img src="{{ section.settings.business_logo | image_url }}"
             style="width:{{ section.settings.logo_width }}px;">
      {% endif %}
      <div>
        <div class="business-name">{{ section.settings.business_name }}</div>
        <div class="rating">
          {{ section.settings.rating_text }}
          <span>{{ section.settings.review_count }}</span>
        </div>
      </div>
    </div>
    {% if section.settings.review_link != blank %}
      <a href="{{ section.settings.review_link }}" class="review-button" target="_blank">
        {{ section.settings.review_button_text }}
      </a>
    {% endif %}
  </div>
  <div class="reviews-container">
    {% for block in section.blocks %}
      <div class="review-card" {{ block.shopify_attributes }}>
        <div class="review-header">
          {% if block.settings.client_image %}
            <div class="avatar" style="background-image:url('{{ block.settings.client_image | image_url }}');"></div>
          {% else %}
            <div class="avatar">{{ block.settings.client_name | slice: 0,1 }}</div>
          {% endif %}
          <div class="review-meta">
            <div class="name">{{ block.settings.client_name }}</div>
            <div class="date">{{ block.settings.client_subtext }}</div>
          </div>
          {% if block.settings.icon_image %}
            <img class="icon" src="{{ block.settings.icon_image | image_url }}">
          {% endif %}
        </div>
        <div class="stars">★★★★★</div>
        <div class="review-text">
          <div class="content">{{ block.settings.testimonial }}</div>
          <span class="toggle-btn">Read more</span>
        </div>
      </div>
    {% endfor %}
  </div>
</div>
<style>
.rf-widget-{{ section.id }}{
  padding: {{ section.settings.padding_top_desktop }}px {{ section.settings.padding_right_desktop }}px {{ section.settings.padding_bottom_desktop }}px {{ section.settings.padding_left_desktop }}px;
}
@media(max-width:768px){
  .rf-widget-{{ section.id }}{
    padding: {{ section.settings.padding_top_mobile }}px {{ section.settings.padding_right_mobile }}px {{ section.settings.padding_bottom_mobile }}px {{ section.settings.padding_left_mobile }}px;
  }
}
.rf-widget-{{ section.id }} .header-section{
  display:flex;justify-content:space-between;align-items:center;
  flex-wrap:wrap;max-width:1200px;margin:0 auto 30px;
}
.rf-widget-{{ section.id }} .business-info{
  display:flex;align-items:center;gap:15px;
}
.rf-widget-{{ section.id }} .business-name{
  font-size:20px;font-weight:600;
}
.rf-widget-{{ section.id }} .rating{
  font-size:15px;color:#f5b301;margin-top:4px;
}
.rf-widget-{{ section.id }} .rating span{
  color:#555;margin-left:6px;font-size:14px;
}
/* Button */
.rf-widget-{{ section.id }} .review-button{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding:12px 26px;
  background:linear-gradient(135deg,#111,#333);
  color:#fff;
  font-weight:600;
  font-size:14px;
  border-radius:8px;
  text-decoration:none;
  transition:all .3s ease;
}
.rf-widget-{{ section.id }} .review-button:hover{
  transform:translateY(-2px);
  background:linear-gradient(135deg,#000,#222);
}
.rf-widget-{{ section.id }} .reviews-container{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:20px;
  max-width:1200px;
  margin:auto;
}
.rf-widget-{{ section.id }} .review-card{
  background:{{ section.settings.card_bg }};
  border-radius:12px;
  padding:20px;
  position:relative;
  {% if section.settings.enable_shadow %}box-shadow:0 4px 12px rgba(0,0,0,0.08);{% endif %}
  {% if section.settings.enable_border %}border:1px solid {{ section.settings.border_color }};{% endif %}
}
.rf-widget-{{ section.id }} .review-header{
  display:flex;align-items:center;margin-bottom:10px;
}
.rf-widget-{{ section.id }} .avatar{
  width:40px;height:40px;border-radius:50%;
  background:#ccc;margin-right:10px;
  background-size:cover;background-position:center;
  display:flex;align-items:center;justify-content:center;
  font-weight:bold;color:#fff;text-transform:uppercase;
}
.rf-widget-{{ section.id }} .icon{
  position:absolute;top:20px;right:20px;width:20px;
}
.rf-widget-{{ section.id }} .review-text .content{
  display:-webkit-box;
  -webkit-line-clamp:4;
  -webkit-box-orient:vertical;
  overflow:hidden;
}
.rf-widget-{{ section.id }} .review-text.expanded .content{
  -webkit-line-clamp:unset;
}
.rf-widget-{{ section.id }} .toggle-btn{
  display:none;margin-top:5px;
  color:#0066cc;font-weight:bold;cursor:pointer;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function(){
  const widget = document.querySelector(".rf-widget-{{ section.id }}");
  widget.querySelectorAll(".review-text").forEach(function(el){
    const content = el.querySelector(".content");
    const btn = el.querySelector(".toggle-btn");
    if(content.scrollHeight > content.clientHeight){
      btn.style.display = "inline-block";
    }
    btn.addEventListener("click", function(){
      el.classList.toggle("expanded");
      btn.textContent = el.classList.contains("expanded") ? "Less" : "Read more";
    });
  });
});
</script>