API Reference / Vue InstantSearch Widgets / ais-infinite-hits
Aug. 23, 2019

ais-infinite-hits

Widget signature
<ais-infinite-hits
  // Optional parameters
  :escapeHTML="boolean"
  :show-previous="boolean"
  :class-names="object"
  :transform-items="function"
/>

About this widget

The ais-infinite-hits widget is used to display a list of results with a “Show more” button.

To configure the number of hits to show, use the ais-hits-per-page widget or the ais-configure widget.

Examples

1
<ais-infinite-hits />

Props

escapeHTML
type: boolean
default: true
Optional

Whether to escape the raw HTML in the hits.

1
<ais-infinite-hits :escapeHTML="false" />
show-previous
type: boolean
default: false
Optional

Enable the button to load previous results.

The button is only displayed if the routing option is enabled in ais-instant-search and if the user is not on the first page. You can override this behavior by using slots.

1
<ais-infinite-hits :show-previous="true" />
class-names
type: object
default: {}
Optional

The CSS classes to override.

  • ais-InfiniteHits: the root element of the widget.
  • ais-InfiniteHits-list: the list of results.
  • ais-InfiniteHits-item: the list items.
  • ais-InfiniteHits-loadPrevious: the button to display previous results.
  • ais-InfiniteHits-loadMore: the button to display more results.
  • ais-InfiniteHits-loadPrevious--disabled: the disabled button to display previous results.
  • ais-InfiniteHits-loadMore--disabled: the disabled button to display more results.
1
2
3
4
5
6
7
<ais-infinite-hits
  :class-names="{
    'ais-InfiniteHits': 'MyCustomInfiniteHits',
    'ais-InfiniteHits-list': 'MyCustomInfiniteHitsList',
    // ...
  }"
/>
transform-items
type: function
default: x => x
Optional

Receives the items, and is called before displaying them. Should return a new array with the same shape as the original array. Useful for mapping over the items to transform, and remove or reorder them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
  <!-- ... -->
  <ais-infinite-hits :transform-items="transformItems" />
</template>

<script>
  export default {
    methods: {
      transformItems(items) {
        return items.map(item => ({
          ...item,
          name: item.name.toUpperCase(),
        }));
      },
    },
  };
</script>

Customize the UI

default

The slot to override the complete DOM output of the widget.

Scope

  • items: object[]: the records that matched the search.
  • refinePrevious: () =\> void: the function to load previous results.
  • refineNext: () =\> void: the function to load more results.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ais-infinite-hits>
  <ul slot-scope="{ items, refinePrevious, refineNext }">
    <li>
      <button @click="refinePrevious">
        Show previous results
      </button>
    </li>
    <li v-for="item in items" :key="item.objectID">
      {{ item.name }}
    </li>
    <li>
      <button @click="refineNext">
        Show more results
      </button>
    </li>
  </ul>
</ais-infinite-hits>
loadPrevious

The slot to override the DOM output of the “Show previous” button.

Scope

  • page: number: the value of the current page.
  • isFirstPage: boolean: whether it’s the first page.
  • refinePrevious: () =\> void: the function to load the previous page.
1
2
3
4
5
6
7
8
9
10
<ais-infinite-hits :show-previous="true">
  <button
    slot="loadPrevious"
    slot-scope="{ page, isFirstPage, refinePrevious }"
    :disabled="isFirstPage"
    @click="refinePrevious"
  >
    Show previous results (page: {{ page + 1 }})
  </button>
</ais-infinite-hits>
item

The slot to override the DOM output of the item.

Scope

  • items: object: a single hit with all its attribute.
  • index: number: the relative position of the hit in the list.
1
2
3
4
5
<ais-infinite-hits>
  <div slot="item" slot-scope="{ item, index }">
    {{ index }} - {{ item.name }}
  </div>
</ais-infinite-hits>
loadMore

The slot to override the DOM output of the “Show more” button.

Scope

  • page: number: the value of the current page.
  • isLastPage: boolean: whether it’s the last page.
  • refineNext: () =\> void: the function to load the next page.
