# Navbar 1

> A clean marketing navbar with a sheet menu on mobile

A shadcn/ui block from the [@shadcnstore](https://www.shadcnstore.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/shadcnstore/navbar-1).

- Page, with a live preview: https://shadcn.exchange/r/shadcnstore/navbar-1
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/shadcnstore/navbar-1-light-b681973b685cd80d.png
- Registry item: https://shadcnstore.com/r/navbar-1.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://shadcnstore.com/r/navbar-1.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`
- Registry items: `button`, `separator`, `sheet`

## Files

### `storage/app/registry-sources/marketing/navbars/navbar-1/page.tsx`

```tsx
import { Navbar1 } from "@/components/blocks/marketing/navbars/navbar-1/components/navbar-1"

export default function Page() {
  return (
    <div className="min-h-svh w-full">
      <Navbar1 />
    </div>
  )
}
```

### `storage/app/registry-sources/marketing/navbars/navbar-1/navbar-1.tsx`

```tsx
'use client'

import { useState } from 'react'
import { Menu } from 'lucide-react'

import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator'
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/components/ui/sheet'
import { cn } from '@/lib/utils'

import { navLinks } from "@/components/data/navbar-1-data"

/**
 * Swap these four values (and `Logo` below) to rebrand the header.
 * `currentPath` is what drives the active-link styling and `aria-current` —
 * wire it to your router (`usePathname()` in Next.js, `useLocation()` in React Router).
 */
const currentPath = '#product'
const signIn = { label: 'Sign in', href: '#sign-in' }
const cta = { label: 'Get started', href: '#get-started' }

function Logo() {
  return (
    <a
      href='#home'
      className='focus-visible:ring-ring flex items-center gap-2 rounded-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none'
    >
      <svg viewBox='0 0 32 32' aria-hidden='true' className='text-primary size-7' fill='none' xmlns='http://www.w3.org/2000/svg'>
        <path
          d='M26 24.75C26.4142 24.75 26.75 24.4142 26.75 24C26.75 23.5858 26.4142 23.25 26 23.25V24.75ZM26 23.25H11V24.75H26V23.25ZM8.75 21V15H7.25V21H8.75ZM11 23.25C9.75736 23.25 8.75 22.2426 8.75 21H7.25C7.25 23.0711 8.92893 24.75 11 24.75V23.25Z'
          fill='currentColor'
        />
        <path
          d='M1.5 3.25C1.08579 3.25 0.75 3.58579 0.75 4C0.75 4.41421 1.08579 4.75 1.5 4.75V3.25ZM1.5 4.75H6V3.25H1.5V4.75ZM7.25 6V21H8.75V6H7.25ZM6 4.75C6.69036 4.75 7.25 5.30964 7.25 6H8.75C8.75 4.48122 7.51878 3.25 6 3.25V4.75Z'
          fill='currentColor'
        />
        <path
          d='M22 21.75C22.4142 21.75 22.75 21.4142 22.75 21C22.75 20.5858 22.4142 20.25 22 20.25V21.75ZM22 20.25H11V21.75H22V20.25ZM8.75 18V12H7.25V18H8.75ZM11 20.25C9.75736 20.25 8.75 19.2426 8.75 18H7.25C7.25 20.0711 8.92893 21.75 11 21.75V20.25Z'
          fill='currentColor'
        />
        <path
          d='M27.2057 19.754C27.0654 20.1438 26.6357 20.346 26.246 20.2057C25.8562 20.0654 25.654 19.6357 25.7943 19.246L27.2057 19.754ZM30.0361 9.67744L29.3305 9.4234L29.3305 9.4234L30.0361 9.67744ZM25.7943 19.246L29.3305 9.4234L30.7418 9.93148L27.2057 19.754L25.7943 19.246ZM28.1543 7.75L8 7.75V6.25L28.1543 6.25V7.75ZM29.3305 9.4234C29.6237 8.60882 29.0201 7.75 28.1543 7.75V6.25C30.059 6.25 31.3869 8.13941 30.7418 9.93148L29.3305 9.4234Z'
          fill='currentColor'
        />
        <path
          d='M13.5 21.75C13.0858 21.75 12.75 21.4142 12.75 21C12.75 20.5858 13.0858 20.25 13.5 20.25V21.75ZM26.7111 19.009L27.4174 19.2613L27.4174 19.2613L26.7111 19.009ZM13.5 20.25H23.8858V21.75H13.5V20.25ZM26.0048 18.7568L27.7937 13.7477L29.2063 14.2523L27.4174 19.2613L26.0048 18.7568ZM23.8858 20.25C24.8367 20.25 25.6849 19.6522 26.0048 18.7568L27.4174 19.2613C26.8843 20.7537 25.4706 21.75 23.8858 21.75V20.25Z'
          fill='currentColor'
        />
        <path d='M21.1694 10.5806L14.5651 17.1849' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' />
        <path d='M22.1694 14.5806L18.5632 18.1868' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' />
        <circle cx='13.1' cy='26.1' r='1.7' stroke='currentColor' strokeWidth='1.2' />
        <circle cx='22.1' cy='26.1' r='1.7' stroke='currentColor' strokeWidth='1.2' />
      </svg>
      <span className='text-base font-semibold tracking-tight'>ShadcnStore</span>
    </a>
  )
}

export function Navbar1() {
  const [open, setOpen] = useState(false)

  return (
    <header className='border-border bg-background w-full border-b'>
      <div className='mx-auto flex h-16 w-full max-w-7xl items-center justify-between gap-4 px-4 sm:px-6 lg:px-8'>
        <Logo />

        <nav aria-label='Main' className='hidden lg:block'>
          <ul className='flex items-center gap-1'>
            {navLinks.map(link => {
              const isActive = link.href === currentPath

              return (
                <li key={link.href}>
                  <a
                    href={link.href}
                    aria-current={isActive ? 'page' : undefined}
                    className={cn(
                      'hover:text-foreground focus-visible:ring-ring rounded-md px-3 py-2 text-sm font-medium transition-colors duration-150 ease-out focus-visible:ring-2 focus-visible:outline-none',
                      isActive ? 'text-foreground' : 'text-muted-foreground'
                    )}
                  >
                    {link.label}
                  </a>
                </li>
              )
            })}
          </ul>
        </nav>

        <div className='hidden items-center gap-2 lg:flex'>
          <Button variant='ghost' size='sm' nativeButton={false} render={<a href={signIn.href} />}>
            {signIn.label}
          </Button>
          <Button size='sm' nativeButton={false} render={<a href={cta.href} />}>
            {cta.label}
          </Button>
        </div>

        <Sheet open={open} onOpenChange={setOpen}>
          <SheetTrigger
            className='lg:hidden'
            render={<Button variant='ghost' size='icon' aria-label='Open menu' />}
          >
            <Menu />
          </SheetTrigger>
          <SheetContent side='right' className='w-full max-w-xs p-0'>
            <SheetHeader className='border-border border-b'>
              <SheetTitle className='text-left text-base'>Menu</SheetTitle>
            </SheetHeader>

            {/* Mobile gets its own hierarchy: large touch targets, then CTAs pinned as full-width actions. */}
            <nav aria-label='Mobile' className='flex flex-col px-2 py-2'>
              {navLinks.map(link => {
                const isActive = link.href === currentPath

                return (
                  <SheetClose
                    key={link.href}
                    render={
                      <a
                        href={link.href}
                        aria-current={isActive ? 'page' : undefined}
                        className={cn(
                          'hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring rounded-md px-3 py-3 text-base font-medium transition-colors duration-150 ease-out focus-visible:ring-2 focus-visible:outline-none',
                          isActive ? 'text-foreground' : 'text-muted-foreground'
                        )}
                      />
                    }
                  >
                    {link.label}
                  </SheetClose>
                )
              })}
            </nav>

            <div className='mt-auto flex flex-col gap-4 p-4'>
              <Separator />
              <div className='flex flex-col gap-2'>
                <SheetClose
                  render={
                    <Button
                      variant='outline'
                      className='w-full'
                      nativeButton={false}
                      render={<a href={signIn.href} />}
                    />
                  }
                >
                  {signIn.label}
                </SheetClose>
                <SheetClose
                  render={<Button className='w-full' nativeButton={false} render={<a href={cta.href} />} />}
                >
                  {cta.label}
                </SheetClose>
              </div>
            </div>
          </SheetContent>
        </Sheet>
      </div>
    </header>
  )
}

/**
 * Preview scaffold — `Navbar1` above is the product. This page body only exists so the
 * mobile sheet has somewhere to open into. Delete it and `export default Navbar1`
 * once the header sits on a real page.
 */
export default function Navbar1Preview() {
  return (
    <div className='bg-background'>
      <Navbar1 />
      <div className='mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8'>
        <div className='bg-muted/40 border-border h-96 rounded-xl border' />
      </div>
    </div>
  )
}
```

### `storage/app/registry-sources/marketing/navbars/navbar-1/navbar-1-data.ts`

```ts
export interface NavLink {
  label: string
  href: string
}

/**
 * The single edit point for this navbar's menu.
 * `navbar-3` uses the same shape, so variants can be swapped without rewriting data.
 */
export const navLinks: NavLink[] = [
  { label: 'Product', href: '#product' },
  { label: 'Pricing', href: '#pricing' },
  { label: 'Blog', href: '#blog' },
  { label: 'Docs', href: '#docs' },
  { label: 'Changelog', href: '#changelog' },
]
```
