Overview
The Navbar component provides a responsive horizontal navigation bar typically placed at the top of an application. It offers flexible layout sections for organizing navigation items, branding, and action buttons.
Use cases
- Display site-wide navigation and branding
- Provide access to primary navigation links
- Show user account controls and settings
- Display search inputs and action buttons
- Create consistent navigation across pages
- Build responsive mobile-friendly headers
Anatomy
The Navbar component is composed of:
Navbar - Root navigation container
Navbar.Start - Left-aligned section for logos and primary navigation
Navbar.End - Right-aligned section for actions and user controls
Navbar (root)
When true, the navbar will stick to the top of the viewport when scrolling.
Additional CSS class names to apply to the navbar container.
Navbar.Start
Accessible label for the start section. When provided, the section will have a group role.
Additional CSS class names to apply to the start section.
Spacing between items in the start section. Defaults to 5.
Navbar.End
Accessible label for the end section. When provided, the section will have a group role.
Additional CSS class names to apply to the end section.
Spacing between items in the end section. Defaults to 5.
Basic navbar
import { Navbar, Button } from '@raystack/apsara';
function App() {
return (
<Navbar>
<Navbar.Start>
<div className="logo">MyApp</div>
<a href="/features">Features</a>
<a href="/pricing">Pricing</a>
<a href="/docs">Docs</a>
</Navbar.Start>
<Navbar.End>
<Button variant="ghost">Sign In</Button>
<Button>Sign Up</Button>
</Navbar.End>
</Navbar>
);
}
Sticky navbar
import { Navbar } from '@raystack/apsara';
function App() {
return (
<Navbar sticky>
<Navbar.Start>
<div className="logo">MyApp</div>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</Navbar.Start>
<Navbar.End>
<button>Menu</button>
</Navbar.End>
</Navbar>
);
}
With search and actions
import { Navbar, Search, IconButton, Avatar } from '@raystack/apsara';
import { BellIcon, MagnifyingGlassIcon } from '@radix-ui/react-icons';
function App() {
return (
<Navbar>
<Navbar.Start>
<img src="/logo.svg" alt="Logo" height={32} />
<Search placeholder="Search..." />
</Navbar.Start>
<Navbar.End>
<IconButton variant="ghost">
<MagnifyingGlassIcon />
</IconButton>
<IconButton variant="ghost">
<BellIcon />
</IconButton>
<Avatar fallback="JD" />
</Navbar.End>
</Navbar>
);
}
import { Navbar, Menu, Avatar } from '@raystack/apsara';
function App() {
return (
<Navbar>
<Navbar.Start>
<h1>Dashboard</h1>
</Navbar.Start>
<Navbar.End>
<Menu>
<Menu.Trigger>
<Avatar fallback="JD" />
</Menu.Trigger>
<Menu.Content>
<Menu.Item>Profile</Menu.Item>
<Menu.Item>Settings</Menu.Item>
<Menu.Separator />
<Menu.Item>Logout</Menu.Item>
</Menu.Content>
</Menu>
</Navbar.End>
</Navbar>
);
}
With accessible sections
import { Navbar } from '@raystack/apsara';
function App() {
return (
<Navbar>
<Navbar.Start aria-label="Primary navigation">
<a href="/">Home</a>
<a href="/products">Products</a>
<a href="/services">Services</a>
</Navbar.Start>
<Navbar.End aria-label="User actions">
<button>Account</button>
<button>Cart</button>
</Navbar.End>
</Navbar>
);
}
Mobile responsive navbar
import { Navbar, Button, Drawer } from '@raystack/apsara';
import { HamburgerMenuIcon } from '@radix-ui/react-icons';
import { useState } from 'react';
function App() {
const [open, setOpen] = useState(false);
return (
<>
<Navbar sticky>
<Navbar.Start>
<div className="logo">MyApp</div>
<nav className="desktop-nav">
<a href="/features">Features</a>
<a href="/pricing">Pricing</a>
</nav>
</Navbar.Start>
<Navbar.End>
<Button className="mobile-menu" onClick={() => setOpen(true)}>
<HamburgerMenuIcon />
</Button>
<div className="desktop-actions">
<Button variant="ghost">Sign In</Button>
<Button>Sign Up</Button>
</div>
</Navbar.End>
</Navbar>
<Drawer open={open} onOpenChange={setOpen}>
<Drawer.Content>
<nav>
<a href="/features">Features</a>
<a href="/pricing">Pricing</a>
<a href="/docs">Docs</a>
</nav>
</Drawer.Content>
</Drawer>
</>
);
}
With custom spacing
import { Navbar } from '@raystack/apsara';
function App() {
return (
<Navbar>
<Navbar.Start gap={8}>
<div>Logo</div>
<a href="/home">Home</a>
<a href="/about">About</a>
</Navbar.Start>
<Navbar.End gap={3}>
<button>Login</button>
<button>Signup</button>
</Navbar.End>
</Navbar>
);
}
Accessibility
- Uses semantic
<nav> element with role="navigation" attribute
- Automatically includes proper navigation landmarks for screen readers
- Supports
aria-label on start and end sections for better context
- Keyboard navigation works naturally with focusable elements
- Sticky navbar maintains focus management during scroll
Styling customization
Customize the navbar appearance using className props:
<Navbar className="custom-navbar">
<Navbar.Start className="custom-start">
{/* Content */}
</Navbar.Start>
<Navbar.End className="custom-end">
{/* Content */}
</Navbar.End>
</Navbar>
The component uses CSS modules internally and exposes data attributes for styling:
/* Style sticky navbar */
nav[data-sticky] {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}