refinementList
refinementList({ container: string|HTMLElement, attribute: string, // Optional parameters operator: string, limit: number, showMore: boolean, showMoreLimit: number, searchable: boolean, searchablePlaceholder: string, searchableIsAlwaysActive: boolean, searchableEscapeFacetValues: boolean, sortBy: string[]|function, templates: object, cssClasses: object, transformItems: function, });
1
import { refinementList } from 'instantsearch.js/es/widgets';
About this widget
The refinementList
widget is one of the most common widget you can find 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 also implements search for facet values, which is a mini search inside the values of the facets. This makes it easy to deal with uncommon facet values.
Requirements
The attribute provided to the widget must be in attributes for faceting, either on the dashboard or using attributesForFaceting
with the API.
If you are using the searchable
prop, you also need to make the attribute searchable using the dashboard or using the searchable
modifier of attributesForFaceting
with the API.
Examples
1
2
3
4
refinementList({
container: '#refinement-list',
attribute: 'brand',
});
Options
Parameter | Description | ||
---|---|---|---|
container
|
type: string|HTMLElement
Required
The CSS Selector of the DOM element inside which the widget is inserted. |
||
Copy
|
|||
attribute
|
type: string
Required
The name of the attribute in the records. To avoid unexpected behavior, you can’t use the same |
||
Copy
|
|||
operator
|
type: string
default: "or"
Optional
How to apply refinements.
|
||
Copy
|
|||
limit
|
type: number
default: 10
Optional
How many facet values to retrieve. When you enable the |
||
Copy
|
|||
showMore
|
type: boolean
default: false
Optional
Whether to display a button that expands the number of items. |
||
Copy
|
|||
showMoreLimit
|
type: number
Optional
The maximum number of displayed items (only used when |
||
Copy
|
|||
searchable
|
type: boolean
default: false
Optional
Whether to add 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 or using the In some situations, refined facet values might not be present in the data returned by Algolia. Read the FAQ to get more information and adjust your configuration. |
||
Copy
|
|||
searchablePlaceholder
|
type: string
default: Search...
Optional
The value of the search input’s placeholder. |
||
Copy
|
|||
searchableIsAlwaysActive
|
type: boolean
default: true
Optional
When |
||
Copy
|
|||
searchableEscapeFacetValues
|
type: boolean
default: true
Optional
When |
||
Copy
|
|||
sortBy
|
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:
It’s also possible to give a function, which receives items two by two, like JavaScript’s If In some situations, refined facet values might not be present in the data returned by Algolia. Read the FAQ to get more information and adjust your configuration. |
||
Copy
|
|||
templates
|
type: object
Optional
The templates to use for the widget. |
||
Copy
|
|||
cssClasses
|
type: object
The CSS classes you can override:
|
||
Copy
|
|||
transformItems
|
type: function
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 transforming, removing, or reordering items. In addition, the full |
||
Copy
|
Templates
You can customize parts of the widget’s UI using the Templates API.
Every template provides an html
function you can use as a tagged template. Using html
lets you safely provide templates as an HTML string. It works directly in the browser without a build step. See Templating your UI for more information.
The html
function is available starting from v4.46.0.
Parameter | Description | ||
---|---|---|---|
item
|
type: string|function
Optional
The template used for an item. It exposes:
|
||
Copy
|
|||
showMoreText
|
type: string|function
Optional
The template for the “Show more” button text. It exposes:
|
||
Copy
|
|||
searchableNoResults
|
type: string|function
Optional
The template used for when there are no results. |
||
Copy
|
|||
searchableSubmit
|
type: string|function
Optional
The template used for displaying the submit button. |
||
Copy
|
|||
searchableReset
|
type: string|function
Optional
The template used for displaying the reset button. |
||
Copy
|
|||
searchableLoadingIndicator
|
type: string|function
Optional
The template used for displaying the loading indicator. |
||
Copy
|
Customize the UI with connectRefinementList
If you want to create your own UI of the refinementList
widget, you can use connectors.
To use connectRefinementList
, you can import it with the declaration relevant to how you installed InstantSearch.js.
1
import { connectRefinementList } from 'instantsearch.js/es/connectors';
Then it’s a 3-step process:
// 1. Create a render function
const renderRefinementList = (renderOptions, isFirstRender) => {
// Rendering logic
};
// 2. Create the custom widget
const customRefinementList = connectRefinementList(
renderRefinementList
);
// 3. Instantiate
search.addWidgets([
customRefinementList({
// instance params
})
]);
Create a render function
This rendering function is called before the first search (init
lifecycle step)
and each time results come back from Algolia (render
lifecycle step).
const renderRefinementList = (renderOptions, isFirstRender) => {
const {
object[] items,
boolean canRefine,
function refine,
function sendEvent,
function createURL,
boolean isFromSearch,
function searchForItems,
boolean hasExhaustiveItems,
boolean isShowingMore,
boolean canToggleShowMore,
function toggleShowMore,
object widgetParams,
} = renderOptions;
if (isFirstRender) {
// Do some initial rendering and bind events
}
// Render the widget
}
Rendering options
Parameter | Description | ||
---|---|---|---|
items
|
type: object[]
The list of refinement values returned from the Algolia API. Each object has the following properties:
|
||
Copy
|
|||
canRefine
|
type: boolean
Required
Indicates if search state can be refined. |
||
Copy
|
|||
refine
|
type: function
A function to toggle a refinement. |
||
Copy
|
|||
sendEvent
|
type: (eventType, facetValue) => void
The function to send
|
||
Copy
|
|||
createURL
|
type: function
Generates a URL for the corresponding search state. |
||
Copy
|
|||
isFromSearch
|
type: boolean
Whether the |
||
Copy
|
|||
searchForItems
|
type: function
A function to trigger a search inside items values. To make this feature work, you need to make the attribute searchable using the dashboard or using the |
||
Copy
|
|||
hasExhaustiveItems
|
type: boolean
Whether the results are complete. |
||
Copy
|
|||
isShowingMore
|
type: boolean
Returns |
||
Copy
|
|||
canToggleShowMore
|
type: boolean
Returns |
||
Copy
|
|||
toggleShowMore
|
type: function
Toggles the number of displayed values between |
||
Copy
|
|||
widgetParams
|
type: object
All original widget options forwarded to the render function. |
||
Copy
|
Create and instantiate the custom widget
We first create custom widgets from our rendering function, then we instantiate them. When doing that, there are two types of parameters you can give:
- Instance parameters: they are predefined parameters that you can use to configure the behavior of Algolia.
- Your own parameters: to make the custom widget generic.
Both instance and custom parameters are available in connector.widgetParams
, inside the renderFunction
.
const customRefinementList = connectRefinementList(
renderRefinementList
);
search.addWidgets([
customRefinementList({
attribute: string,
// Optional parameters
operator: string,
limit: number,
showMoreLimit: number,
escapeFacetValues: boolean,
sortBy: string[]|function,
transformItems: function,
})
]);
Instance options
Parameter | Description | ||
---|---|---|---|
attribute
|
type: string
Required
The name of the attribute in the records. To avoid unexpected behavior, you can’t use the same |
||
Copy
|
|||
operator
|
type: string ("or"|"and")
default: "or"
Optional
How to apply refinements.
|
||
Copy
|
|||
limit
|
type: number
default: 10
Optional
How many facet values to retrieve. When isShowingMore is |
||
Copy
|
|||
showMoreLimit
|
type: number
Optional
The maximum number of items to display if the widget is showing more items. Needs to be bigger than the |
||
Copy
|
|||
escapeFacetValues
|
type: boolean
default: true
Optional
When activate, escapes the facet values that are returned from Algolia. In this case, the sourrounding tags are always |
||
Copy
|
|||
sortBy
|
type: string[]|function
default: Uses facetOrdering if set, ["isRefined","count:desc","name:asc"]
Optional
How to sort refinements. Must be one or more of the following strings:
It’s also possible to give a function, which receives items two by two, like JavaScript’s If In some situations, refined facet values might not be present in the data returned by Algolia. Read the FAQ to get more information and adjust your configuration. |
||
Copy
|
|||
transformItems
|
type: function
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 transforming, removing, or reordering items. In addition, the full |
||
Copy
|
Full example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// 1. Create a render function
const renderRefinementList = (renderOptions, isFirstRender) => {
const {
items,
isFromSearch,
refine,
createURL,
isShowingMore,
canToggleShowMore,
searchForItems,
toggleShowMore,
widgetParams,
} = renderOptions;
if (isFirstRender) {
const input = document.createElement('input');
const ul = document.createElement('ul');
const button = document.createElement('button');
button.textContent = 'Show more';
input.addEventListener('input', event => {
searchForItems(event.currentTarget.value);
});
button.addEventListener('click', () => {
toggleShowMore();
});
widgetParams.container.appendChild(input);
widgetParams.container.appendChild(ul);
widgetParams.container.appendChild(button);
}
const input = widgetParams.container.querySelector('input');
if (!isFromSearch && input.value) {
input.value = '';
}
widgetParams.container.querySelector('ul').innerHTML = items
.map(
item => `
<li>
<a
href="${createURL(item.value)}"
data-value="${item.value}"
style="font-weight: ${item.isRefined ? 'bold' : ''}"
>
${item.label} (${item.count})
</a>
</li>
`
)
.join('');
[...widgetParams.container.querySelectorAll('a')].forEach(element => {
element.addEventListener('click', event => {
event.preventDefault();
refine(event.currentTarget.dataset.value);
});
});
const button = widgetParams.container.querySelector('button');
button.disabled = !canToggleShowMore;
button.textContent = isShowingMore ? 'Show less' : 'Show more';
};
// 2. Create the custom widget
const customRefinementList = connectRefinementList(
renderRefinementList
);
// 3. Instantiate
search.addWidgets([
customRefinementList({
container: document.querySelector('#refinement-list'),
attribute: 'brand',
showMoreLimit: 20,
})
]);