Skip to main content
The infiniteHits widget displays search results with infinite scrolling or “Load more” buttons. It’s ideal for creating engaging, continuous browsing experiences.

Usage

const infiniteHits = instantsearch.widgets.infiniteHits({
  container: '#infinite-hits',
  templates: {
    item: `
      <div>
        <h2>{{name}}</h2>
        <p>{{description}}</p>
      </div>
    `,
  },
});

search.addWidget(infiniteHits);

Examples

Basic Infinite Hits

instantsearch.widgets.infiniteHits({
  container: '#infinite-hits',
  templates: {
    item: (hit, { html, components }) => html`
      <article>
        <img src="${hit.image}" alt="${hit.name}" />
        <h3>${components.Highlight({ hit, attribute: 'name' })}</h3>
        <p>$${hit.price}</p>
      </article>
    `,
  },
});

With Show Previous Button

instantsearch.widgets.infiniteHits({
  container: '#infinite-hits',
  showPrevious: true,
  templates: {
    showPreviousText: 'Show previous results',
    showMoreText: 'Load more results',
  },
});

With Caching

const sessionStorageCache = {
  read({ state }) {
    return JSON.parse(
      window.sessionStorage.getItem(
        `ais.infiniteHits.${state.index}.${state.page}`
      )
    );
  },
  write({ state, hits }) {
    window.sessionStorage.setItem(
      `ais.infiniteHits.${state.index}.${state.page}`,
      JSON.stringify(hits)
    );
  },
};

instantsearch.widgets.infiniteHits({
  container: '#infinite-hits',
  cache: sessionStorageCache,
});

Options

container
string | HTMLElement
required
CSS Selector or HTMLElement to insert the widget.
escapeHTML
boolean
default:"true"
Whether to escape HTML entities in the hits.
transformItems
function
Function to transform the items before rendering.
(items: object[]) => object[]
showPrevious
boolean
default:"false"
Whether to display a “Show previous” button to load previous results.
cache
object
Reads and writes hits from/to cache. Helps restore scroll position when users navigate back.
{
  read: ({ state }) => hits[],
  write: ({ state, hits }) => void
}
templates
object
Templates to customize the widget rendering.
cssClasses
object
CSS classes to add to the widget elements.

HTML Output

<div class="ais-InfiniteHits">
  <button class="ais-InfiniteHits-loadPrevious">
    Show previous results
  </button>
  <ol class="ais-InfiniteHits-list">
    <li class="ais-InfiniteHits-item">
      <!-- Your item template -->
    </li>
    <!-- More items... -->
  </ol>
  <button class="ais-InfiniteHits-loadMore">
    Show more results
  </button>
</div>

Automatic Infinite Scrolling

To trigger automatic loading when scrolling to the bottom:
const infiniteHits = instantsearch.widgets.infiniteHits({
  container: '#infinite-hits',
});

// Get the showMore function from the widget
const showMore = () => {
  const button = document.querySelector('.ais-InfiniteHits-loadMore');
  if (button && !button.disabled) {
    button.click();
  }
};

// Trigger on scroll
window.addEventListener('scroll', () => {
  const scrollTop = window.scrollY;
  const windowHeight = window.innerHeight;
  const documentHeight = document.documentElement.scrollHeight;
  
  if (scrollTop + windowHeight >= documentHeight - 100) {
    showMore();
  }
});

Build docs developers (and LLMs) love