Facet display in React InstantSearch
This is the React InstantSearch v7 documentation. React InstantSearch v7 is the latest version of React InstantSearch and the stable version of React InstantSearch Hooks.
If you were using React InstantSearch v6, you can upgrade to v7.
If you were using React InstantSearch Hooks, you can still use the React InstantSearch v7 documentation, but you should check the upgrade guide for necessary changes.
If you want to keep using React InstantSearch v6, you can find the archived documentation.
On this page
Learn how to configure, order, hide, and display facets and facet values using the dashboard, API, and your choice of InstantSearch or a custom solution.
Manage facet display from the Algolia dashboard
Control the facets to display and their order by sending a renderingContent
parameter with your search query.
Your UI must interpret this setting so your users can interact with the index.
The main implementation steps are:
- Configure the attributes to use for faceting on your search index.
- Configure your facet display.
- Build a UI capable of interpreting the
renderingContent
setting. For this step, use InstantSearch library widgets. You can create a UI with other tools but must write the interpretation logic yourself.
Configure facet display from the dashboard
- Select the Search product icon on your dashboard and then select your index.
- Click the Configuration tab.
- Under the Filtering and Faceting category, click Facet display.
- Click Add facet to display to choose the facets you want to display in your UI.
- Use the
=
icon next to each facet to drag them into the correct position. The order you set here determines how facets display in your UI. -
For each facet, click the pen icon to configure how the engine should display the facet’s values. You can:
- Pin some values at the top of the list if you want to display them first.
- Hide some values from the list entirely.
- Choose how to display the remaining facet values: by count, alphabetically, or only display pinned values.
- To remove a facet from the list and stop displaying it in your UI, click the trash icon.
- Save your changes.
If you want to only display the facets “brand”, “size”, and “color” in your UI, declare than as attributes for faceting and add them to the list of facets to display.
With those three facets added, you want to display the brands alphabetically. However:
- Since you have a specific partnership with the brand “Lacoste”, you want the brand to always display on top.
- Sizes need to be in a specific order: S, M, L, XL. You may have sizes in different formats in your data, but for the sake of clarity, you only want to display those four. You pin them at the top in the correct order and choose not to display other values
- For colors, you want to display them by count and not pin any specific value.
As soon as you save the changes, the UI adapts to this new configuration.
This approach lets you configure a static facet display. If you want a more dynamic approach that customizes the display of the facets and values for a specific query or category, see the Merchandising facets.
Configure facet display with the API
To replicate the preceding dashboard example, use the API client’s setSettings
method with the following settings applied to your index:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$index->setSettings([
'renderingContent' => [
'facetOrdering' => [
'facets' => [
'order' => ['brand', 'size', 'color']
],
'values' => [
'brand'=> [
'order' => ['Uniqlo'],
'sortRemainingBy' => 'alpha'
],
'size'=> [
'order' => ['S', 'M', 'L','XL'],
'sortRemainingBy' => 'hidden'
],
'color'=> [
'sortRemainingBy' => 'count'
]
]
]
]
]);
Hide facet values
Hiding facet values is not supported in InstantSearch iOS and InstantSearch Android.
The following example shows three facets: author
, brand
, and on_sale
(in that order).
The author
facet is sorted by number of hits, the brand
facet is ordered alphabetically, always shows the facet value “Kensington” in the first position (pinned) and never shows the value “Bosch” (hidden). The on_sale
facet only shows the pinned true value.
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
index
.setSettings({
renderingContent: {
facetOrdering: {
facets: {
order: ['author', 'brand', 'on_sale'],
},
values: {
"author": {
"sortRemainingBy": "count"
},
"brand": {
"order": ["Kensington"],
"hide": ["Bosch"]
"sortRemainingBy": "alpha"
},
"on_sale": {
"order": ["true"],
"sortRemainingBy": "hidden"
},
},
},
},
})
.then(() => {
// done
});
Build the UI with InstantSearch
The simplest way to control facet display is to use InstantSearch.
This UI library has built-in widgets that understand the renderingContent
data returned by searches.
This data includes everything you need to show facets how you want.
Facet display requirements for InstantSearch
To make your UI compatible with the facet display feature:
- Add refinement widgets for the different facets.
- Add a
dynamicWidgets
container around the widgets you want to sort. - In those widgets, remove any custom
sortBy
or setfacetOrdering
totrue
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// This example assumes you're including InstantSearch.js in your web
// page via a CDN. If you're using it with a package manager, you
// should adjust the way you import InstantSearch.js and its widgets.
const { dynamicWidgets, menu, hierarchicalMenu } = instantsearch.widgets;
search.addWidgets([
dynamicWidgets({
container: '#dynamic-widgets',
fallbackWidget: ({ container, attribute }) =>
menu({ container, attribute, limit: 10 }),
widgets: [
container =>
hierarchicalMenu({
limit: 10,
attributes: [
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
],
}),
],
}),
])
Upgrade InstantSearch
If you already built your UI using InstantSearch, you may need to update it to use the dynamic widgets introduced in the following versions:
- InstantSearch.js: available from version 4.22.0
- Vue InstantSearch: available from version 4.1.0
- React InstantSearch: available from version 6.14.0
- InstantSearch iOS: available from version 7.12.0
- InstantSearch Android: available from version 2.11.0
Check the upgrade guide for InstantSearch to upgrade your UI to the latest version.
Optimize dynamic widget network requests
Algolia automatically mounts the appropriate widgets for the search results.
- In versions 4.32 to 4.35, dynamic widgets request all facets and generate an extra network request for this. To avoid this, set
facets
to[]
(empty). - In version 4.36 and later, to avoid an extra request,
facets
is set to[*]
by default. If you prefer to do two network requests with only the relevant facets returned, setfacets
to[]
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// This example assumes you're including InstantSearch.js in your web
// page via a CDN. If you're using it with a package manager, you
// should adjust the way you import InstantSearch.js and its widgets.
const { dynamicWidgets, menu, hierarchicalMenu } = instantsearch.widgets;
search.addWidgets([
dynamicWidgets({
container: '#dynamic-widgets',
fallbackWidget: ({ container, attribute }) =>
menu({ container, attribute, limit: 10 }),
widgets: [
container =>
hierarchicalMenu({
limit: 10,
attributes: [
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
],
}),
],
// do two network requests
facets: []
}),
])
Widget limitation
Applies to:
- InstantSearch.js v4.36 and later
- React InstantSearch v7 and later
- Vue InstantSearch v4.3 and later
Dynamic widgets can show up to 1,000 facets. If you do have more than that, here’s how to display the ones with the most results.
- Add an
applicable_facets
facet to every object:
1
2
3
4
5
{
"applicable_facets": ["special_type", "color"],
"special_type": "stretch",
"color": "blue"
}
- Configure the dynamic widget so it doesn’t ask for all facets. Many of them will be hidden anyway because of the 1,000 facet limit. To do this, set
facets
to[]
(empty).
1
2
3
dynamicWidgets({
facets: []
})
- Ensure that
applicable_facets
is always requested. Such as from a hidden menu:
1
connectMenu(() => {})({ attribute: "applicable_facets" })
- Use
transformItems
ofdynamicWidgets
to useapplicable_facets
for dynamic widget rendering:
1
2
3
4
5
6
dynamicWidgets({
facets: [],
transformItems(_items, { results }) {
return Object.keys(results._rawResults[0].facets.applicable_facets);
}
});
Build the UI without InstantSearch
If you aren’t using InstantSearch to build your UI, you need to build frontend logic to:
- Interpret the
renderingContent
parameter returned along search results, - Order facets and values based on your interpretation of the
renderingContent
parameter values.
A custom implementation of frontend search requires:
- Reading the facet order
- Reading the facet value order
Read the facet order
If you hardcode the list of facets to display on a page, you can read that from result.renderingContent.facetOrdering.facets.order
(all keys are optional).
This is the list of attributes that you chose to display and can loop over to display individual facet lists.
Read the facet value order
You need to list the attribute you want to display facets of in searchParameters.facets
.
Read the possible results from result.facets[facetName]
.
After fetching those values, you can read the result.renderingContent.facetOrdering.values[facetName]
object to sort them.
This object has the following keys:
order
: an array of facet values to pin at the start of the listhide
: an array of facet values to hide from the listsortRemainingBy
: a string that describes how to sort the remaining values. Either “alpha” (alphabetically, ascending), “count” (value retrieved fromfacets[facetName][facetValue]
, descending), or “hidden”, which only displays the ordered items.