Command Palette

Search for a command to run...

Github

Navigation Menu

A collection of links for navigating websites.

import {
	CircleAlertIcon,
	CircleCheckIcon,
	CircleDashedIcon,
} from "lucide-react";
import Link from "next/link";
import type * as React from "react";

import {
	NavigationMenu,
	NavigationMenuContent,
	NavigationMenuItem,
	NavigationMenuLink,
	NavigationMenuList,
	NavigationMenuTrigger,
	navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";

const components: { title: string; href: string; description: string }[] = [
	{
		title: "Alert Dialog",
		href: "/docs/components/alert-dialog",
		description:
			"A modal dialog that interrupts the user with important content and expects a response.",
	},
	{
		title: "Hover Card",
		href: "/docs/components/hover-card",
		description:
			"For sighted users to preview content available behind a link.",
	},
	{
		title: "Progress",
		href: "/docs/components/progress",
		description:
			"Displays an indicator showing the completion progress of a task.",
	},
	{
		title: "Scroll-area",
		href: "/docs/components/scroll-area",
		description: "Visually or semantically separates content.",
	},
	{
		title: "Tabs",
		href: "/docs/components/tabs",
		description:
			"A set of layered sections of content displayed one at a time.",
	},
	{
		title: "Tooltip",
		href: "/docs/components/tooltip",
		description:
			"A popup that displays information related to an element on hover or focus.",
	},
];

export function NavigationMenuDemo() {
	return (
		<NavigationMenu>
			<NavigationMenuList>
				<NavigationMenuItem>
					<NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
					<NavigationMenuContent>
						<ul className="w-96">
							<ListItem href="/docs" title="Introduction">
								Re-usable components built with Tailwind CSS.
							</ListItem>
							<ListItem href="/docs/installation" title="Installation">
								How to install dependencies and structure your app.
							</ListItem>
							<ListItem href="/docs/components/typography" title="Typography">
								Styles for headings, paragraphs, lists...etc
							</ListItem>
						</ul>
					</NavigationMenuContent>
				</NavigationMenuItem>
				<NavigationMenuItem className="hidden md:flex">
					<NavigationMenuTrigger>Components</NavigationMenuTrigger>
					<NavigationMenuContent>
						<ul className="grid w-[400px] gap-2 md:w-[500px] md:grid-cols-2 lg:w-[600px]">
							{components.map((component) => (
								<ListItem
									key={component.title}
									title={component.title}
									href={component.href}
								>
									{component.description}
								</ListItem>
							))}
						</ul>
					</NavigationMenuContent>
				</NavigationMenuItem>
				<NavigationMenuItem>
					<NavigationMenuTrigger>With Icon</NavigationMenuTrigger>
					<NavigationMenuContent>
						<ul className="grid w-[200px]">
							<li>
								<NavigationMenuLink
									className="flex-row items-center gap-2"
									render={<Link href="#" />}
								>
									<CircleAlertIcon />
									Backlog
								</NavigationMenuLink>
								<NavigationMenuLink
									className="flex-row items-center gap-2"
									render={<Link href="#" />}
								>
									<CircleDashedIcon />
									To Do
								</NavigationMenuLink>
								<NavigationMenuLink
									className="flex-row items-center gap-2"
									render={<Link href="#" />}
								>
									<CircleCheckIcon />
									Done
								</NavigationMenuLink>
							</li>
						</ul>
					</NavigationMenuContent>
				</NavigationMenuItem>
				<NavigationMenuItem>
					<NavigationMenuLink
						className={navigationMenuTriggerStyle()}
						render={<Link href="/docs" />}
					>
						Docs
					</NavigationMenuLink>
				</NavigationMenuItem>
			</NavigationMenuList>
		</NavigationMenu>
	);
}

function ListItem({
	title,
	children,
	href,
	className,
	...props
}: React.ComponentPropsWithRef<"li"> & { href: string }) {
	return (
		<li className={className} {...props}>
			<NavigationMenuLink render={<Link href={href} />}>
				<div className="flex flex-col gap-1 text-sm">
					<div className="font-medium leading-none">{title}</div>
					<div className="line-clamp-2 text-muted-foreground">{children}</div>
				</div>
			</NavigationMenuLink>
		</li>
	);
}

Installation

pnpm dlx shadcn@latest add https://herocn.dev/r/navigation-menu.json

Usage

import {
  NavigationMenu,
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuTrigger,
} from "@/components/ui/navigation-menu"
<NavigationMenu>
  <NavigationMenuList>
    <NavigationMenuItem>
      <NavigationMenuTrigger>Item One</NavigationMenuTrigger>
      <NavigationMenuContent>
        <NavigationMenuLink href="#">Link</NavigationMenuLink>
      </NavigationMenuContent>
    </NavigationMenuItem>
  </NavigationMenuList>
</NavigationMenu>

Composition

Use the following composition to build a NavigationMenu:

NavigationMenu
├── NavigationMenuList
│   ├── NavigationMenuItem
│   │   ├── NavigationMenuTrigger
│   │   └── NavigationMenuContent
│   │       ├── NavigationMenuLink
│   │       └── NavigationMenuLink
│   └── NavigationMenuItem
│       └── NavigationMenuLink
└── NavigationMenuIndicator

Examples

Use the href prop to link to a page. For custom link components, use the render prop.

import Link from "next/link";
import {
	NavigationMenu,
	NavigationMenuItem,
	NavigationMenuLink,
	NavigationMenuList,
	navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";

export function NavigationMenuLinkDemo() {
	return (
		<NavigationMenu>
			<NavigationMenuList>
				<NavigationMenuItem>
					<NavigationMenuLink
						className={navigationMenuTriggerStyle()}
						render={<Link href="/docs" />}
					>
						Documentation
					</NavigationMenuLink>
				</NavigationMenuItem>
				<NavigationMenuItem>
					<NavigationMenuLink
						className={navigationMenuTriggerStyle()}
						render={<Link href="/docs/components" />}
					>
						Components
					</NavigationMenuLink>
				</NavigationMenuItem>
				<NavigationMenuItem>
					<NavigationMenuLink
						className={navigationMenuTriggerStyle()}
						render={<Link href="/docs/rtl" />}
					>
						RTL
					</NavigationMenuLink>
				</NavigationMenuItem>
			</NavigationMenuList>
		</NavigationMenu>
	);
}

RTL

"use client";

import {
	CircleAlertIcon,
	CircleCheckIcon,
	CircleDashedIcon,
} from "lucide-react";
import Link from "next/link";
import type * as React from "react";

import {
	type Translations,
	useTranslation,
} from "@/components/language-selector";
import {
	NavigationMenu,
	NavigationMenuContent,
	NavigationMenuItem,
	NavigationMenuLink,
	NavigationMenuList,
	NavigationMenuTrigger,
	navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";

const translations: Translations = {
	en: {
		dir: "ltr",
		values: {
			gettingStarted: "Getting started",
			introduction: "Introduction",
			introductionDesc: "Re-usable components built with Tailwind CSS.",
			installation: "Installation",
			installationDesc: "How to install dependencies and structure your app.",
			typography: "Typography",
			typographyDesc: "Styles for headings, paragraphs, lists...etc",
			withIcon: "With Icon",
			backlog: "Backlog",
			toDo: "To Do",
			done: "Done",
			docs: "Docs",
		},
	},
	ar: {
		dir: "rtl",
		values: {
			gettingStarted: "البدء",
			introduction: "مقدمة",
			introductionDesc:
				"مكونات قابلة لإعادة الاستخدام مبنية باستخدام Tailwind CSS.",
			installation: "التثبيت",
			installationDesc: "كيفية تثبيت التبعيات وتنظيم تطبيقك.",
			typography: "الطباعة",
			typographyDesc: "أنماط للعناوين والفقرات والقوائم...إلخ",
			withIcon: "مع أيقونة",
			backlog: "قائمة الانتظار",
			toDo: "المهام",
			done: "منجز",
			docs: "الوثائق",
		},
	},
	he: {
		dir: "rtl",
		values: {
			gettingStarted: "התחלה",
			introduction: "הקדמה",
			introductionDesc: "רכיבים לשימוש חוזר שנבנו עם Tailwind CSS.",
			installation: "התקנה",
			installationDesc: "כיצד להתקין תלויות ולבנות את האפליקציה שלך.",
			typography: "טיפוגרפיה",
			typographyDesc: "סגנונות לכותרות, פסקאות, רשימות...וכו'",
			withIcon: "עם אייקון",
			backlog: "רשימת המתנה",
			toDo: "לעשות",
			done: "הושלם",
			docs: "תיעוד",
		},
	},
};

export function NavigationMenuRtl() {
	const { dir, t, language } = useTranslation(translations, "ar");

	return (
		<NavigationMenu dir={dir} align={dir === "rtl" ? "end" : "start"}>
			<NavigationMenuList>
				<NavigationMenuItem>
					<NavigationMenuTrigger>{t.gettingStarted}</NavigationMenuTrigger>
					<NavigationMenuContent
						dir={dir}
						data-lang={dir === "rtl" ? language : undefined}
					>
						<ul className="w-96">
							<ListItem href="/docs" title={t.introduction}>
								{t.introductionDesc}
							</ListItem>
							<ListItem href="/docs/installation" title={t.installation}>
								{t.installationDesc}
							</ListItem>
							<ListItem href="/docs/components/typography" title={t.typography}>
								{t.typographyDesc}
							</ListItem>
						</ul>
					</NavigationMenuContent>
				</NavigationMenuItem>
				<NavigationMenuItem>
					<NavigationMenuTrigger>{t.withIcon}</NavigationMenuTrigger>
					<NavigationMenuContent
						dir={dir}
						data-lang={dir === "rtl" ? language : undefined}
					>
						<ul className="grid w-[200px]">
							<li>
								<NavigationMenuLink
									className="flex-row items-center gap-2"
									render={<Link href="#" />}
								>
									<CircleAlertIcon />
									{t.backlog}
								</NavigationMenuLink>
								<NavigationMenuLink
									className="flex-row items-center gap-2"
									render={<Link href="#" />}
								>
									<CircleDashedIcon />
									{t.toDo}
								</NavigationMenuLink>
								<NavigationMenuLink
									className="flex-row items-center gap-2"
									render={<Link href="#" />}
								>
									<CircleCheckIcon />
									{t.done}
								</NavigationMenuLink>
							</li>
						</ul>
					</NavigationMenuContent>
				</NavigationMenuItem>
				<NavigationMenuItem>
					<NavigationMenuLink
						className={navigationMenuTriggerStyle()}
						data-lang={dir === "rtl" ? language : undefined}
						render={<Link href="/docs" />}
					>
						{t.docs}
					</NavigationMenuLink>
				</NavigationMenuItem>
			</NavigationMenuList>
		</NavigationMenu>
	);
}

function ListItem({
	title,
	children,
	href,
	...props
}: React.ComponentPropsWithoutRef<"li"> & { href: string }) {
	return (
		<li {...props}>
			<NavigationMenuLink render={<Link href={href} />}>
				<div className="flex flex-col gap-1 text-sm">
					<div className="font-medium leading-none">{title}</div>
					<div className="line-clamp-2 text-muted-foreground">{children}</div>
				</div>
			</NavigationMenuLink>
		</li>
	);
}

API Reference

See the Base UI Navigation Menu documentation.