How To Add Recent Sales Popup in Shopify [Free – No App]

Create a new section file called recent-sales-popup.liquid and add the following code:

{% assign wsp_section_id = section.id | replace: '-', '' | downcase %}

{% style %}
  .wsp-recent-purchase-popup-{{ wsp_section_id }} {
    position: fixed;
    bottom: 20px;
    left: 20px;
    background: {{ section.settings.popup_background_color }};
    border-radius: {{ section.settings.border_radius }}px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    padding: 16px;
    max-width: 320px;
    width: calc(100vw - 40px);
    z-index: 1000;
    transform: translateX(-100%);
    opacity: 0;
    transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    border: 1px solid {{ section.settings.border_color }};
  }

  .wsp-recent-purchase-popup-{{ wsp_section_id }}.show {
    transform: translateX(0);
    opacity: 1;
  }

  .wsp-recent-purchase-popup-header-{{ wsp_section_id }} {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
  }

  .wsp-recent-purchase-popup-icon-{{ wsp_section_id }} {
    width: 20px;
    height: 20px;
    color: {{ section.settings.accent_color }};
    flex-shrink: 0;
  }

  .wsp-recent-purchase-popup-title-{{ wsp_section_id }} {
    font-size: 14px;
    font-weight: 600;
    color: {{ section.settings.text_color }};
    margin: 0;
  }

  .wsp-recent-purchase-popup-content-{{ wsp_section_id }} {
    display: flex;
    gap: 12px;
    align-items: center;
  }

  .wsp-recent-purchase-popup-image-{{ wsp_section_id }} {
    width: 60px;
    height: 60px;
    border-radius: {{ section.settings.image_border_radius }}px;
    overflow: hidden;
    flex-shrink: 0;
  }

  .wsp-recent-purchase-popup-image-{{ wsp_section_id }} img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .wsp-recent-purchase-popup-image-placeholder-{{ wsp_section_id }} {
    width: 100%;
    height: 100%;
    background-color: #f4f4f4;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .wsp-recent-purchase-popup-image-placeholder-{{ wsp_section_id }} svg {
    width: 30px;
    height: 30px;
    color: #999;
  }

  .wsp-recent-purchase-popup-details-{{ wsp_section_id }} {
    flex-grow: 1;
    min-width: 0;
  }

  .wsp-recent-purchase-popup-customer-{{ wsp_section_id }} {
    font-size: 13px;
    color: {{ section.settings.customer_text_color }};
    margin: 0 0 4px 0;
    font-weight: 500;
  }

  .wsp-recent-purchase-popup-product-{{ wsp_section_id }} {
    font-size: 14px;
    color: {{ section.settings.text_color }};
    margin: 0 0 4px 0;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .wsp-recent-purchase-popup-time-{{ wsp_section_id }} {
    font-size: 12px;
    color: {{ section.settings.time_text_color }};
    margin: 0;
  }

  .wsp-recent-purchase-popup-close-{{ wsp_section_id }} {
    position: absolute;
    top: 8px;
    right: 8px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px;
    color: {{ section.settings.text_color }};
    opacity: 0.6;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .wsp-recent-purchase-popup-close-{{ wsp_section_id }}:hover {
    opacity: 1;
    background-color: rgba(0, 0, 0, 0.1);
  }

  .wsp-recent-purchase-popup-close-{{ wsp_section_id }} svg {
    width: 12px;
    height: 12px;
  }

  @media screen and (max-width: 768px) {
    .wsp-recent-purchase-popup-{{ wsp_section_id }} {
      bottom: 10px;
      left: 10px;
      max-width: 280px;
      width: calc(100vw - 20px);
    }
  }

  .wsp-recent-purchase-popup-{{ wsp_section_id }},
  .wsp-recent-purchase-popup-container-{{ wsp_section_id }}{
    z-index: 999 !important;
  }
{% endstyle %}

<recent-purchase-popup-{{ wsp_section_id }}
  class="wsp-recent-purchase-popup-container-{{ wsp_section_id }}"
  data-show-interval="{{ section.settings.show_interval }}"
  data-display-duration="{{ section.settings.display_duration }}"
  {{ section.shopify_attributes }}
>
  <div class="wsp-recent-purchase-popup-{{ wsp_section_id }}" id="wsp-recent-purchase-popup-{{ wsp_section_id }}">
    <button class="wsp-recent-purchase-popup-close-{{ wsp_section_id }}" aria-label="Close notification">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <line x1="18" y1="6" x2="6" y2="18"></line>
        <line x1="6" y1="6" x2="18" y2="18"></line>
      </svg>
    </button>

    <div class="wsp-recent-purchase-popup-header-{{ wsp_section_id }}">
      <svg class="wsp-recent-purchase-popup-icon-{{ wsp_section_id }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <circle cx="9" cy="21" r="1"></circle>
        <circle cx="20" cy="21" r="1"></circle>
        <path d="m1 1 4 4 2.5 11h9.5"></path>
      </svg>
      <h3 class="wsp-recent-purchase-popup-title-{{ wsp_section_id }}">{{ section.settings.popup_title }}</h3>
    </div>

    <div class="wsp-recent-purchase-popup-content-{{ wsp_section_id }}">
      <div class="wsp-recent-purchase-popup-image-{{ wsp_section_id }}">
        <div class="wsp-recent-purchase-popup-image-placeholder-{{ wsp_section_id }}">
          {{ 'product-1' | placeholder_svg_tag }}
        </div>
      </div>
      <div class="wsp-recent-purchase-popup-details-{{ wsp_section_id }}">
        <p class="wsp-recent-purchase-popup-customer-{{ wsp_section_id }}"></p>
        <p class="wsp-recent-purchase-popup-product-{{ wsp_section_id }}"></p>
        <p class="wsp-recent-purchase-popup-time-{{ wsp_section_id }}"></p>
      </div>
    </div>
  </div>
</recent-purchase-popup-{{ wsp_section_id }}>

<script>
  (function() {
    class RecentPurchasePopup{{ wsp_section_id }} extends HTMLElement {
      constructor() {
        super();
        this.products = [];
        this.currentIndex = 0;
        this.showInterval = parseInt(this.dataset.showInterval) * 1000;
        this.displayDuration = parseInt(this.dataset.displayDuration) * 1000;
        this.popup = this.querySelector('#wsp-recent-purchase-popup-{{ wsp_section_id }}');
        this.isVisible = false;
        this.timeoutId = null;
        this.intervalId = null;
      }

      connectedCallback() {
        this.loadProducts();
        this.setupEventListeners();
        this.startCycle();
      }

      disconnectedCallback() {
        if (this.timeoutId) clearTimeout(this.timeoutId);
        if (this.intervalId) clearInterval(this.intervalId);
      }

      loadProducts() {
        {% for i in (1..10) %}
          {% liquid
            assign product_key = 'product_' | append: i
            assign customer_key = 'customer_name_' | append: i
            assign product = section.settings[product_key]
            assign customer_name = section.settings[customer_key]
          %}
          
          {% if product != blank and customer_name != blank %}
            this.products.push({
              id: {{ product.id }},
              title: {{ product.title | json }},
              image: {% if product.featured_image %}{{ product.featured_image | image_url: width: 120 | json }}{% else %}null{% endif %},
              customerName: {{ customer_name | json }},
              url: {{ product.url | json }}
            });
          {% endif %}
        {% endfor %}
      }

      setupEventListeners() {
        const closeButton = this.popup.querySelector('.wsp-recent-purchase-popup-close-{{ wsp_section_id }}');
        closeButton.addEventListener('click', () => {
          this.hidePopup();
        });

        this.popup.addEventListener('click', (e) => {
          if (!e.target.closest('.wsp-recent-purchase-popup-close-{{ wsp_section_id }}')) {
            const currentProduct = this.products[this.currentIndex];
            if (currentProduct && currentProduct.url) {
              window.location.href = currentProduct.url;
            }
          }
        });
      }

      startCycle() {
        if (this.products.length === 0) return;

        this.showPopup();
        
        this.intervalId = setInterval(() => {
          this.showPopup();
        }, this.showInterval);
      }

      showPopup() {
        if (this.products.length === 0 || this.isVisible) return;

        const product = this.products[this.currentIndex];
        this.updatePopupContent(product);
        
        this.popup.classList.add('show');
        this.isVisible = true;

        this.timeoutId = setTimeout(() => {
          this.hidePopup();
        }, this.displayDuration);

        this.currentIndex = (this.currentIndex + 1) % this.products.length;
      }

      hidePopup() {
        this.popup.classList.remove('show');
        this.isVisible = false;
        if (this.timeoutId) {
          clearTimeout(this.timeoutId);
          this.timeoutId = null;
        }
      }

      updatePopupContent(product) {
        const imageContainer = this.popup.querySelector('.wsp-recent-purchase-popup-image-{{ wsp_section_id }}');
        const customerElement = this.popup.querySelector('.wsp-recent-purchase-popup-customer-{{ wsp_section_id }}');
        const productElement = this.popup.querySelector('.wsp-recent-purchase-popup-product-{{ wsp_section_id }}');
        const timeElement = this.popup.querySelector('.wsp-recent-purchase-popup-time-{{ wsp_section_id }}');

        if (product.image) {
          imageContainer.innerHTML = `<img src="${product.image}" alt="${product.title}" loading="lazy">`;
        } else {
          imageContainer.innerHTML = `
            <div class="wsp-recent-purchase-popup-image-placeholder-{{ wsp_section_id }}">
              {{ 'product-1' | placeholder_svg_tag }}
            </div>
          `;
        }

        customerElement.textContent = product.customerName;
        productElement.textContent = product.title;
        
        const randomMinutes = Math.floor(Math.random() * 30) + 1;
        timeElement.textContent = `${randomMinutes} minute${randomMinutes === 1 ? '' : 's'} ago`;
      }
    }

    customElements.define('recent-purchase-popup-{{ wsp_section_id }}', RecentPurchasePopup{{ wsp_section_id }});
  })();
</script>

{% schema %}
{
  "name": "Recent Purchase Popup",
  "settings": [
    {
      "type": "header",
      "content": "General Settings"
    },
    {
      "type": "text",
      "id": "popup_title",
      "label": "Popup title",
      "default": "Recently purchased"
    },
    {
      "type": "range",
      "id": "show_interval",
      "min": 10,
      "max": 120,
      "step": 5,
      "unit": "s",
      "label": "Show interval",
      "default": 30
    },
    {
      "type": "range",
      "id": "display_duration",
      "min": 3,
      "max": 15,
      "step": 1,
      "unit": "s",
      "label": "Display duration",
      "default": 6
    },
    {
      "type": "header",
      "content": "Style Settings"
    },
    {
      "type": "color",
      "id": "popup_background_color",
      "label": "Background color",
      "default": "#ffffff"
    },
    {
      "type": "color",
      "id": "border_color",
      "label": "Border color",
      "default": "#e6e6e6"
    },
    {
      "type": "color",
      "id": "text_color",
      "label": "Text color",
      "default": "#000000"
    },
    {
      "type": "color",
      "id": "customer_text_color",
      "label": "Customer name color",
      "default": "#666666"
    },
    {
      "type": "color",
      "id": "time_text_color",
      "label": "Time text color",
      "default": "#999999"
    },
    {
      "type": "color",
      "id": "accent_color",
      "label": "Accent color",
      "default": "#000f9f"
    },
    {
      "type": "range",
      "id": "border_radius",
      "min": 0,
      "max": 20,
      "step": 2,
      "unit": "px",
      "label": "Border radius",
      "default": 8
    },
    {
      "type": "range",
      "id": "image_border_radius",
      "min": 0,
      "max": 20,
      "step": 2,
      "unit": "px",
      "label": "Image border radius",
      "default": 6
    },
    {
      "type": "header",
      "content": "Product 1"
    },
    {
      "type": "product",
      "id": "product_1",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_1",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 2"
    },
    {
      "type": "product",
      "id": "product_2",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_2",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 3"
    },
    {
      "type": "product",
      "id": "product_3",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_3",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 4"
    },
    {
      "type": "product",
      "id": "product_4",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_4",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 5"
    },
    {
      "type": "product",
      "id": "product_5",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_5",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 6"
    },
    {
      "type": "product",
      "id": "product_6",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_6",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 7"
    },
    {
      "type": "product",
      "id": "product_7",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_7",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 8"
    },
    {
      "type": "product",
      "id": "product_8",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_8",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 9"
    },
    {
      "type": "product",
      "id": "product_9",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_9",
      "label": "Customer name"
    },
    {
      "type": "header",
      "content": "Product 10"
    },
    {
      "type": "product",
      "id": "product_10",
      "label": "Product"
    },
    {
      "type": "text",
      "id": "customer_name_10",
      "label": "Customer name"
    }
  ],
  "presets": [
    {
      "name": "Recent Sales Popup"
    }
  ]
}
{% endschema %}
Vote Here

About

Leave a Comment

Your email address will not be published. Required fields are marked *