Babelize Elements
ComponentsNavigation

Navbar

Full-featured navigation bar with built-in language selector, mobile menu, CTA button, and GitHub link.

Installation

bash npx shadcn@latest add @elements/navbar

Usage

import { NavBar } from "@/components/ui/navbar";
<NavBar
  logo={<span className="font-bold text-lg">MyApp</span>}
  links={[
    { label: "Home", href: "/" },
    { label: "Docs", href: "/docs" },
    { label: "Pricing", href: "/pricing" },
  ]}
  locales={[{ code: "en" }, { code: "fr" }, { code: "es" }]}
  value="en"
  onValueChange={(code) => console.log(code)}
  cta={{ label: "Get Started", href: "/signup" }}
  showGitHub
/>

Props

PropTypeRequiredDescription
logoReact.ReactNodeNoLogo element (renders before nav links)
linksNavLink[]NoNavigation links
localesLocale[]NoAvailable locales for language selector
valuestringNoSelected locale code โ€” pass this to control the component
defaultValuestringNoInitial locale code when uncontrolled (default: "en")
onValueChange(code: string) => voidNoCallback when locale changes
cta{ label: string; href: string }NoCTA button
showGitHubbooleanNoShow GitHub icon button
githubUrlstringNoGitHub repository URL
stickybooleanNoMake navbar sticky at top (default: true)
showFlagsbooleanNoShow flags in language selector (default: true)
linkComponentReact.ElementTypeNoComponent used for internal links (default: "a")
classNamestringNoAdditional CSS classes

Any other prop is spread onto the underlying <nav> element, and the ref is forwarded to it.

Client-side navigation

Links render as plain <a> elements, so NavBar works in any React app with no router installed. Pass your router's link component to opt into client-side navigation:

import Link from "next/link";

<NavBar links={links} linkComponent={Link} />;
PropertyTypeDescription
labelstringLink text โ€” required
hrefstringLink URL โ€” required

Locale Object

PropertyTypeDescription
codestringISO 639-1 / BCP 47 code (e.g. "en", "fr-FR") โ€” required
labelstringOverride display name (auto-resolved if omitted)
flagstringOverride flag emoji (auto-detected if omitted)

Examples

With Babelize SDK

Pair NavBar with the Babelize SDK for automatic locale routing:

"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { NavBar } from "@/components/ui/navbar";
import { useBabelize } from "@babelize/sdk/react";

const links = [
  { label: "Home", href: "/" },
  { label: "Docs", href: "/docs" },
  { label: "Pricing", href: "/pricing" },
];

const locales = [
  { code: "en" },
  { label: "English", flag: "๐Ÿ‡บ๐Ÿ‡ธ" },
  { label: "Franรงais", flag: "๐Ÿ‡ซ๐Ÿ‡ท" },
  { label: "Espaรฑol", flag: "๐Ÿ‡ช๐Ÿ‡ธ" },
  { label: "Deutsch", flag: "๐Ÿ‡ฉ๐Ÿ‡ช" },
  { label: "ๆ—ฅๆœฌ่ชž", flag: "๐Ÿ‡ฏ๐Ÿ‡ต" },
  { label: "ุงู„ุนุฑุจูŠุฉ", flag: "๐Ÿ‡ธ๐Ÿ‡ฆ" },
];

export default function App() {
  const router = useRouter();
  const { locale, setLocale } = useBabelize();

  return (
    <NavBar
      logo={<span className="font-bold">MyApp</span>}
      links={links}
      locales={locales}
      value={locale}
      onValueChange={(code) => {
        setLocale(code);
        router.push(`/${code}`);
      }}
      cta={{ label: "Get Started", href: "/signup" }}
      showGitHub
    />
  );
}

With next-intl

"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { NavBar } from "@/components/ui/navbar";

export function AppNavBar() {
  const router = useRouter();
  const [locale, setLocale] = useState("en");

  return (
    <NavBar
      logo={<span className="font-bold">MyApp</span>}
      links={[
        { label: "Home", href: "/" },
        { label: "About", href: "/about" },
      ]}
      locales={[{ code: "en" }, { code: "fr" }]}
      value={locale}
      onValueChange={(code) => {
        setLocale(code);
        router.push(`/${code}`);
      }}
    />
  );
}

With react-i18next

"use client";

import { useTranslation } from "react-i18next";
import { NavBar } from "@/components/ui/navbar";

export function AppNavBar() {
  const { i18n } = useTranslation();

  return (
    <NavBar
      logo={<span className="font-bold">MyApp</span>}
      links={[{ label: "Home", href: "/" }]}
      locales={[{ code: "en" }, { code: "fr" }]}
      value={i18n.language}
      onValueChange={(code) => i18n.changeLanguage(code)}
    />
  );
}

Non-sticky

"use client";

import { NavBar } from "@/components/ui/navbar";

export default function App() {
  return (
    <NavBar
      logo={<span className="font-bold">MyApp</span>}
      links={[{ label: "Home", href: "/" }]}
      sticky={false}
    />
  );
}

Features

  • Responsive โ€” hamburger menu on mobile, full layout on desktop
  • Built-in language selector โ€” same dropdown component as LanguageSwitcher
  • RTL-aware โ€” auto-detects RTL locales and adjusts layout
  • CTA button โ€” optional call-to-action with customizable text and href
  • GitHub link โ€” optional icon button linking to your repo
  • Sticky/non-sticky โ€” toggle top-of-page stickiness
  • Keyboard accessible โ€” arrow keys, Enter, Escape, Tab navigation
  • ARIA labels โ€” proper aria-expanded, aria-haspopup, aria-label
  • Dark mode โ€” built with Tailwind CSS, dark-mode compatible
  • Next.js Link โ€” uses next/link for client-side navigation

Dependencies

Peer dependencies:

  • react >= 18
  • react-dom >= 18
  • tailwindcss >= 3
  • next >= 13 (uses next/link)

Credits

Created by sapatmohit.

On this page