useMenu is a React hook that generates menu items based on your defined resources. It’s commonly used to build navigation menus and sidebars, automatically creating menu items with proper routes and labels.
Usage
import { useMenu } from "@refinedev/core";
const CustomSidebar = () => {
const { menuItems, selectedKey, defaultOpenKeys } = useMenu();
return (
<nav>
{menuItems.map((item) => (
<a key={item.key} href={item.route}>
{item.icon}
{item.label}
</a>
))}
</nav>
);
};
Parameters
Return Values
Array of menu items generated from your resources. Each item includes:Unique identifier for the menu item.
Display label for the menu item (from meta.label or translated resource name).
URL path for the menu item.
Icon element from resource meta.
Nested menu items (for resources with parent relationships).
The key of the currently active menu item, based on the current route and resource.
Array of keys that should be expanded by default, including the current resource and all its parent resources.
Examples
import { useMenu } from "@refinedev/core";
const Sidebar = () => {
const { menuItems } = useMenu();
return (
<aside>
<ul>
{menuItems.map((item) => (
<li key={item.key}>
<a href={item.route}>
{item.icon}
<span>{item.label}</span>
</a>
</li>
))}
</ul>
</aside>
);
};
import { useMenu } from "@refinedev/core";
const Sidebar = () => {
const { menuItems, selectedKey } = useMenu();
return (
<nav>
<ul>
{menuItems.map((item) => (
<li
key={item.key}
className={item.key === selectedKey ? "active" : ""}
>
<a href={item.route}>
{item.icon}
{item.label}
</a>
</li>
))}
</ul>
</nav>
);
};
import { useMenu } from "@refinedev/core";
const MenuItem = ({ item, selectedKey }) => {
const hasChildren = item.children.length > 0;
return (
<li>
<a
href={item.route}
className={item.key === selectedKey ? "active" : ""}
>
{item.icon}
{item.label}
</a>
{hasChildren && (
<ul>
{item.children.map((child) => (
<MenuItem
key={child.key}
item={child}
selectedKey={selectedKey}
/>
))}
</ul>
)}
</li>
);
};
const Sidebar = () => {
const { menuItems, selectedKey } = useMenu();
return (
<nav>
<ul>
{menuItems.map((item) => (
<MenuItem key={item.key} item={item} selectedKey={selectedKey} />
))}
</ul>
</nav>
);
};
import { useMenu } from "@refinedev/core";
import { useState } from "react";
const Sidebar = () => {
const { menuItems, selectedKey, defaultOpenKeys } = useMenu();
const [openKeys, setOpenKeys] = useState(defaultOpenKeys);
const toggleItem = (key: string) => {
setOpenKeys((prev) =>
prev.includes(key)
? prev.filter((k) => k !== key)
: [...prev, key]
);
};
return (
<nav>
<ul>
{menuItems.map((item) => (
<li key={item.key}>
<div onClick={() => toggleItem(item.key)}>
{item.icon}
{item.label}
</div>
{openKeys.includes(item.key) && item.children.length > 0 && (
<ul>
{item.children.map((child) => (
<li key={child.key}>
<a href={child.route}>{child.label}</a>
</li>
))}
</ul>
)}
</li>
))}
</ul>
</nav>
);
};
import { useMenu } from "@refinedev/core";
const Sidebar = () => {
const { menuItems } = useMenu({
meta: {
tenant: "company-1",
},
});
return (
<nav>
<ul>
{menuItems.map((item) => (
<li key={item.key}>
<a href={item.route}>{item.label}</a>
</li>
))}
</ul>
</nav>
);
};
API Reference
Type definitions:
export type UseMenuProps = {
meta?: Record<string, any>;
hideOnMissingParameter?: boolean;
};
export type TreeMenuItem = {
key: string;
name: string;
label?: string;
route?: string;
icon?: React.ReactNode;
children: TreeMenuItem[];
};
type UseMenuReturnType = {
defaultOpenKeys: string[];
selectedKey: string;
menuItems: TreeMenuItem[];
};
Menu items are automatically generated from resources defined in your <Refine> component. Resources with a list property will appear in the menu.
Use the meta.hide property on a resource to exclude it from the menu, or meta.label to customize the display text.