Components
<AisRefinementList>
Facet refinement widget with optional search and show-more behavior.
Usage
<AisInstantSearch :configuration="configuration">
<AisRefinementList attribute="brand" searchable :show-more="true" />
</AisInstantSearch>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
attribute | string | required | Facet attribute name to refine. |
id | string | "" | Optional widget ID for repeated instances (also scoped by indexId). |
searchable | boolean | false | Enables in-widget facet search. |
searchablePlaceholder | string | "Search here…" | Placeholder for facet search input. |
operator | "and" | "or" | connector default | Refinement operator. |
limit | number | connector default | Initial number of facet values. |
showMore | boolean | false | Enables show-more pagination in the facet list. |
showMoreLimit | number | connector default | Max facet values after show-more. |
sortBy | unknown[] | function | connector default | Sorting strategy for facet values. |
transformItems | function | undefined | Transforms facet items before rendering. |
Slots
| Slot | Slot props | Description |
|---|---|---|
default | { items, refine, searchForItems, searchForItemsQuery, toggleShowMore, canToggleShowMore, isShowingMore, createURL, isFromSearch, canRefine, sendEvent } | Replaces full rendering and exposes all connector interactions. |
item | { item, refine, createURL } | Customizes one facet item. |
noResults | { query } | Custom empty state for searchable mode. |
showMoreLabel | { isShowingMore } | Custom label for the show-more button. |
sendEvent signature in this widget: sendEvent(eventType, facetValue, eventName?, additionalData?).
Typed transformItems
Use Vue's @vue-generic syntax to type transformed facet items in slot props.
<script setup lang="ts">
import type { RefinementListItem } from "instantsearch.js/es/connectors/refinement-list/connectRefinementList";
type BrandFacet = RefinementListItem & {
visualLabel: string;
};
const transformBrands = (items: RefinementListItem[]) => {
return items.map((item) => ({
...item,
visualLabel: `${item.label} (${item.count})`,
})) as BrandFacet[];
};
</script>
<template>
<!-- @vue-generic {BrandFacet} -->
<AisRefinementList attribute="brand" :transform-items="transformBrands">
<template #item="{ item }">
{{ item.visualLabel }}
</template>
</AisRefinementList>
</template>
End-to-end example
<AisRefinementList attribute="brand" searchable :show-more="true">
<template
#default="{ items, refine, sendEvent, canToggleShowMore, isShowingMore, toggleShowMore }"
>
<ul>
<li v-for="item in items" :key="item.value">
<button
type="button"
:aria-pressed="item.isRefined"
@click="
refine(item.value);
sendEvent('click', item.value, 'Brand Filter Selected');
"
>
{{ item.label }} ({{ item.count }})
</button>
</li>
</ul>
<button
v-if="canToggleShowMore"
type="button"
@click="toggleShowMore"
>
{{ isShowingMore ? "Show fewer brands" : "Show more brands" }}
</button>
</template>
<template #noResults="{ query }">
No brands matching "{{ query }}"
</template>
</AisRefinementList>
When used multiple times in the same index, set explicit
id values to keep instances independent.