Navbar
A floating top navigation bar with scroll-spy links, control slots, auth buttons, and a mobile menu.
A floating top navigation bar: a logo, center links with scroll-spy and active-link styling, theme/language control slots, and auth buttons with a built-in mobile menu. Links are plain data (NavLink[]), and navigation goes through the configured Link adapter. It manages its own mobile-menu state.
Import
1import { Navbar } from "@yuhuanowo/yunui/ai";Basic
The bar is fixed to the top of the viewport. Provide links and an appName; the host supplies routing through the adapters.
Basic
Minimal variant
Use variant="minimal" to drop the center links and auth buttons — useful for auth or onboarding flows.
Minimal variant
Slots
The bar is built for hosts that need more than a logo and links. Each slot is optional; leave them off and nothing changes.
| Slot | Where it lands |
|---|---|
brand | Replaces the logo + wordmark inside the home link — pass a mark-only logo or a custom lockup. |
actions | Extra controls in the right cluster, before the language/theme pills. Desktop only, like the rest of that cluster. |
languageSwitcher / themeToggle | The two standard pills. |
account | Signed-in control; replaces the sign in / sign up pair on desktop and mobile. |
mobileMenuHeader | Top of the mobile menu, above the links. |
mobileMenuFooter | Bottom of the mobile menu. Replaces the automatic language row there, so you can lay that row out yourself. |
label | Accessible name for the <nav> landmark — needed on any page with more than one nav. |
These exist because two apps forked this component rather than use it: YunUI's own site needed a mark-only brand and a GitHub link, and YunNEWS needed a search button. Neither was expressible, so both copied the bar. That is a design failure in the API, not in the consumers — the slots are the fix.
1<Navbar2 appName="YunUI"3 brand={<Logo size={24} />}4 links={NAV_LINKS}5 currentPath={pathname}6 actions={<GithubLink />}7 languageSwitcher={<LanguageSwitcher variant="pill" … />}8 mobileMenuFooter={9 <div className="flex items-center justify-between px-2 py-1">10 <LanguageSwitcher variant="pill" … />11 <GithubLink />12 </div>13 }14/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| account | ReactNode | — | Signed-in account control — pass an `AccountMenu`. When present it REPLACES the sign in / sign up buttons (desktop and mobile), so a reader who is already signed in sees their avatar rather than an invitation to sign in again. |
| actions | ReactNode | — | Extra controls in the right-hand cluster, before the language/theme pills — a GitHub link, a search button. Desktop only, matching the rest of that cluster; put the mobile equivalent in `mobileMenuHeader`. |
| appName* | string | — | Brand name shown next to the logo. |
| brand | ReactNode | — | Replaces the logo + wordmark block entirely. Pass a mark-only logo, a custom lockup, anything — it is still wrapped in the link to `homeHref`. Without this, a brand that is a single glyph had to be faked through `logoSrc`/`appName`, which is why YunUI's own site and YunNEWS each kept a private copy of this bar. |
| className | string | — | Extra classes on the `<nav>` element. |
| currentPath | string | / | Current route, used for active-link + scroll-spy. |
| homeHref | string | / | Where the logo links to. |
| label | string | — | Accessible name for the `<nav>` landmark. A page with more than one nav needs each one named, or a screen reader offers several identical "navigation" regions. |
| labels | { signIn?: string; signUp?: string; menu?: string | undefined; } | undefined | — | Localized auth labels. |
| languageSwitcher | ReactNode | — | Right-side control slots; the host injects the configured switcher. |
| links | NavLink[] | [] | Center navigation links. The host builds these from branding/flags/i18n. |
| loginHref | string | /login | Sign-in link destination. |
| logoSrc | string | /favicon.ico | Logo image src (default: /favicon.ico). |
| mobileMenuFooter | ReactNode | — | The bottom region of the mobile menu, under the divider. Passing this REPLACES the automatic `languageSwitcher` row there — so a host that wants the language pill alongside something else (a GitHub link, a status chip) lays that row out itself instead of getting two rows. Leave it off and the language row appears on its own, as before. |
| mobileMenuHeader | ReactNode | — | Rendered at the TOP of the mobile menu, above the links. |
| signupHref | string | /signup | Sign-up link destination. |
| themeToggle | ReactNode | — | Defaults to YunUI's ThemeToggle. |
| variant | "public" | "minimal" | public | `public` (full nav + auth) or `minimal` (no links/auth). |