docs/docs/guides/extending-the-dashboard/navigation/index.mdx
The dashboard provides a flexible navigation system that allows you to add custom navigation sections and menu items. Navigation items are organized into sections that can be placed in either the "Platform" (top) or "Administration" (bottom) areas of the sidebar.
The simplest way to add navigation is to add menu items to existing sections. This is done automatically when you define routes with navMenuItem properties.
import { defineDashboardExtension } from '@vendure/dashboard';
defineDashboardExtension({
routes: [
{
path: '/my-custom-page',
component: () => <div>My Custom Page</div>,
navMenuItem: {
// The section where this item should appear
sectionId: 'catalog',
// Unique identifier for this menu item
id: 'my-custom-page',
// Display text in the navigation
title: 'My Custom Page',
// Optional: URL if different from path
url: '/my-custom-page',
},
},
],
});
The dashboard comes with several built-in sections that can receive route navMenuItem entries:
catalog - For product-related functionalitysales - For order managementcustomers - For customer managementmarketing - For promotions and marketing toolssettings - For configuration and admin settingssystem - For system tools such as the job queue and scheduled tasksThe Insights entry has the ID insights, but it is a top-level navigation item, not a section with child items. Do not use insights as a route navMenuItem.sectionId.
You can find the available IDs & their order value for all navigation sections and items using Dev mode:
You can create entirely new navigation sections with their own icons and ordering:
import { defineDashboardExtension } from '@vendure/dashboard';
import { FileTextIcon, SettingsIcon } from 'lucide-react';
defineDashboardExtension({
// Define custom navigation sections
navSections: [
{
id: 'content-management',
title: 'Content',
icon: FileTextIcon,
placement: 'top', // Platform area
order: 350, // After Sales (300), before Customers (400)
},
{
id: 'integrations',
title: 'Integrations',
icon: SettingsIcon,
placement: 'bottom', // Administration area
order: 150, // Between System (100) and Settings (200)
},
],
routes: [
{
path: '/articles',
component: () => <div>Articles</div>,
navMenuItem: {
sectionId: 'content-management', // Use our custom section
id: 'articles',
title: 'Articles',
},
},
{
path: '/pages',
component: () => <div>Pages</div>,
navMenuItem: {
sectionId: 'content-management',
id: 'pages',
title: 'Pages',
},
},
],
});
For documentation on all the configuration properties available, see the reference docs:
The navigation sidebar is divided into two areas:
'top'): The "Platform" area for core functionality (Dashboard, Catalog, Sales, etc.)'bottom'): The "Administration" area for system and configuration sections (System, Settings)defineDashboardExtension({
navSections: [
{
id: 'reports',
title: 'Reports',
icon: BarChartIcon,
placement: 'top', // Appears in Platform area
order: 150, // Positioned within top sections
},
{
id: 'integrations',
title: 'Integrations',
icon: PlugIcon,
placement: 'bottom', // Appears in Administration area
order: 150, // Positioned within bottom sections
},
],
});
:::important Order Scoping Order values are scoped within each placement area. This means:
Top Placement (Platform):
Bottom Placement (Administration):
This means if you want to add a section between Catalog and Sales in the top area, you might use order: 250. If you want to add a section between Settings and System in the bottom area, you could use order: 150.
:::note[Default Placement]
If you don't specify a placement, sections default to 'top' placement.
:::
The navSections property can also be a function. Use this form when you need full control over the existing navigation structure, including moving, removing, renaming, or reordering built-in sections and items.
The function receives the fully registered navigation config after all array-form navSections and route navMenuItem registrations have been applied. Return a new config object rather than mutating the input.
import { defineDashboardExtension } from '@vendure/dashboard';
defineDashboardExtension({
navSections: config => ({
sections: config.sections.map(section => {
if (section.id === 'settings' && 'items' in section) {
return {
...section,
items: section.items?.filter(item => item.id !== 'administrators'),
};
}
return section;
}),
}),
});
import { defineDashboardExtension } from '@vendure/dashboard';
import { KeyRoundIcon } from 'lucide-react';
import type { NavMenuConfig } from '@vendure/dashboard';
defineDashboardExtension({
navSections: (config: NavMenuConfig): NavMenuConfig => {
const idsToMove = ['administrators', 'roles'];
const settingsSection = config.sections.find(section => section.id === 'settings');
const settingsItems =
settingsSection && 'items' in settingsSection ? (settingsSection.items ?? []) : [];
return {
sections: [
...config.sections.map(section => {
if (section.id === 'settings' && 'items' in section) {
return {
...section,
items: section.items?.filter(item => !idsToMove.includes(item.id)),
};
}
return section;
}),
{
id: 'access',
title: 'Access',
icon: KeyRoundIcon,
placement: 'bottom',
order: 150,
items: settingsItems.filter(item => idsToMove.includes(item.id)),
},
],
};
},
});
defineDashboardExtension({
navSections: config => ({
sections: config.sections.map(section =>
section.id === 'catalog' ? { ...section, title: 'Products' } : section,
),
}),
});
Use Dev Mode or the Extension Targets reference to find built-in navigation IDs.
By default, all navigation is assumed to be for authenticated routes, i.e. the routes are only accessible to administrators who are logged in.
Sometimes you want to make a certain route accessible to unauthenticated users. For example, you may want to implement a completely custom login page or a password recovery page, which must be accessible to everyone.
This is done by setting authenticated: false in your route definition:
import { defineDashboardExtension } from '@vendure/dashboard';
defineDashboardExtension({
routes: [
{
path: '/public',
component: () => (
<div className="flex h-screen items-center justify-center text-2xl">
This is a public page!
</div>
),
authenticated: false, // [!code highlight]
},
],
});
This page will then be accessible to all users at http://localhost:4873/dashboard/public
Here's a comprehensive example showing how to create a complete navigation structure for a content management system:
import { defineDashboardExtension } from '@vendure/dashboard';
import { FileTextIcon, ImageIcon, TagIcon, FolderIcon, SettingsIcon } from 'lucide-react';
defineDashboardExtension({
// Create custom navigation sections
navSections: [
{
id: 'content',
title: 'Content',
icon: FileTextIcon,
placement: 'top', // Platform area
order: 250, // Between Catalog (200) and Sales (300)
},
{
id: 'media',
title: 'Media',
icon: ImageIcon,
placement: 'top', // Platform area
order: 275, // After Content section
},
],
routes: [
// Content section items
{
path: '/articles',
component: () => <div>Articles List</div>,
navMenuItem: {
sectionId: 'content',
id: 'articles',
title: 'Articles',
},
},
{
path: '/pages',
component: () => <div>Pages List</div>,
navMenuItem: {
sectionId: 'content',
id: 'pages',
title: 'Pages',
},
},
{
path: '/categories',
component: () => <div>Categories List</div>,
navMenuItem: {
sectionId: 'content',
id: 'categories',
title: 'Categories',
},
},
// Media section items
{
path: '/media-library',
component: () => <div>Media Library</div>,
navMenuItem: {
sectionId: 'media',
id: 'media-library',
title: 'Library',
},
},
{
path: '/media-folders',
component: () => <div>Media Folders</div>,
navMenuItem: {
sectionId: 'media',
id: 'media-folders',
title: 'Folders',
},
},
// Add to existing settings section
{
path: '/cms-settings',
component: () => <div>CMS Settings</div>,
navMenuItem: {
sectionId: 'settings',
id: 'cms-settings',
title: 'CMS Settings',
},
},
],
});
The dashboard uses Lucide React icons. You can import any icon from the library:
import {
HomeIcon,
ShoppingCartIcon,
UsersIcon,
SettingsIcon,
FileTextIcon,
ImageIcon,
BarChartIcon,
// ... any other Lucide icon
} from 'lucide-react';
Common icons for navigation sections:
FileTextIcon, EditIcon, BookOpenIconImageIcon, FolderIcon, UploadIconBarChartIcon, TrendingUpIcon, PieChartIconWrenchIcon, SettingsIcon, CogIconLinkIcon, ZapIcon, PlugIcon:::tip[Navigation Design Guidelines]