1
2
3
4
5
6
7
8
9
10
<ais-infinite-hits>
  <button
    slot="loadMore"
    slot-scope="{ page, isLastPage, refineNext }"
    :disabled="isLastPage"
    @click="refineNext"
  >
    Show more results (page: {{ page + 1 }})
  </button>
</ais-infinite-hits>

HTML output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="ais-InfiniteHits">
  <button class="ais-InfiniteHits-loadPrevious">
    Show previous results
  </button>
  <ol class="ais-InfiniteHits-list">
    <li class="ais-InfiniteHits-item">
      ...
    </li>
    <li class="ais-InfiniteHits-item">
      ...
    </li>
    <li class="ais-InfiniteHits-item">
      ...
    </li>
  </ol>
  <button class="ais-InfiniteHits-loadMore">
    Show more results
  </button>
</div>

Sending Click and Conversion events

InstantSearch can connect with the Insights API client for JavaScript to allow sending click and conversion events right from the ais-infinite-hits widget.

Requirements

This requires installing the search-insights library separately:

You can refer to our insights API documentation for more details.

It’s a 3-step process:

1. Install the Insights API client for JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
  var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@1.3.0";

  !function(e,a,t,n,s,i,c){e.AlgoliaAnalyticsObject=s,e.aa=e.aa||function(){
  (e.aa.queue=e.aa.queue||[]).push(arguments)},i=a.createElement(t),c=a.getElementsByTagName(t)[0],
  i.async=1,i.src=ALGOLIA_INSIGHTS_SRC,c.parentNode.insertBefore(i,c)
  }(window,document,"script",0,"aa");

  aa('init', {
    appId: 'YourApplicationID',
    apiKey: 'YourSearchOnlyAPIKey',
  });
</script>

2. Connect the Insights API client for JavaScript with InstantSearch and enable clickAnalytics

1
2
3
4
5
6
7
<ais-instant-search 
  [...] 
  :insights-client="window.aa"
>
  <ais-configure :clickAnalytics="true" />
  <!-- widgets -->
</ais-instant-search>

3. Call the insights function from your ais-infinite-hits component

1
2
3
4
5
6
7
8
9
10
11
12
13
<ais-infinite-hits>
  <div slot-scope="{ items, refine, insights }">
    <div v-for="item in items">
      <h1>{{item.name}}</h1>

      <button @click="insights('clickedObjectIDsAfterSearch', { eventName: 'Add to cart', objectIDs: [item.objectID] })">
        Add to cart
      </button>

      <button @click="refine()">Load more</button>
    </div>
  </div>
</ais-infinite-hits>

Provided props

insights
type: function
signature: (method: string, payload: object) => void

Sends insights events.

  • method: string: the insights method to be called. Only search-related methods are supported: 'clickedObjectIDsAfterSearch', 'convertedObjectIDsAfterSearch'.

  • payload: object: the payload to be sent.

    • eventName: string: the name of the event.
    • objectIDs: string[]: a list of objectIDs.
    • index?: string: the name of the index related to the click.
    • queryID?: string: the Algolia queryID that can be found in the search response when using clickAnalytics: true.
    • userToken?: string: a user identifier.
    • positions?: number[]: the position of the click in the list of Algolia search results.

When not provided, index, queryID, and positions are inferred by the InstantSearch context and the passed objectIDs:

  • index by default is the name of index that returned the passed objectIDs.
  • queryID by default is the ID of the query that returned the passed objectIDs.
  • positions by default is the absolute positions of the passed objectIDs.

It is worth noting that each element of items has the following read-only properties:

  • __queryID: the query ID (only if clickAnalytics is set to true).
  • __position: the absolute position of the item.

For more details on the contraints that apply to each payload property, please refer to the insights client documentation.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<ais-infinite-hits>
  <div slot-scope="{ items, refine, insights }">
    <div v-for="item in items">
      <a href="/product?queryID={{item.__queryID}}">
        <h1>{{item.name}}</h1>
      </a>

      <button @click="insights('clickedObjectIDsAfterSearch', { eventName: 'Add to cart', objectIDs: [item.objectID] })">
        Add to cart
      </button>

      <button @click="refine()">Load more</button>
    </div>
  </div>
</ais-infinite-hits>

Did you find this page helpful?