> ## 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-refinement-list

> Shows a list of facets for refining search results.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

```vue Signature theme={"system"}
<ais-refinement-list
  attribute="string"
  // Optional parameters
  operator="string"
  :limit="number"
  :show-more="boolean"
  :show-more-limit="number"
  :searchable="boolean"
  :searchable-placeholder="string"
  :sort-by="string[] | function"
  :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 { AisRefinementList } from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    export default {
      components: {
        AisRefinementList,
      },
      // ...
    };
    ```
  </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-refinement-list" horizontal>
  Preview this widget and its behavior.
</Card>

## About this widget

The `ais-refinement-list` widget is one of the most common widgets in a search UI.
With this widget, users can filter the dataset based on facets.

The widget only displays the most relevant facet values for the current search context.
The sort option only affects the facets that are returned by the engine, not which facets are returned.

This widget includes a "search for facet values" feature,
enabling users to search through the [values of a specific facet attribute](/doc/guides/managing-results/refine-results/faceting#search-for-facet-values).
This helps you find uncommon facet values.

### Requirements

The [`attribute`](#param-attribute) provided to the widget must be in attributes for faceting,
either on the [dashboard](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting-with-dashboard)
or using the [`attributesForFaceting`](/doc/api-reference/api-parameters/attributesForFaceting) parameter with the API.

If you are using the [`searchable`](#param-searchable) prop, you also need to make the attribute searchable using the [dashboard](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting-with-dashboard) or using the `searchable` modifier of [`attributesForFaceting`](/doc/api-reference/api-parameters/attributesForFaceting) with the API.

### Disappearing facet values

With many facet values, the available options can change depending on the user's query.
The refinement widget displays the most common facet values for a given query.

A user's chosen value can vanish if they alter the query.
This occurs because only the most common facet values are displayed when there are many options.
A previously selected value might not appear if it's uncommon for the new query.

To also show less common values, adjust the maximum number of values with the [`configure`](/doc/api-reference/widgets/configure/vue) widget.
It doesn't change how many items are shown: the limits you set with [`limit`](/doc/api-reference/widgets/refinement-list/vue#param-limit) and [`show-more-limit`](/doc/api-reference/widgets/refinement-list/vue#param-show-more-limit) still apply.

## Examples

```vue Vue icon=code theme={"system"}
<ais-refinement-list attribute="brand" />
```

## Props

<ParamField body="attribute" type="string" required>
  The name of the attribute in the <Records />.

  To avoid unexpected behavior, you can't use the same `attribute` prop in a different type of widget.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list attribute="brand" />
  ```
</ParamField>

<ParamField body="operator" type="string ('or'|'and')" default="or">
  How to apply refinements.

  * `'or'`: Returns results matching any of the selected values.
  * `'and'`: Returns results matching all selected values.

  Use [filters or facet filters](/doc/guides/managing-results/refine-results/filtering/in-depth/filters-and-facetfilters) for more complex result refinement.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list
    [...]
    operator="and"
  />
  ```
</ParamField>

<ParamField body="limit" type="number" default={10}>
  How many facet values to retrieve.
  When you enable the [`show-more`](#param-show-more) feature,
  this is the number of facet values to display before clicking the "Show more" button.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list
    [...]
    :limit="5"
  />
  ```
</ParamField>

<ParamField body="show-more" type="boolean" default={false}>
  Whether to display a button that expands the number of items.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list
    [...]
    show-more
  />
  ```
</ParamField>

<ParamField body="show-more-limit" type="number" default={20}>
  The maximum number of displayed items (only used when [`show-more`](#param-show-more) is set to `true`).

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list
    [...]
    :show-more-limit="15"
  />
  ```
</ParamField>

<ParamField body="searchable" type="boolean" default={false}>
  Adds a search input to let users search for more facet values.
  To make this feature work,
  you need to make the attribute searchable using the [dashboard](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting-with-dashboard)) or using the `searchable` modifier of [`attributesForFaceting`](/doc/api-reference/api-parameters/attributesForFaceting) with the API.

  <Note>
    In some situations, refined facet values might not be present in the data
    returned by Algolia.
  </Note>

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list
    [...]
    searchable
  />
  ```
</ParamField>

<ParamField body="searchable-placeholder" type="string" default="Search here…">
  The value of the search input placeholder.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list
    [...]
    searchable-placeholder="Search our products"
  />
  ```
</ParamField>

<ParamField body="sort-by" type="string[] | function" default="Uses facetOrdering if set, ['isRefined','count:desc','name:asc']">
  How to sort refinements. Must be one or more of the following strings:

  * `"count"` (same as `"count:desc"`)
  * `"count:asc"`
  * `"count:desc"`
  * `"name"` (same as `"name:asc"`)
  * `"name:asc"`
  * `"name:desc"`
  * `"isRefined"` (same as `"isRefined:asc"`)
  * `"isRefined:asc"`
  * `"isRefined:desc"`

  It's also possible to give a function,
  which receives items two by two, like JavaScript's [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort).

  If `facetOrdering` is set for this facet in `renderingContent`,
  and no value for `sortBy` is passed to this widget,
  `facetOrdering` is used, and the default order as a fallback.

  In some situations, refined facet values might not be present in the data returned by Algolia.

  <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"}
  <ais-refinement-list
    [...]
    :sort-by="['isRefined', 'name:asc']"
  />
  ```
</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`.

  ```vue Vue icon=code theme={"system"}
  <template>
    <!-- ... -->
    <ais-refinement-list
      [...]
      :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 results.page === 0
            ? items.slice(0, 5)
            : items;
        },
      },
    };
  </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-RefinementList`. The root element of the widget.
  * `.ais-RefinementList--noRefinement`. The root element of the widget with no refinement.
  * `.ais-RefinementList-list`. The list of all items.
  * `.ais-RefinementList-item`. The list item.
  * `.ais-RefinementList-item--selected`. The selected list item.
  * `.ais-RefinementList-label`. The label of each item.
  * `.ais-RefinementList-labelText`. The text of the label of each item.
  * `.ais-RefinementList-checkbox`. The checkbox element.
  * `.ais-RefinementList-count`. The count of values for each item.
  * `.ais-RefinementList-searchBox`. The search box when the widget is searchable.
  * `.ais-RefinementList-noResults`. The element rendered when the search doesn't have results.
  * `.ais-RefinementList-showMore`. The button used to display more categories (enabled).
  * `.ais-RefinementList-showMore--disabled`. The button used to display more categories (turned off).

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list
    [...]
    :class-names="{
      'ais-RefinementList': 'MyCustomRefinementList',
      'ais-RefinementList-item': 'MyCustomRefinementListItem',
      // ...
    }"
  />
  ```
</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 values applicable to this widget.
  * `isShowingMore: boolean`. Is [`show-more`](#param-show-more) enabled?
  * `isFromSearch: boolean`. `true` if there are search results.
  * `canRefine: boolean`. Can the refinement be applied?
  * `canToggleShowMore: boolean`. Is [`show-more`](#param-show-more) possible?
  * `toggleShowMore: () => void`. Toggles the number of displayed values between [`limit`](#param-limit) and [`show-more-limit`](#param-show-more-limit).
  * `searchForItems: (value: string) => void`. A function to search into the facet values.
  * `refine: (value: string) => void`. A function to select a refinement.
  * `createURL: (value: string) => string`. A function to return a link for this refinement.
  * `sendEvent: (eventType: 'click', facetValue: string) => void`. The function to send `click` events.

    * The `view` event is automatically sent when the facets are rendered.
    * The `click` event is automatically sent when `refine` is called.
    * You can learn more about the [`insights`](/doc/api-reference/widgets/insights/vue) middleware.

  Where each item is an `object` containing:

  * `value: string`. The value of the item.
  * `label: string`. The human-readable value of the item.
  * `count: number`. The number of matched results after a refinement is applied.
  * `isRefined: boolean`. Indicates if the refinement is applied.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list attribute="brand" searchable show-more>
    <template
      v-slot="{
        items,
        isShowingMore,
        isFromSearch,
        canToggleShowMore,
        refine,
        createURL,
        toggleShowMore,
        searchForItems,
        sendEvent,
      }"
    >
      <input @input="searchForItems($event.currentTarget.value)">
      <ul>
        <li v-if="isFromSearch && !items.length">No results.</li>
        <li v-for="item in items" :key="item.value">
          <a
            :href="createURL(item)"
            :style="{ fontWeight: item.isRefined ?  'bold' : '' }"
            @click.prevent="refine(item.value)"
          >
            <ais-highlight attribute="item" :hit="item"/>
            ({{ item.count.toLocaleString() }})
          </a>
        </li>
      </ul>
      <button
        @click="toggleShowMore"
        :disabled="!canToggleShowMore"
      >
        {{ !isShowingMore ? 'Show more' : 'Show less'}}
      </button>
    </template>
  </ais-refinement-list>
  ```
</ParamField>

<ParamField body="item">
  The slot to override the DOM output of an item.

  **Scope**

  * `item: object`. An item object.
  * `refine: (Item.value) => void`. A function to select a refinement.
  * `createURL: (Item) => string`. A function to return a link for this refinement.

  Where an item is an `object` containing:

  * `value: string`. The value of the item.
  * `label: string`. The human-readable value of the item.
  * `count: number`. The number of results matched after a refinement is applied.
  * `isRefined: boolean`. Indicates if the refinement is applied.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list attribute="brand">
    <template v-slot:item="{ item, refine, createURL }">
      <a
        :href="createURL(item.value)"
        :style="{ fontWeight: item.isRefined ? 'bold' : '' }"
        @click.prevent="refine(item.value)"
      >
        <ais-highlight attribute="item" :hit="item"/>
        ({{ item.count.toLocaleString() }})
      </a>
    </template>
  </ais-refinement-list>
  ```
</ParamField>

<ParamField body="showMoreLabel">
  The slot to override the DOM output of the "Show more" button.

  **Scope**

  * `isShowingMore: boolean`. Is the list of items expanded?

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list attribute="brand" show-more>
    <template v-slot:showMoreLabel="{ isShowingMore }">
      {{ !isShowingMore ? 'More' : 'Less' }}
    </template>
  </ais-refinement-list>
  ```
</ParamField>

<ParamField body="noResults">
  The slot to override the DOM output of the no results placeholder.

  **Scope**

  * `query: string`. The current value of the query.

  ```vue Vue icon=code theme={"system"}
  <ais-refinement-list attribute="brand" searchable>
    <template v-slot:noResults="{ query }">
      No results for
      <q>{{ query }}</q>
    </template>
  </ais-refinement-list>
  ```
</ParamField>

## HTML output

```html HTML icon=code-xml theme={"system"}
<div class="ais-RefinementList">
  <div class="ais-RefinementList-searchBox">
    <!-- SearchBox widget here -->
  </div>
  <ul class="ais-RefinementList-list">
    <li class="ais-RefinementList-item ais-RefinementList-item--selected">
      <label class="ais-RefinementList-label">
        <input
          class="ais-RefinementList-checkbox"
          type="checkbox"
          value="Insignia™"
          checked
        />
        <span class="ais-RefinementList-labelText">Insignia™</span>
        <span class="ais-RefinementList-count">746</span>
      </label>
    </li>
    <li class="ais-RefinementList-item">
      <label class="ais-RefinementList-label">
        <input
          class="ais-RefinementList-checkbox"
          type="checkbox"
          value="Samsung"
        />
        <span class="ais-RefinementList-labelText">Samsung</span>
        <span class="ais-RefinementList-count">633</span>
      </label>
    </li>
  </ul>
  <button class="ais-RefinementList-showMore">Show more</button>
</div>
```
