Navbar

A navbar is a component that helps you organize your content and navigation in a consistent way.

Basic

A navbar provides a variety of actions or options for users to select.

Installation

In the terminal, run the following command to begin:
npx hq-kit add navbar

Creating a Navbar

You can certainly create a single component to handle the entire navbar. However, in this guide, I'll show you how to build a navbar using modern techniques common in frameworks like Next.js, Inertia.js, and others.

App Navbar

When designing a layout, a navbar that links to all your pages is essential. Let's start with the simplest approach.

Layout

Next, you'll need to create a layout component that includes the navbar. Here's what it looks like:

Done

Great job! You've successfully created a navbar. Now, let's put it to use.

Using the Layout

There are several ways to use the layout, depending on your framework. Or, if you're not using any framework, you can simply apply the layout component.

Common Usage

A typical approach is to wrap your content with the layout like this:

<AppLayout>
  {/* your main content */}
</AppLayout>

Inertia.js

If you're using Inertia.js, you can implement a persistent layout. Here's how it looks:

Home.layout = (page: React.ReactNode) => <AppLayout children={page} />

Next.js

If you're using Next.js, there's no extra configuration needed. Simply create a page component and ensure it inherits the layout like this:

app/
├── app-navbar.tsx
├── layout.tsx
└── page.tsx

The logo is typically the first item in the navbar, usually representing the brand or company.

Current

Highlight the current page in the navbar for better navigation clarity.

Variant

There are three types of variants: navbar, floating, and inset, each with distinct behaviors.

The default variant of the navbar is navbar. You can change it to floating or inset by setting the variant prop.

Floating

The floating variant will have a border inside the navbar itself, the wrapper will have a padding to the content.

Inset

The inset one will have the padding to inset main content. You can of course see what's going on the demo, but you can also see the live example here.

Sticky

You also make the navbar sticky by setting the isSticky prop to true.

<Navbar isSticky />

Without Inset

If you prefer full control of your layout and don't want to use the <Navbar.Inset /> component which by default centers your content within a container, simply avoid using the inset variant. This allows you to freely manage the layout without the automatic centering effect.

<Navbar {...props}>
  <Navbar.Nav />
  <Navbar.Compact />
  <Navbar.Inset> {/* remove this line */}
    {children}
  </Navbar.Inset> {/* remove this line */}
</Navbar>

Using Icons

If you'd like to use icons on the navbar items, that's no problem at all. The navbar is already designed and optimized to accommodate icons seamlessly. First of all, you need to install the hq-icons package.

In the terminal, run the following command to begin:
npm i hq-icons

Disabled

Disable individual navbar items when needed.

Controlled

On mobile devices, the navbar is hidden by default. You can open it using Navbar.Trigger, but there are times when you might want to manage its state by clicking one of the links within the navbar. You can achieve this because it shares the sheet properties, specifically isOpen and onOpenChange. There are multiple ways to control the state, but the simplest method is to listen for path changes and set isOpen to true or false accordingly.

Inertia.js

When you are using inertia.js, you can listen the path by using usePage hooks.

import { usePage } from '@inertiajs/react';
 
export function AppNavbar({ children, ...props }: React.ComponentProps<typeof Navbar>) {
 
  const page = usePage();
  const [isOpen, setIsOpen] = React.useState(false);
  React.useEffect(() => setIsOpen(false), [page.url]);
 
  return (
    <Navbar isOpen={isOpen} onOpenChange={setIsOpen} {...props}/>
  )
}

Next.js

On next.js, you can listen the path by using usePathname hooks.

import { usePathname } from "next/navigation"
 
export function AppNavbar({ children, ...props }: React.ComponentProps<typeof Navbar>) {
 
  const pathname = usePathname();
  const [isOpen, setIsOpen] = React.useState(false);
  React.useEffect(() => setIsOpen(false), [pathname]);
 
  return (
    <Navbar isOpen={isOpen} onOpenChange={setIsOpen} {...props}>
        {/* Rest of your code */}
    </Navbar>
  )
}