HierarchicalMenu
<HierarchicalMenu attributes={string[]} // Optional parameters defaultRefinement={string} limit={number} showMore={boolean} showMoreLimit={number} separator={string} rootPath={string} showParentLevel={boolean} transformItems={function} translations={object} />
About this widget
The HierarchicalMenu
widget is used to create a navigation based on a hierarchy of facet attributes. It is commonly used for categories with subcategories.
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"
}
]
It’s also possible to 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 added in attributes for faceting, either on the dashboard or using attributesForFaceting with the API. By default, the separator we expect is >
(with spaces) but you can use a different one by using the separator option.
Examples
1
2
3
4
5
6
7
8
9
10
import { HierarchicalMenu } from 'react-instantsearch-dom';
<HierarchicalMenu
attributes={[
'categories.lvl0',
'categories.lvl1',
'categories.lvl2',
'categories.lvl3',
]}
/>
Props
attributes
|
type: string[]
Required
The names of the attributes inside the records. |
||
Copy
|
|||
defaultRefinement
|
type: string
Optional
The value of the item selected by default. |
||
Copy
|
|||
limit
|
type: number
default: 10
Optional
The minimum number of facet values to retrieve. |
||
Copy
|
|||
showMore
|
type: boolean
default: false
Optional
Whether to display a button that expands the number of items. |
||
Copy
|
|||
showMoreLimit
|
type: number
default: 20
Optional
The maximum number of displayed items. Only used when |
||
Copy
|
|||
separator
|
type: string
default: >
Optional
The level separator used in the records. |
||
Copy
|
|||
rootPath
|
type: string
Optional
The path to use if the first level is not the root level. |
||
Copy
|
|||
showParentLevel
|
type: boolean
default: true
Optional
Whether to show the siblings of the selected parent level of the current refined value. |
||
Copy
|
|||
transformItems
|
type: function
Optional
Modifies the items being displayed, for example, to filter or sort them. It takes items as argument and expects them back in return. |
||
Copy
|
|||
translations
|
type: object
Optional
A mapping of keys to translation values.
|
||
Copy
|
Customize the UI - connectHierarchicalMenu
If you want to create your own UI of the HierarchicalMenu
widget or use another UI library, you can use connectors.
Connectors are higher-order components. They encapsulate the logic for a specific kind of widget and they provide a way to interact with the InstantSearch context.
They have an outer component API that we call exposed props, and they provide some other props to the wrapped components which are called the provided props.
It’s a 3-step process:
// 1. Create a React component
const HierarchicalMenu = () => {
// return the DOM output
};
// 2. Connect the component using the connector
const CustomHierarchicalMenu = connectHierarchicalMenu(HierarchicalMenu);
// 3. Use your connected widget
<CustomHierarchicalMenu />
Create a React component
const HierarchicalMenu = ({
object[] items,
string currentRefinement,
function refine,
function createURL,
}) => {
// return the DOM output
};
Provided Props
items
|
type: object[]
The list of items the widget can display, with each item:
|
||
Copy
|
|||
currentRefinement
|
type: string
The currently applied refinement. |
||
Copy
|
|||
refine
|
type: function
Toggles a refinement. |
||
Copy
|
|||
createURL
|
type: function
Generates a URL for the corresponding search state. |
||
Copy
|
Create and instantiate your connected widget
const CustomHierarchicalMenu = connectHierarchicalMenu(HierarchicalMenu);
<CustomHierarchicalMenu
attributes={string[]}
// Optional parameters
defaultRefinement={string}
limit={number}
showMore={boolean}
showMoreLimit={number}
separator={string}
rootPath={string}
showParentLevel={boolean}
transformItems={function}
/>
Exposed Props
attributes
|
type: string[]
Required
The names of the attributes inside the records. |
||
Copy
|
|||
defaultRefinement
|
type: string
Optional
The value of the item selected by default. |
||
Copy
|
|||
limit
|
type: number
default: 10
Optional
The minimum number of diplayed items. |
||
Copy
|
|||
showMore
|
type: boolean
default: false
Optional
We don’t expose the function to toggle the number of value displayed by the widget with the connector. Yet, the option is required to enable the “Show more” behavior. The option drives how many values are retrieved (either |
||
Copy
|
|||
showMoreLimit
|
type: number
default: 20
Optional
The maximum number of displayed items. Only used when |
||
Copy
|
|||
separator
|
type: string
default: >
Optional
The level separator used in the records. |
||
Copy
|
|||
rootPath
|
type: string
Optional
The path to use if the first level is not the root level. |
||
Copy
|
|||
showParentLevel
|
type: boolean
default: true
Optional
Whether to show the siblings of the selected parent level of the current refined value. |
||
Copy
|
|||
transformItems
|
type: function
Optional
Modifies the items being displayed, for example, to filter or sort them. It takes items as argument and expects them back in return. |
||
Copy
|
If SEO is critical to your search page, your custom HTML markup needs to be parsable:
- use plain
<a>
tags withhref
attributes for search engines bots to follow them, - use semantic markup with structured data when relevant, and test it.
Refer to our SEO checklist for building SEO-ready search experiences.
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
import { connectHierarchicalMenu } from 'react-instantsearch-dom';
const HierarchicalMenu = ({ items, refine, createURL }) => (
<ul>
{items.map(item => (
<li key={item.label}>
<a
href={createURL(item.value)}
style={{ fontWeight: item.isRefined ? 'bold' : '' }}
onClick={event => {
event.preventDefault();
refine(item.value);
}}
>
{item.label} ({item.count})
</a>
{item.items && (
<HierarchicalMenu
items={item.items}
refine={refine}
createURL={createURL}
/>
)}
</li>
))}
</ul>
);
const CustomHierarchicalMenu = connectHierarchicalMenu(HierarchicalMenu);
HTML output
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
<div class="ais-HierarchicalMenu">
<ul class="ais-HierarchicalMenu-list ais-HierarchicalMenu-list--lvl0">
<li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent ais-HierarchicalMenu-item--selected">
<a class="ais-HierarchicalMenu-link" href="#">
<span class="ais-HierarchicalMenu-label">Appliances</span>
<span class="ais-HierarchicalMenu-count">4,306</span>
</a>
<ul class="ais-HierarchicalMenu-list ais-HierarchicalMenu-list--child ais-HierarchicalMenu-list--lvl1">
<li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent">
<a class="ais-HierarchicalMenu-link" href="#">
<span class="ais-HierarchicalMenu-label">Dishwashers</span>
<span class="ais-HierarchicalMenu-count">181</span>
</a>
</li>
<li class="ais-HierarchicalMenu-item">
<a class="ais-HierarchicalMenu-link" href="#">
<span class="ais-HierarchicalMenu-label">Fans</span>
<span class="ais-HierarchicalMenu-count">91</span>
</a>
</li>
</ul>
</li>
<li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent">
<a class="ais-HierarchicalMenu-link" href="#">
<span class="ais-HierarchicalMenu-label">Audio</span>
<span class="ais-HierarchicalMenu-count">1,570</span>
</a>
</li>
</ul>
<button class="ais-HierarchicalMenu-showMore">Show more</button>
</div>