Pagination is a common method for displaying large sets of data in manageable chunks. However, “Load More” functionality provides a seamless and user-friendly experience, allowing users to fetch more products without reloading the page. In this blog post, we’ll explore how to implement a “Load More” button in Shopify using JavaScript and Liquid.

Why Use a “Load More” Button Instead of Pagination?

  1. Improved User Experience – Users can browse content smoothly without navigating through multiple pages.
  2. Faster Interaction – AJAX-based loading eliminates page reloads, making browsing quicker.
  3. Modern Design Trend – Many eCommerce websites prefer this method to enhance engagement.
<div class="h-[200px] bg-black">
  <div class="max-w-7xl mx-auto flex items-end h-full">
    <div class="p-6">
      <h1 class="text-white text-2xl md:text-4xl">{{ collection.title }}</h1>
      <a href="/" class="text-white text-lg md:text-2xl">Home</a>
    </div>
  </div>
</div>
<div id="ProductGridContainer">
  {% paginate collection.products by section.settings.number_of_products_per_page %}
    <div
      class="max-w-7xl mx-auto p-2 py-10"
      x-data="
        {
            sort: '{{ sort_by }}',
            sorting(){
                fetch('/collections/{{ collection.handle }}?sort_by='  +this.sort)
                .then(response => response.text())
                .then(data=>{
                    let newElement = document.createElement('div');
                    newElement.innerHTML = data;
                    let newHTML = newElement.querySelector('#ProductGridContainer').innerHTML;

                    document.querySelector('#ProductGridContainer').innerHTML = newHTML;

                    history.replaceState(null,null, '?sort_by='+ this.sort)
                })
                .catch(error => sonsole.log(error))
            }
        }
      "
    >
      {% if section.settings.enable_sorting %}
        <select
          name=""
          id=""
          x-model="sort"
          @change="sorting()"
          class="py-3 px-4 border bg-gray-100 rounded-sm cursor-pointer mb-8"
        >
          {% for option in collection.sort_options %}
            <option
              value="{{ option.value }}"
              {%- if option.valeu == sort_by -%}
                selected
              {%- endif -%}
            >
              {{ option.name }}
            </option>
          {% endfor %}
        </select>
      {% endif %}
      <div
        class="load-more"
        x-data="
          {
            page: 1,
            hasMoreProducts: true,
            loading: false,
            async loadMore(){
              this.loading = true;
              this.page++;
              const response = await fetch(`{{ collection.url }}?page=${this.page}`);
              const text = await response.text();
              const html = new DOMParser().parseFromString(text,'text/html');
              const newHTML = html.querySelectorAll('#product-grid > *');
              if(newHTML.length > 0){
                newHTML.forEach(product => document.querySelector('#product-grid').appendChild(product) )
              }
               totalPages = parseInt(document.getElementById('totalPages').value);
               if(this.page >= totalPages){
                this.hasMoreProducts = false;
              }
              this.loading = false;
            }

          }
        "
      >
        <input type="hidden" id="totalPages" value="{{ paginate.pages }}">
        {% render 'loader' %}
        <div class="grid grid-cols-2 md:grid-cols-4 gap-4" id="product-grid">
          {% for product in collection.products %}
            {% render 'product-card', productCard: product %}
          {% endfor %}
        </div>

        {% if collection.all_products_count > section.settings.number_of_products_per_page %}
          <button
            x-show="hasMoreProducts"
            @click="loadMore()"
            class="bg-black text-white w-64 p-3 rounded-md flex justify-center items-center mt-10 mx-auto"
          >
            Load More
          </button>
        {% endif %}
      </div>

      {% comment %} {% render 'pagination', pagination: paginate %} {% endcomment %}
    </div>
  {% endpaginate %}
</div>
{% schema %}
{
  "name": "Collection Page",
  "settings": [
    {
      "type": "number",
      "id": "number_of_products_per_page",
      "label": "Number of products per page",
      "default": 8
    },
    {
      "type": "checkbox",
      "id": "enable_sorting",
      "label": "Enable sorting",
      "default": false
    }
  ]
}
{% endschema %}