Skip to content
All Taste components

Navigation & footer

Website header

The bar at the top of every page: logo, main links, sign in and the main action, with an announcement strip above.

announcement strip · desktop links · collapsed menu below 640px

"use client";
import { useState } from "react";
import { ArrowRight, Menu, X } from "lucide-react";
import { cn } from "@/lib/utils";

const links = [
  { label: "Product", href: "/product" },
  { label: "Pricing", href: "/pricing" },
  { label: "Customers", href: "/customers" },
  { label: "Docs", href: "/docs" },
];

export function SiteHeader({ current = "/product" }: { current?: string }) {
  const [open, setOpen] = useState(false);
  return (
    <div className="font-sans">
      <div className="flex flex-wrap items-center justify-center gap-x-2.5 gap-y-1 bg-fg px-4 py-2 text-center text-[13px] text-bg">
        <span>Recurring invoices are here — set it once, bill every month.</span>
        <a href="/recurring" className="inline-flex items-center gap-1 font-medium underline underline-offset-4">
          See how <ArrowRight className="size-3.5" aria-hidden />
        </a>
      </div>

      <header className="sticky top-0 z-40 border-b border-border bg-bg">
        <div className="mx-auto flex h-16 max-w-6xl items-center gap-6 px-4 sm:px-6">
          <a href="/" className="flex items-center gap-2 text-[15px] font-semibold tracking-tight text-fg">
            <span aria-hidden className="size-6 rounded-sm bg-primary" />
            Fernbill
          </a>

          <nav aria-label="Main" className="hidden md:block">
            <ul className="flex gap-0.5">
              {links.map((l) => (
                <li key={l.href}>
                  <a
                    href={l.href}
                    aria-current={l.href === current ? "page" : undefined}
                    className="rounded px-2.5 py-1.5 text-sm text-fg-muted transition hover:bg-surface hover:text-fg aria-[current=page]:text-fg"
                  >
                    {l.label}
                  </a>
                </li>
              ))}
            </ul>
          </nav>

          <div className="ml-auto flex items-center gap-1.5">
            <a href="/login" className="hidden h-8 items-center rounded px-3 text-[13px] font-medium text-fg hover:bg-surface-2 md:inline-flex">
              Sign in
            </a>
            <a href="/signup" className="inline-flex h-8 items-center rounded bg-primary px-3 text-[13px] font-medium text-primary-fg hover:bg-primary-hover">
              Start free
            </a>
            <button
              type="button"
              onClick={() => setOpen(!open)}
              aria-expanded={open}
              aria-controls="mobile-nav"
              aria-label={open ? "Close menu" : "Open menu"}
              className="inline-grid size-8 place-items-center rounded border border-border-strong text-fg md:hidden"
            >
              {open ? <X className="size-4" /> : <Menu className="size-4" />}
            </button>
          </div>
        </div>

        <nav id="mobile-nav" aria-label="Mobile" className={cn("border-t border-border px-4 py-3 md:hidden", !open && "hidden")}>
          <ul className="grid gap-0.5">
            {links.map((l) => (
              <li key={l.href}>
                <a href={l.href} className="block rounded px-2 py-2.5 text-[15px] text-fg hover:bg-surface">{l.label}</a>
              </li>
            ))}
            <li><a href="/login" className="block rounded px-2 py-2.5 text-[15px] text-fg-muted hover:bg-surface">Sign in</a></li>
          </ul>
        </nav>
      </header>
    </div>
  );
}

The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.