> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ais-hits-per-page

> Lets users change the number of search results per page.

```vue Signature theme={"system"}
<ais-hits-per-page
  :items="object[]"
  // Optional parameters
  :transform-items="function"
  :class-names="object"
/>
```

## Import

<Tabs>
  <Tab title="Component">
    To ensure optimal bundle sizes,
    see [Optimize build size](/doc/guides/building-search-ui/going-further/improve-performance/vue#optimize-build-size).

    ```js Vue icon=code theme={"system"}
    import { AisHitsPerPage } from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    export default {
      components: {
        AisHitsPerPage,
      },
      // ...
    };
    ```
  </Tab>

  <Tab title="Plugin">
    This imports all widgets, even the ones you don't use.
    For more information, see [Get started with Vue InstantSearch](/doc/guides/building-search-ui/getting-started/vue).

    ```js JavaScript icon="code" theme={"system"}
    import Vue from "vue";
    import InstantSearch from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    Vue.use(InstantSearch);
    ```
  </Tab>
</Tabs>

<Card title="See this widget in action" icon="monitor-play" href="https://instantsearchjs.netlify.app/stories/vue/?selectedKind=ais-hits-per-page" horizontal>
  Preview this widget and its behavior.
</Card>

## About this widget

The `ais-hits-per-page` widget displays a select element to let users change the number of displayed hits.

If you only want to configure the number of hits per page without displaying a widget,
you can use the [`ais-configure`](/doc/api-reference/widgets/configure/vue) widget with the [`hitsPerPage`](/doc/api-reference/api-parameters/hitsPerPage) search parameter.

## Examples

```vue Vue icon=code theme={"system"}
<ais-hits-per-page
  :items="[
    { label: '8 hits per page', value: 8, default: true },
    { label: '16 hits per page', value: 16 },
  ]"
/>
```

## Props

<ParamField body="items" type="object[]" required>
  The list of available options, with each item:

  * `label: string`. The label to display in the option.
  * `value: number`. The number of hits to display per page.
  * `default: boolean`. Whether it's the default hits per page on first search.

  ```vue Vue icon=code theme={"system"}
  <ais-hits-per-page
    :items="[
      { label: '8 hits per page', value: 8, default: true },
      { label: '16 hits per page', value: 16 },
    ]"
  />
  ```
</ParamField>

<ParamField body="transform-items" type="function" default="items => items">
  A function that receives the list of items before they are displayed.
  It should return a new array with the same structure.
  Use this to transform, filter, or reorder the items.

  The function also has access to the full `results` data,
  including all standard [response parameters](/doc/guides/building-search-ui/going-further/backend-search/in-depth/understanding-the-api-response/)
  and [parameters from the helper](https://community.algolia.com/algoliasearch-helper-js/reference.html#query-parameters),
  such as `disjunctiveFacetsRefinements`.

  <Note>
    To [prevent creating infinite loops](https://support.algolia.com/hc/en-us/articles/4406511683217-Vue-InstantSearch-How-do-I-prevent-infinite-loops),
    avoid passing arrays, objects, or functions directly in the template.
    These values aren't referentially equal on each render,
    which causes the widget to re-register every time.
    Instead, define them in your component's `data` option and reference them in the template.
  </Note>

  ```vue Vue icon=code theme={"system"}
  <template>
    <!-- ... -->
    <ais-hits-per-page
      [...]
      :transform-items="transformItems"
    />
  </template>

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

      /* or, combined with results */
      transformItems(items, { results }) {
        return items.map((item) => ({
          ...item,
          label:
            item.isRefined && results
              ? `${item.label} (${results.nbPages} pages in total)`
              : item.label,
        }));
      },
    },
  };
  </script>
  ```
</ParamField>

<ParamField body="class-names" type="object" default="{}">
  The [CSS classes you can override](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/vue#style-your-widgets):

  * `ais-HitsPerPage`. The root of the widget.
  * `ais-HitsPerPage-select`. The select element.
  * `ais-HitsPerPage-option`. The option element of the select.

  ```vue Vue icon=code theme={"system"}
  <ais-hits-per-page
    [...]
    :class-names="{
      'ais-HitsPerPage': 'MyCustomHitsPerPage',
      'ais-HitsPerPage-select': 'MyCustomHitsPerPageSelect',
      // ...
    }"
  />
  ```
</ParamField>

## Customize the UI

<ParamField body="default">
  The slot to override the complete DOM output of the widget.

  When you implement this slot,
  none of the other slots will change the output,
  as the default slot surrounds them.

  **Scope**

  * `items: object[]`. The list of items the widget can display.
  * `canRefine: boolean`. Whether a refinement can be applied.
  * `refine: (value: number) => void`. The function to call with the next value of hits per page.

  Where each item is an `object` containing:

  * `label: string`. The label to display in the option.
  * `value: number`. The number of hits to display per page.
  * `isRefined: boolean`. Indicates if the item is the current refined value.

  ```vue Vue icon=code theme={"system"}
  <ais-hits-per-page
    :items="[
      { label: '8 hits per page', value: 8, default: true },
      { label: '16 hits per page', value: 16 },
    ]"
  >
    <template v-slot="{ items, refine }">
      <ul>
        <li v-for="item in items" :key="item.value">
          <button
            :style="{ fontWeight: item.isRefined ? 'bold' : '' }"
            @click="refine(item.value)"
          >
            {{ item.label }}
          </button>
        </li>
      </ul>
    </template>
  </ais-hits-per-page>
  ```
</ParamField>

## HTML output

```html HTML icon=code-xml theme={"system"}
<div class="ais-HitsPerPage">
  <select class="ais-HitsPerPage-select">
    <option class="ais-HitsPerPage-option" value="8">8 per page</option>
    <option class="ais-HitsPerPage-option" value="16">16 per page</option>
  </select>
</div>
```
