Navbar SaaS

SaaS-style navigation bar with branding and links.

Report a bug

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Installation

pnpm dlx shadcn@latest add https://ui.vllnt.ai/r/navbar-saas.json

Storybook

Explore all variants, controls, and accessibility checks in the interactive Storybook playground.

View in Storybook

Code

"use client"; import { Menu, X } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; import type { ReactNode } from "react"; import { cn } from "../../lib/utils"; import { Button } from "../button/button"; import { useSidebar } from "../sidebar-provider"; import { ThemeToggle } from "../theme-toggle"; export type NavItem = { href: string; title: string; }; export type NavbarSaasProps = { brand?: ReactNode; navItems?: NavItem[]; rightSlot?: ReactNode; showMobileMenu?: boolean; }; const EMPTY_NAV_ITEMS: NavItem[] = []; export function NavbarSaas({ brand, navItems = EMPTY_NAV_ITEMS, rightSlot, showMobileMenu = true, }: NavbarSaasProps) { const pathname = usePathname(); const { open, setOpen } = useSidebar(); return ( <header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 shrink-0"> <div className="w-full"> <div className="mx-auto flex h-16 items-center justify-between px-4"> <div className="flex items-center gap-4"> {showMobileMenu ? ( <Button aria-expanded={open} aria-label="Toggle sidebar" data-testid="navbar-saas-mobile-trigger" onClick={() => { setOpen(!open); }} size="icon" variant="ghost" > {open ? <X className="size-4" /> : <Menu className="size-4" />} </Button> ) : null} {brand ? ( typeof brand === "string" ? ( <Link className="text-xl font-bold truncate" href="/"> {brand} </Link> ) : ( brand ) ) : null} {navItems.length > 0 ? ( <nav className="hidden lg:flex gap-6"> {navItems.map((item) => ( <Link className={cn( "text-sm font-medium transition-colors hover:text-foreground/80", pathname === item.href ? "text-foreground" : "text-foreground/60", )} href={item.href} key={item.href} > {item.title} </Link> ))} </nav> ) : null} </div> <div className="flex items-center gap-4"> {rightSlot} <ThemeToggle dict={{ theme: { dark: "Dark", light: "Light", system: "System", toggle_theme: "Toggle theme", }, }} /> </div> </div> </div> </header> ); }

Dependencies

  • @vllnt/ui@^0.2.1