← Go back

Shopify Product Showcase – Feature-Rich Product Grid & Slider

Shopify Product Showcase – Feature-Rich Product Grid & Slider

Add a versatile product showcase to your Shopify store with customizable product cards, ratings, quantity selectors, and add-to-cart functionality. Features responsive design with desktop grid and mobile slider views.

Preview Password = 1 *When you first time enter them back again then click agian Preview to show*
Liquid Code
                    <!-- 
========================================
Section Name: Product Showcase
Tech Stack: Liquid, HTML, CSS, JavaScript, Swiper.js
What This Section Does: 
- Displays a customizable grid of product cards with detailed information and functionality.
- Features product badges, ratings, pricing with compare-at options, and shipping information.
- Includes quantity selectors with dynamic price updates and direct add-to-cart functionality.
- Fully responsive with desktop grid and mobile swiper layouts for optimal viewing experience.

Promotion: 
Enhance your Shopify store with a professional product showcase section. Highlight featured products with rich details and seamless shopping experience. Get it now at [PrebuiltTemplates](https://prebuilttemplates.com/).
========================================
-->
{% comment %}
  Section: Custom Product Showcase 
  A grid of selected products with dynamic data rendering and mobile swiper
{% endcomment %}

<section class="product-showcase-section-{{ section.id }}" style="background-color: {{ section.settings.bg_color }}; padding: {{ section.settings.pad_top }}px 0 {{ section.settings.pad_bot }}px;">
  <div class="product-showcase-container page-width">
    {% if section.settings.title != blank %}
      <h2 class="product-showcase-heading">{{ section.settings.title }}</h2>
    {% endif %}
    
    {% if section.settings.description != blank %}
      <div class="product-showcase-description">{{ section.settings.description }}</div>
    {% endif %}

    <!-- Desktop/Tablet View -->
    <div class="product-showcase-grid desktop-grid" style="grid-template-columns: repeat({{ section.settings.columns_desktop }}, 1fr);">
      {% for block in section.blocks %}
        {% if block.type == 'product' %}
          {% assign product = all_products[block.settings.product] %}
          {% if product != blank %}
            {% assign current_variant = product.selected_or_first_available_variant %}
            
            <div class="product-showcase-item" {{ block.shopify_attributes }}>
              <div class="product-showcase-card">
                {% if block.settings.show_badge %}
                  <div class="product-badge" style="background-color: {{ block.settings.badge_color }};">
                    <span>{{ block.settings.badge_text }}</span>
                  </div>
                {% endif %}
                
                <div class="product-showcase-images">
                  <a href="{{ product.url }}" class="product-image-link">
                    {% if product.featured_image != blank %}
                      <img class="product-showcase-image" 
                           src="{{ product.featured_image | img_url: 'medium' }}" 
                           alt="{{ product.featured_image.alt | default: product.title | escape }}">
                    {% else %}
                      {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }}
                    {% endif %}
                  </a>
                </div>
                
                <div class="product-showcase-info">
                  <p class="product-vendor">{{ product.vendor }}</p>
                  
                  <h3 class="product-showcase-title">
                    <a href="{{ product.url }}">{{ product.title }}</a>
                  </h3>
                  
                  <p class="product-showcase-description">
                    {{ product.description | strip_html | truncatewords: 15 }}
                  </p>
                  
                  <div class="product-showcase-rating" style="--rating: {{ block.settings.rating }};">
                    <div class="rating-stars">
                      <span>★★★★★</span>
                    </div>
                    <span class="rating-count">{{ block.settings.review_count }} Reviews</span>
                  </div>
                  
                  <div class="product-showcase-pricing" data-price="{{ current_variant.price | divided_by: 100.00 }}">
                    {% if current_variant.compare_at_price > current_variant.price %}
                      <span class="product-showcase-price-old">${{ current_variant.compare_at_price | divided_by: 100.00 }}</span>
                    {% endif %}
                    
                    <span class="product-showcase-price">${{ current_variant.price | divided_by: 100.00 }}</span>
                  </div>
                  
                  {% if block.settings.show_free_shipping %}
                    <p class="product-showcase-shipping">{{ block.settings.shipping_text }}</p>
                  {% endif %}
                  
                  <form method="post" action="/cart/add" id="product-form-{{ product.id }}-{{ section.id }}" accept-charset="UTF-8" class="product-form" enctype="multipart/form-data">
                    <input type="hidden" name="id" value="{{ current_variant.id }}">
                    
                    <div class="product-showcase-actions">
                      <div class="quantity-selector">
                        <button type="button" class="quantity-button minus" aria-label="Decrease quantity">−</button>
                        <input type="number" name="quantity" value="1" min="1" class="quantity-input" pattern="[0-9]*">
                        <button type="button" class="quantity-button plus" aria-label="Increase quantity">+</button>
                      </div>
                      
                      <button type="submit" name="add" class="add-to-cart-button" style="background-color: {{ section.settings.button_color }}; color: {{ section.settings.button_text_color }};">
                        {{ section.settings.button_text }}
                      </button>
                    </div>
                  </form>
                </div>
              </div>
            </div>
          {% else %}
            <div class="product-showcase-item" {{ block.shopify_attributes }}>
              <div class="product-showcase-card product-placeholder">
                <div class="product-showcase-images">
                  {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }}
                </div>
                <div class="product-showcase-info">
                  <p class="product-vendor">Vendor Name</p>
                  <h3 class="product-showcase-title">Product Title</h3>
                  <p class="product-showcase-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vitae fermentum metus.</p>
                </div>
              </div>
            </div>
          {% endif %}
        {% endif %}
      {% endfor %}
    </div>

    <!-- Mobile Swiper View -->
    <div class="product-showcase-swiper mobile-swiper">
      <div class="swiper-wrapper">
        {% for block in section.blocks %}
          {% if block.type == 'product' %}
            {% assign product = all_products[block.settings.product] %}
            {% if product != blank %}
              {% assign current_variant = product.selected_or_first_available_variant %}
              
              <div class="swiper-slide" {{ block.shopify_attributes }}>
                <div class="product-showcase-card">
                  {% if block.settings.show_badge %}
                    <div class="product-badge" style="background-color: {{ block.settings.badge_color }};">
                      <span>{{ block.settings.badge_text }}</span>
                    </div>
                  {% endif %}
                  
                  <div class="product-showcase-images">
                    <a href="{{ product.url }}" class="product-image-link">
                      {% if product.featured_image != blank %}
                        <img class="product-showcase-image" 
                             src="{{ product.featured_image | img_url: 'medium' }}" 
                             alt="{{ product.featured_image.alt | default: product.title | escape }}">
                      {% else %}
                        {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }}
                      {% endif %}
                    </a>
                  </div>
                  
                  <div class="product-showcase-info">
                    <p class="product-vendor">{{ product.vendor }}</p>
                    
                    <h3 class="product-showcase-title">
                      <a href="{{ product.url }}">{{ product.title }}</a>
                    </h3>
                    
                    <p class="product-showcase-description">
                      {{ product.description | strip_html | truncatewords: 15 }}
                    </p>
                    
                    <div class="product-showcase-rating" style="--rating: {{ block.settings.rating }};">
                      <div class="rating-stars">
                        <span>★★★★★</span>
                      </div>
                      <span class="rating-count">{{ block.settings.review_count }} Reviews</span>
                    </div>
                    
                    <div class="product-showcase-pricing" data-price="{{ current_variant.price | divided_by: 100.00 }}">
                      {% if current_variant.compare_at_price > current_variant.price %}
                        <span class="product-showcase-price-old">${{ current_variant.compare_at_price | divided_by: 100.00 }}</span>
                      {% endif %}
                      
                      <span class="product-showcase-price">${{ current_variant.price | divided_by: 100.00 }}</span>
                    </div>
                    
                    {% if block.settings.show_free_shipping %}
                      <p class="product-showcase-shipping">{{ block.settings.shipping_text }}</p>
                    {% endif %}
                    
                    <form method="post" action="/cart/add" id="product-form-mobile-{{ product.id }}-{{ section.id }}" accept-charset="UTF-8" class="product-form" enctype="multipart/form-data">
                      <input type="hidden" name="id" value="{{ current_variant.id }}">
                      
                      <div class="product-showcase-actions">
                        <div class="quantity-selector">
                          <button type="button" class="quantity-button minus" aria-label="Decrease quantity">−</button>
                          <input type="number" name="quantity" value="1" min="1" class="quantity-input" pattern="[0-9]*">
                          <button type="button" class="quantity-button plus" aria-label="Increase quantity">+</button>
                        </div>
                        
                        <button type="submit" name="add" class="add-to-cart-button" style="background-color: {{ section.settings.button_color }}; color: {{ section.settings.button_text_color }};">
                          {{ section.settings.button_text }}
                        </button>
                      </div>
                    </form>
                  </div>
                </div>
              </div>
            {% else %}
              <div class="swiper-slide" {{ block.shopify_attributes }}>
                <div class="product-showcase-card product-placeholder">
                  <div class="product-showcase-images">
                    {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }}
                  </div>
                  <div class="product-showcase-info">
                    <p class="product-vendor">Vendor Name</p>
                    <h3 class="product-showcase-title">Product Title</h3>
                    <p class="product-showcase-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vitae fermentum metus.</p>
                  </div>
                </div>
              </div>
            {% endif %}
          {% endif %}
        {% endfor %}
      </div>
      <div class="swiper-pagination"></div>
    </div>
  </div>
