Navbar Playground

Showcase, tweak, and document the new @anvilkit/navbar component from a real demo app surface.

This route pairs a default demo, a live configuration panel, and copy-ready code examples. Preview links are intercepted here so you can experiment safely without leaving the page.

How to use this page
Start with the default navbar, then adjust props live in the panel.

Included controls

Swap between text, image, and custom logo modes, add or remove menu items, and tune CTA variants, size, and state.

Code section

The live snippet tracks your current configuration, while the static examples cover minimal, composed, and responsive usage.

Current API

The navbar ships flat navigation links and action buttons. If you need dropdown-heavy navigation, compose it alongside the navbar rather than pushing that complexity into its base props.

Basic Demo

The default package state with a sample brand, centered links, and a single right-side signup action.

Left

Logo section

Accepts text or image props today, plus a React node override when the consumer wants a custom lockup.

Center

Navigation menu

Uses a concise items prop made of { label, href } objects and an optional active match.

Right

Action buttons

Multiple CTAs are supported with button variant, size, href, and disabled state baked into the array shape.

Interactive Configuration Panel

Modify the navbar in real time, then copy the generated JSX from the code examples section below.

Live Preview
This preview reflects your current control values.

Logo mode

text

Items

5 configured

Actions

1 configured

Preview tips
Useful behaviors to validate while you experiment.

1. Increase the number of items to confirm the center section still wraps cleanly on smaller widths.

2. Swap between image and custom logo modes to verify the left slot stays vertically aligned.

3. Mix button variants and disabled states to see how the right action cluster balances visually.

Logo Controls
Choose between text, image, and custom node presentation.
Logo mode
Logo href
Logo text
Text mode uses the logo string directly and keeps the prop surface fully serializable.
Navigation Items
Update labels, links, and which item should be marked active.

Item 1

Configure the label and destination for this link.

Label
Href

Item 2

Configure the label and destination for this link.

Label
Href

Item 3

Configure the label and destination for this link.

Label
Href

Item 4

Configure the label and destination for this link.

Label
Href

Item 5

Configure the label and destination for this link.

Label
Href
Action Buttons
Control the right-side CTAs, including variant, size, and disabled state.

Action 1

Keep button copy short so the cluster stays balanced.

Label
Href
Variant
Size

Code Examples

Use the live snippet to mirror your current test case, then reference the examples below for minimal usage, composed dropdown patterns, and responsive page integration.

Live configuration
Mirrors the current state of the interactive controls.
import { Navbar } from "@anvilkit/navbar";
export function SiteHeader() {
  return (
    <Navbar
      logo={{ type: "text", text: "Underline", href: "/" }}
      items={[
        { label: "Overview", href: "/overview" },
        { label: "Features", href: "/features" },
        { label: "Integrations", href: "/integrations" },
        { label: "Customers", href: "/customers" },
        { label: "Changelog", href: "/changelog" },
      ]}
      actions={[
        { label: "Sign up", href: "/signup" },
      ]}
      active="/features"
    />
  );
}
Logo only
A stripped-down brand bar when the page already carries its own local navigation.
import { Navbar } from "@anvilkit/navbar";

export function MinimalHeader() {
  return (
    <Navbar
      logo={{ type: "text", text: "Sandbox", href: "/" }}
      items={[]}
      actions={[]}
    />
  );
}
Composed with dropdown menus
The navbar keeps its API flat, while dropdown-heavy navigation is composed around it.
import { Navbar } from "@anvilkit/navbar";
import {
  Menubar,
  MenubarContent,
  MenubarItem,
  MenubarMenu,
  MenubarTrigger,
} from "@anvilkit/ui/menubar";

export function DocsNavigation() {
  return (
    <div className="space-y-3">
      <Navbar
        logo={{ type: "text", text: "Underline Docs", href: "/" }}
        items={[
          { label: "Guides", href: "/guides" },
          { label: "API", href: "/api" },
        ]}
        actions={[{ label: "Launch app", href: "/app", variant: "secondary" }]}
        active="/api"
      />

      <Menubar>
        <MenubarMenu>
          <MenubarTrigger>Resources</MenubarTrigger>
          <MenubarContent>
            <MenubarItem>Components</MenubarItem>
            <MenubarItem>Templates</MenubarItem>
            <MenubarItem>Release notes</MenubarItem>
          </MenubarContent>
        </MenubarMenu>
      </Menubar>
    </div>
  );
}
Responsive layout
A realistic landing-page header that lets the component handle stacking and wrapping at smaller widths.
import { Navbar } from "@anvilkit/navbar";

export function LandingHeader() {
  return (
    <header className="px-4 py-4 sm:px-6 lg:px-10">
      <Navbar
        logo={{
          type: "image",
          imageUrl: "/turborepo-light.svg",
          alt: "Underline Studio",
          href: "/",
        }}
        items={[
          { label: "Overview", href: "/overview" },
          { label: "Pricing", href: "/pricing" },
          { label: "Customers", href: "/customers" },
          { label: "Changelog", href: "/changelog" },
        ]}
        actions={[
          { label: "Login", href: "/login", variant: "ghost", size: "default" },
          { label: "Start free", href: "/signup", variant: "secondary" },
        ]}
        active="/pricing"
      />
    </header>
  );
}
What this demo is exercising
A quick checklist for manual QA before shipping the package.

Layout balance

Verify the three sections stay readable with longer labels and multiple CTAs.

Prop ergonomics

Confirm the concise API still covers text, image, and custom logo use cases cleanly.

Composition story

Use the snippets to decide when the base navbar is enough and when surrounding UI primitives should take over.