Skip to main content

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

Props

sticky
boolean
default:"false"
When true, the navbar will stick to the top of the viewport when scrolling.
className
string
Additional CSS class names to apply to the navbar container.
aria-label
string
Accessible label for the start section. When provided, the section will have a group role.
className
string
Additional CSS class names to apply to the start section.
gap
number | string
Spacing between items in the start section. Defaults to 5.
aria-label
string
Accessible label for the end section. When provided, the section will have a group role.
className
string
Additional CSS class names to apply to the end section.
gap
number | string
Spacing between items in the end section. Defaults to 5.

Usage

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>
  );
}
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>
  );
}

With dropdown menu

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);
}