</section>

{% style %}
.product-showcase-section-{{ section.id }} {
  overflow: hidden;
}

.product-showcase-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 20px;
}

.product-showcase-heading {
  font-size: 30px;
  margin-bottom: 15px;
  text-align: center;
}

.product-showcase-description {
  max-width: 800px;
  margin: 0 auto 40px;
  text-align: center;
}

.product-showcase-grid {
  display: grid;
  gap: 30px;
}

.product-showcase-item {
  transition: transform 0.3s ease;
}

.product-showcase-item:hover {
  transform: translateY(-8px);
}

.product-showcase-card {
  background-color: {{ section.settings.card_bg_color }};
  border-radius: 12px;
  overflow: hidden;
  position: relative;
  box-shadow: 0 5px 15px rgba(0,0,0,0.05);
  padding: 30px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.product-placeholder {
  opacity: 0.7;
}

.product-badge {
  position: absolute;
  top: 20px;
  left: 20px;
  background-color: #009688;
  color: white;
  border-radius: 50%;
  width: 60px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 14px;
  z-index: 2;
}

.product-showcase-images {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

.product-image-link {
  display: block;
  text-align: center;
  overflow: hidden;
}

.product-showcase-image,
.product-showcase-placeholder {
  max-width: 100%;
  height: auto;
  transition: transform 0.5s ease;
}

.product-image-link:hover .product-showcase-image {
  transform: scale(1.05);
}

.product-vendor {
  font-size: 14px;
  color: #666;
  margin-bottom: 5px;
  text-transform: uppercase;
}

.product-showcase-title {
  font-size: 24px;
  margin: 0 0 10px;
  font-weight: 700;
  color: #333;
}

.product-showcase-title a {
  color: inherit;
  text-decoration: none;
}

.product-showcase-description {
  font-size: 16px;
  color: #666;
  margin-bottom: 15px;
  line-height: 1.5;
  text-align: center;
}

.product-showcase-rating {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 15px;
}

.rating-stars {
  position: relative;
  display: inline-block;
  color: #ddd;
  font-size: 18px;
}

.rating-stars::before {
  content: '★★★★★';
  position: absolute;
  top: 0;
  left: 0;
  color: #009688;
  width: calc(var(--rating) * 20%);
  overflow: hidden;
}

.rating-count {
  font-size: 14px;
  color: #666;
}

.product-showcase-pricing {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.product-showcase-price-old {
  text-decoration: line-through;
  color: #999;
  font-size: 16px;
}

.product-showcase-price {
  font-size: 24px;
  font-weight: 600;
  color: #333;
}

.product-showcase-shipping {
  font-size: 14px;
  color: #666;
  margin-bottom: 20px;
}

.product-showcase-actions {
  display: flex;
  flex-direction: column;
  gap: 15px;
  margin-top: auto;
}

.quantity-selector {
  display: flex;
  align-items: center;
  border: 1px solid #e0e0e0;
  border-radius: 30px;
  overflow: hidden;
  width: 100%;
}

.quantity-button {
  background: none;
  border: none;
  width: 40px;
  font-size: 18px;
  cursor: pointer;
  padding: 10px 0;
  color: #333;
}

.quantity-input {
  border: none;
  text-align: center;
  flex-grow: 1;
  padding: 12px 0;
  font-size: 16px;
  -moz-appearance: textfield;
}

.quantity-input::-webkit-inner-spin-button, 
.quantity-input::-webkit-outer-spin-button { 
  -webkit-appearance: none;
  margin: 0;
}

.add-to-cart-button {
  border: none;
  border-radius: 30px;
  padding: 15px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.2s ease;
  text-transform: uppercase;
  width: 100%;
}

.add-to-cart-button:hover {
  opacity: 0.9;
}

.product-form {
  width: 100%;
}

/* Swiper Styles */
.product-showcase-swiper {
  width: 100%;
  padding-bottom: 50px;
  display: none;
}

.swiper-slide {
  height: auto;
}

.swiper-pagination {
  bottom: 0;
}

.swiper-pagination-bullet-active {
  background-color: #009688;
}

@media screen and (max-width: 989px) {
  .product-showcase-grid {
    grid-template-columns: repeat({{ section.settings.columns_tablet }}, 1fr);
  }
}

@media screen and (max-width: 749px) {
  .desktop-grid {
    display: none;
  }
  
  .mobile-swiper {
    display: block;
  }
  
  .product-showcase-card {
    padding: 20px;
  }
}
{% endstyle %}

<!-- Include Swiper JS -->
<script src="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.css" />

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Initialize Swiper for mobile
    if (window.innerWidth <= 749) {
      const swiper = new Swiper('.product-showcase-swiper', {
        slidesPerView: {{ section.settings.columns_mobile }},
        spaceBetween: 20,
        pagination: {
          el: '.swiper-pagination',
          clickable: true,
        },
        breakpoints: {
          320: {
            slidesPerView: 1,
          },
          480: {
            slidesPerView: Math.min(2, {{ section.settings.columns_mobile }}),
          },
          640: {
            slidesPerView: {{ section.settings.columns_mobile }},
          }
        }
      });
    }
    
    // Quantity selector functionality for all products
    const quantitySelectors = document.querySelectorAll('.quantity-selector');
    
    quantitySelectors.forEach(function(selector) {
      const minusButton = selector.querySelector('.minus');
      const plusButton = selector.querySelector('.plus');
      const input = selector.querySelector('.quantity-input');
      
      // Update price based on quantity
      function updatePrice() {
        const form = selector.closest('.product-form');
        const priceContainer = form.parentNode.querySelector('.product-showcase-pricing');
        const priceDisplay = priceContainer.querySelector('.product-showcase-price');
        const basePrice = parseFloat(priceContainer.getAttribute('data-price'));
        const quantity = parseInt(input.value, 10);
        
        const totalPrice = (basePrice * quantity).toFixed(2);
        priceDisplay.textContent = '$' + totalPrice;
      }
      
      minusButton.addEventListener('click', function() {
        const currentValue = parseInt(input.value, 10);
        if (currentValue > 1) {
          input.value = currentValue - 1;
          updatePrice();
        }
      });
      
      plusButton.addEventListener('click', function() {
        const currentValue = parseInt(input.value, 10);
        input.value = currentValue + 1;
        updatePrice();
      });
      
      input.addEventListener('change', function() {
        if (this.value < 1) {
          this.value = 1;
        }
        updatePrice();
      });
    });
    
    // Handle window resize for responsive swiper
    window.addEventListener('resize', function() {
      if (window.innerWidth <= 749) {
        if (!document.querySelector('.swiper-initialized')) {
          const swiper = new Swiper('.product-showcase-swiper', {
            slidesPerView: {{ section.settings.columns_mobile }},
            spaceBetween: 20,
            pagination: {
              el: '.swiper-pagination',
              clickable: true,
            },
            breakpoints: {
              320: {
                slidesPerView: 1,
              },
              480: {
                slidesPerView: Math.min(2, {{ section.settings.columns_mobile }}),
              },
              640: {
                slidesPerView: {{ section.settings.columns_mobile }},
              }
            }
          });
        }
      }
    });
  });
</script>

{% schema %}
{
  "name": "Product Showcase",
  "settings": [
    {
      "type": "range",
      "id": "pad_top",
      "label": "Padding Top",
      "min": 0,
      "max": 100,
      "step": 5,
      "default": 40
    },
    {
      "type": "range",
      "id": "pad_bot",
      "label": "Padding Bottom",
      "min": 0,
      "max": 100,
      "step": 5,
      "default": 40
    },
    {
      "type": "color",
      "id": "bg_color",
      "label": "Background Color",
      "default": "#f8f8f8"
    },
    {
      "type": "color", 
      "id": "card_bg_color",
      "label": "Card Background Color",
      "default": "#FFFFFF"
    },
    {
      "type": "text",
      "id": "title",
      "label": "Section Title",
      "default": "Featured Products"
    },
    {
      "type": "richtext",
      "id": "description",
      "label": "Section Description",
      "default": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>"
    },
    {
      "type": "text",
      "id": "button_text",
      "label": "Add to Cart Button Text",
      "default": "ADD TO CART"
    },
    {
      "type": "color",
      "id": "button_color",
      "label": "Button Background Color",
      "default": "#000000"
    },
    {
      "type": "color",
      "id": "button_text_color",
      "label": "Button Text Color",
      "default": "#FFFFFF"
    },
    {
      "type": "header",
      "content": "Layout"
    },
    {
      "type": "range",
      "id": "columns_desktop",
      "label": "Columns (Desktop)",
      "min": 1,
      "max": 4,
      "step": 1,
      "default": 3
    },
    {
      "type": "range",
      "id": "columns_tablet",
      "label": "Columns (Tablet)",
      "min": 1,
      "max": 3,
      "step": 1,
      "default": 2
    },
    {
      "type": "range",
      "id": "columns_mobile",
      "label": "Columns (Mobile)",
      "min": 1,
      "max": 3,
      "step": 1,
      "default": 1
    }
  ],
  "blocks": [
    {
      "type": "product",
      "name": "Product",
      "settings": [
        {
          "type": "product",
          "id": "product",
          "label": "Product"
        },
        {
          "type": "checkbox",
          "id": "show_badge",
          "label": "Show Badge",
          "default": true
        },
        {
          "type": "text",
          "id": "badge_text",
          "label": "Badge Text",
          "default": "15% OFF"
        },
        {
          "type": "color",
          "id": "badge_color",
          "label": "Badge Color",
          "default": "#009688"
        },
        {
          "type": "range",
          "id": "rating",
          "min": 0,
          "max": 5,
          "step": 0.1,
          "default": 4.8,
          "label": "Product Rating"
        },
        {
          "type": "text",
          "id": "review_count",
          "label": "Review Count",
          "default": "42"
        },
        {
          "type": "checkbox",
          "id": "show_free_shipping",
          "label": "Show Shipping Info",
          "default": true
        },
        {
          "type": "text",
          "id": "shipping_text",
          "label": "Shipping Text",
          "default": "Free Oil + Free USA Shipping"
        }
      ]
    }
  ],
  "presets": [
    {
      "name": "Product Showcase",
      "blocks": [
        {
          "type": "product"
        },
        {
          "type": "product"
        },
        {
          "type": "product"
        }
      ]
    }
  ]
}
{% endschema %}