infinite scrolling using the section rendering API on main-collection-product-grid Dawn theme

Topic summary

A developer implemented infinite scrolling on a Shopify Dawn theme collection page using the Section Rendering API. The implementation works initially but breaks after applying or removing product filters, requiring a page refresh to function again.

Technical Implementation:

  • Uses IntersectionObserver to detect when users reach the bottom of the product grid
  • Fetches additional products via the Section Rendering API with pagination
  • Includes logic to stop loading when “No products found” is detected

Core Problem:
The infinite scroll functionality fails to persist after filter interactions, suggesting the event listeners or observers aren’t being properly reinitialized when the DOM updates from filtering actions.

Current Status:
The issue remains unresolved. A second user encountered the same problem, indicating this may be a common challenge when combining Dawn’s filtering system with custom infinite scroll implementations.

Summarized with AI on November 2. AI used: claude-sonnet-4-5-20250929.

I implemented infinite scrolling using the section rendering API on “main-collection-product-grid”. How can I fix the issue where it stops working after adding or removing a filter, and only works again after refreshing the page?

Here is script and html

    {%- render 'loading-spinner',class:"loading__spinner" -%}

document.addEventListener('DOMContentLoaded', function() {
  let currentPage = 1;
  const productGrid = document.getElementById('product-grid');
  const loader = document.getElementById('infinite-scroll-loader');
  const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      loadMoreProducts();
    }
  }, { threshold: 1.0 });

  function loadMoreProducts() {
    currentPage++;
    loader.style.display = 'block';
    const url = `${window.location.pathname}?section_id=main-collection-product-grid&page=${currentPage}`;

    fetch(url)
      .then(response => response.text())
      .then((responseText) => {
        const parser = new DOMParser();
        const htmlDocument = parser.parseFromString(responseText, 'text/html');
        const newProducts = htmlDocument.getElementById('product-grid').innerHTML;
         // Check if the response contains "No products found"
        if (newProducts.includes("No products found")) {
          loader.style.display = 'none';
          observer.disconnect(); // Stop the observer
          return;
        }

        productGrid.insertAdjacentHTML('beforeend', newProducts);
        loader.style.display = 'none';

        // Re-observe the last product to continue infinite scrolling
        observer.observe(productGrid.lastElementChild);
      })
      .catch((error) => {
        console.error('Error loading more products:', error);
        loader.style.display = 'none';
      });
  }

  // Observe the last product initially
  observer.observe(productGrid.lastElementChild);
});

Hit a similar issue, did you ever find an answer?