<HierarchicalMenu>
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.
<HierarchicalMenu attributes={string[]} // Optional props limit={number} showMore={boolean} showMoreLimit={number} separator={string} rootPath={string} showParentLevel={boolean} sortBy={string[] | function} transformItems={function} classNames={object} translations={object} ...props={ComponentProps<'div'>} />
1
import { HierarchicalMenu } from 'react-instantsearch';
About this widget
<HierarchicalMenu>
is a widget that creates a navigation menu based on a hierarchy of facet attributes. It’s commonly used for categories with subcategories.
By default, the count of the refined root level is updated to match the count of the actively refined parent level. You can choose to keep the root level count intact by setting persistHierarchicalRootCount
in <InstantSearch>
.
Requirements
The objects to use in the hierarchical menu must follow this structure:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"objectID": "321432",
"name": "lemon",
"categories.lvl0": "products",
"categories.lvl1": "products > fruits"
},
{
"objectID": "8976987",
"name": "orange",
"categories.lvl0": "products",
"categories.lvl1": "products > fruits"
}
]
You can also provide more than one path for each level:
1
2
3
4
5
6
7
8
[
{
"objectID": "321432",
"name": "lemon",
"categories.lvl0": ["products", "goods"],
"categories.lvl1": ["products > fruits", "goods > to eat"]
}
]
The attributes provided to the widget must be in attributes for faceting, either on the dashboard) or using attributesForFaceting
with the API. By default, the separator is >
(with spaces), but you can use a different one by using the separator option.
You can also create your own UI with
useHierarchicalMenu()
.
Examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React from 'react';
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch, HierarchicalMenu } from 'react-instantsearch';
const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
function App() {
return (
<InstantSearch indexName="instant_search" searchClient={searchClient}>
<HierarchicalMenu
attributes={[
'categories.lvl0',
'categories.lvl1',
'categories.lvl2',
'categories.lvl3',
]}
/>
</InstantSearch>
);
}
Props
Parameter | Description | ||
---|---|---|---|
attributes
|
type: string[]
Required
The name of the attributes to generate the menu with.
To avoid unexpected behavior, you can’t use the same |
||
Copy
|
|||
limit
|
type: number
default: 10
The number of facet values to retrieve. When you enable the |
||
Copy
|
|||
showMore
|
type: boolean
default: false
Whether to display a button that expands the number of items. |
||
Copy
|
|||
showMoreLimit
|
type: number
The maximum number of displayed items (only used when |
||
Copy
|
|||
separator
|
type: string
default: " > "
The level separator used in the records. |
||
Copy
|
|||
rootPath
|
type: string
The prefix path to use if the first level isn’t the root level. Make sure to also include the root path in your UI state—for example, by setting |
||
Copy
|
|||
showParentLevel
|
type: boolean
default: true
Whether to show the siblings of the selected parent level of the current refined value. This option doesn’t impact the root level. All root items are always visible. |
||
Copy
|
|||
sortBy
|
type: string[] | (a: FacetValue, b: FacetValue) => number
default: ["name:asc"], or `facetOrdering` if set
How to sort refinements. Must be one or more of the following strings:
You can also give a function that receives items two by two, like JavaScript’s |
||
Copy
|
|||
transformItems
|
type: (items: object[], metadata: { results: SearchResults }) => object[]
Receives the items and is called before displaying them. Should return a new array with the same shape as the original array. This is helpful when transforming, removing, or reordering items. In addition, the full |
||
Copy
|
|||
classNames
|
type: Partial<HierarchicalMenuClassNames>
CSS classes to pass to the widget’s elements. This is helpful when styling widgets with class-based CSS frameworks like Bootstrap or Tailwind CSS.
|
||
Copy
|
|||
translations
|
type: Partial<HierarchicalMenuTranslations>
A dictionary of translations to customize the UI text and support internationalization.
|
||
Copy
|
|||
...props
|
type: React.ComponentProps<'div'>
Any |
||
Copy
|
Hook
React InstantSearch let you create your own UI for the <HierarchicalMenu>
widget with useHierarchicalMenu()
. Hooks provide APIs to access the widget state and interact with InstantSearch.
The useHierarchicalMenu()
Hook accepts parameters and returns APIs.
Usage
First, create your React component:
import { useHierarchicalMenu } from 'react-instantsearch';
function CustomHierarchicalMenu(props) {
const {
items,
isShowingMore,
canToggleShowMore,
canRefine,
refine,
sendEvent,
toggleShowMore,
createURL,
} = useHierarchicalMenu(props);
return <>{/* Your JSX */}</>;
}
Then, render the widget:
<CustomHierarchicalMenu {...props} />
Parameters
Hooks accept parameters. You can pass them manually, or forward the props from your custom component.
When you provide a function to Hooks, make sure to pass a stable reference to avoid rendering endlessly (for example, with useCallback()
). Objects and arrays are memoized; you don’t need to stabilize them.
Parameter | Description | ||
---|---|---|---|
attributes
|
type: string[]
Required
The names of the attributes inside the records. To avoid unexpected behavior, you can’t use the same |
||
Copy
|
|||
separator
|
type: string
default: " > "
The level separator used in the records. |
||
Copy
|
|||
rootPath
|
type: string
The path to use if the first level isn’t the root level. Make sure to also include the root path in your UI state—for example, by setting |
||
Copy
|
|||
showParentLevel
|
type: boolean
default: true
Whether to show the siblings of the selected parent level of the current refined value. |
||
Copy
|
|||
limit
|
type: number
default: 10
How many facet values to retrieve. When you enable the |
||
Copy
|
|||
showMore
|
type: boolean
default: false
Whether to display a button that expands the number of items. |
||
Copy
|
|||
showMoreLimit
|
type: number
The maximum number of displayed items. Only used when |
||
Copy
|
|||
sortBy
|
type: string[] | (a: RefinementListItem, b: RefinementListItem) => number
default: ["name:asc"] (or `facetOrdering` if set)
How to sort refinements. Must be one or more of the following strings:
You can also use a sort function that behaves like the standard Javascript When you don’t set this parameter, and you’ve set |
||
Copy
|
|||
transformItems
|
type: (items: object[], metadata: { results: SearchResults }) => object[]
Receives the items and is called before displaying them. Should return a new array with the same shape as the original array. This is helpful when transforming, removing, or reordering items. In addition, the full |
||
Copy
|
APIs
Hooks return APIs, such as state and functions. You can use them to build your UI and interact with React InstantSearch.
Parameter | Description | ||
---|---|---|---|
items
|
type: HierarchicalMenuItem[]
The list of items the widget can display. |
||
Copy
|
|||
isShowingMore
|
type: boolean
Whether the list is expanded. |
||
canToggleShowMore
|
type: boolean
Whether users can click the “Show more” button. |
||
canRefine
|
type: boolean
Indicates if you can refine the search state. |
||
refine
|
type: (value: string) => void
Sets the path of the hierarchical filter and triggers a new search. |
||
sendEvent
|
type: (eventType: string, facetValue: string, eventName?: string) => void
The function to send
|
||
toggleShowMore
|
type: () => void
Toggles the number of displayed values between |
||
createURL
|
type: (value: string) => string
Generates a URL for the next state. |
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
import React from 'react';
import { useHierarchicalMenu } from 'react-instantsearch';
function CustomHierarchicalMenu(props) {
const {
items,
refine,
canToggleShowMore,
toggleShowMore,
isShowingMore,
createURL,
} = useHierarchicalMenu(props);
return (
<>
<HierarchicalList
items={items}
onNavigate={refine}
createURL={createURL}
/>
{props.showMore && (
<button disabled={!canToggleShowMore} onClick={toggleShowMore}>
{isShowingMore ? 'Show less' : 'Show more'}
</button>
)}
</>
);
}
function HierarchicalList({ items, createURL, onNavigate }) {
if (items.length === 0) {
return null;
}
return (
<ul>
{items.map((item) => (
<li key={item.value}>
<a
href={createURL(item.value)}
onClick={(event) => {
if (isModifierClick(event)) {
return;
}
event.preventDefault();
onNavigate(item.value);
}}
style={{ fontWeight: item.isRefined ? 'bold' : 'normal' }}
>
<span>{item.label}</span>
<span>{item.count}</span>
</a>
{item.data && (
<HierarchicalList
items={item.data}
onNavigate={onNavigate}
createURL={createURL}
/>
)}
</li>
))}
</ul>
);
}