A bar with a wordmark, plain links, a Resources trigger and a small button. Resources drops a full-width panel topped by a search input that filters three groups of described links as you type, with an empty state line. On phones an overlay opens with a live search field over the same groups. The groups stay in the markup and the filter only hides them with CSS.
A bar with a wordmark, plain links, a Resources trigger and a small button. Resources drops a full-width panel whose search input filters three groups of described links live, and on phones an overlay opens with the same live search field above the groups.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://beste.dev/r/navbar92?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://beste.dev/r-base/navbar92?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/navbar92.tsx plus the shadcn button and input primitives it uses.
The installed file exports navbar92Demo alongside the block: the exact props behind the preview above. Spread it to get a working navbar in one line.
import { Navbar92, navbar92Demo } from "@/components/beste/block/navbar92";
export default function Page() {
return <Navbar92 {...navbar92Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Navbar92 } from "@/components/beste/block/navbar92";
export default function Page() {
return (
<Navbar92
brand="Kestrel"
resources={{
label: "Resources",
heading: "Find a guide, a reference or a story",
groups: [
{
title: "Learn",
links: [
{ title: "Guides", description: "Step by step walkthroughs.", href: "/guides" },
{ title: "Webinars", description: "Live sessions every month.", href: "/webinars" },
],
},
{
title: "Build",
links: [{ title: "API reference", description: "Every endpoint, with examples.", href: "/api" }],
},
],
}}
links={[
{ label: "Product", href: "/product" },
{ label: "Pricing", href: "/pricing" },
]}
button={{ label: "Get started", href: "/signup" }}
labels={{ search: "Search resources", empty: "No resources match that search.", clear: "Clear search", open: "Open menu", close: "Close menu" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
brand | string | – | Wordmark on the left |
resources | ResourcesMenu | – | The trigger label, panel heading and the searchable link groups |
links | NavItem[] | [] | Plain links before the Resources trigger |
button | NavItem | – | Small action on the right, repeated at the foot of the mobile overlay |
labels | { search?: string; empty?: string; clear?: string; open?: string; close?: string } | {} | Search placeholder, empty state line and accessible names for the clear button and the menu toggle |
className | string | – | Extra classes for the outer <header> |
type ResourcesMenu = {
label: string;
heading?: string;
groups: ResourceGroup[];
};
type ResourceGroup = {
title: string;
links: ResourceLink[];
};
type ResourceLink = {
title: string;
description: string;
href: string;
};
type NavItem = {
label: string;
href: string;
};invisible opacity-0 to visible opacity-100), so every resource link is in the HTML before any script runs.hidden; nothing is unmounted, so the unfiltered groups are the server output.role="status" empty line appears; the clear button fades in once there is a query.inert while closed, locks body scroll while open, hides the plain links while a query is active and closes when any link is tapped.