The useHierarchicalMenu hook provides the logic to build a custom hierarchical menu component for faceted navigation with hierarchical data.
Import
import { useHierarchicalMenu } from 'react-instantsearch';
Parameters
Attributes to use to generate the hierarchy of the menu.const { items } = useHierarchicalMenu({
attributes: [
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
'hierarchicalCategories.lvl2',
],
});
Maximum number of values to display.const { items } = useHierarchicalMenu({
attributes: ['category'],
limit: 5,
});
Whether to display the “show more” button.const { toggleShowMore } = useHierarchicalMenu({
attributes: ['category'],
showMore: true,
showMoreLimit: 20,
});
Maximum number of values to display when showing more.
Separator used in the attributes to separate level values.const { items } = useHierarchicalMenu({
attributes: ['category'],
separator: ' > ',
});
Prefix path to use if the first level is not the root level.
Show the siblings of the selected parent levels of the current refined value.
sortBy
string[] | (a, b) => number
How to sort refinements. Possible values: count|isRefined|name:asc|name:desc.const { items } = useHierarchicalMenu({
attributes: ['category'],
sortBy: ['name:asc'],
});
transformItems
(items: HierarchicalMenuItem[]) => HierarchicalMenuItem[]
Function to transform the items passed to the templates.
Returns
The list of hierarchical menu items.const { items } = useHierarchicalMenu({
attributes: ['category'],
});
items.forEach((item) => {
console.log(item.value); // "Electronics"
console.log(item.label); // "Electronics"
console.log(item.count); // 142
console.log(item.isRefined); // true/false
console.log(item.data); // Nested items or null
});
Function to select a menu item.const { refine } = useHierarchicalMenu({
attributes: ['category'],
});
refine('Electronics > Phones');
Whether refinements can be applied.
Whether “show more” is currently active.
Function to toggle between showing more/less items.
Whether the “show more” toggle is available.
createURL
(value: string) => string
Function to create a URL for a menu item.
Function to send Insights events.
Examples
import { useHierarchicalMenu } from 'react-instantsearch';
function CategoryMenu() {
const { items, refine } = useHierarchicalMenu({
attributes: [
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
'hierarchicalCategories.lvl2',
],
});
function renderItems(items) {
return (
<ul>
{items.map((item) => (
<li key={item.value}>
<button
onClick={() => refine(item.value)}
style={{ fontWeight: item.isRefined ? 'bold' : 'normal' }}
>
{item.label} ({item.count})
</button>
{item.data && renderItems(item.data)}
</li>
))}
</ul>
);
}
return (
<div>
<h3>Categories</h3>
{renderItems(items)}
</div>
);
}
With Show More
import { useHierarchicalMenu } from 'react-instantsearch';
function ExpandableHierarchicalMenu() {
const {
items,
refine,
toggleShowMore,
isShowingMore,
canToggleShowMore,
} = useHierarchicalMenu({
attributes: ['category.lvl0', 'category.lvl1'],
limit: 5,
showMore: true,
showMoreLimit: 15,
});
function renderItems(items) {
return (
<ul>
{items.map((item) => (
<li key={item.value}>
<button onClick={() => refine(item.value)}>
{item.label} ({item.count})
</button>
{item.data && renderItems(item.data)}
</li>
))}
</ul>
);
}
return (
<div>
<h3>Categories</h3>
{renderItems(items)}
{canToggleShowMore && (
<button onClick={toggleShowMore}>
{isShowingMore ? 'Show less' : 'Show more'}
</button>
)}
</div>
);
}
With Expansion Icons
import { useHierarchicalMenu } from 'react-instantsearch';
function HierarchicalMenuWithIcons() {
const { items, refine } = useHierarchicalMenu({
attributes: ['category.lvl0', 'category.lvl1', 'category.lvl2'],
});
function renderItems(items) {
return (
<ul className="hierarchical-menu">
{items.map((item) => (
<li key={item.value}>
<div className="menu-item">
{item.data && (
<span className="icon">
{item.isRefined ? '▼' : '▶'}
</span>
)}
<button
onClick={() => refine(item.value)}
className={item.isRefined ? 'refined' : ''}
>
{item.label} ({item.count})
</button>
</div>
{item.isRefined && item.data && renderItems(item.data)}
</li>
))}
</ul>
);
}
return <div>{renderItems(items)}</div>;
}
TypeScript
import { useHierarchicalMenu } from 'react-instantsearch';
import type { UseHierarchicalMenuProps } from 'react-instantsearch';
function CategoryMenu(props: UseHierarchicalMenuProps) {
const { items, refine } = useHierarchicalMenu(props);
function renderItems(items: typeof items): JSX.Element {
return (
<ul>
{items.map((item) => (
<li key={item.value}>
<button onClick={() => refine(item.value)}>
{item.label}
</button>
{item.data && renderItems(item.data)}
</li>
))}
</ul>
);
}
return renderItems(items);
}