Marketing
Site Header
Sticky header with wordmark, nav, primary CTA and a mobile menu.
pnpm dlx shadcn@latest add @paragon/site-headerBrings in@paragon/button@paragon/wordmarklucide-reactcn
registry/paragon/blocks/site-header/site-header.tsx
"use client"
import * as React from "react"
import Link from "next/link"
import { Menu, X } from "lucide-react"
import { cn } from "cn"
import { Button } from "@/registry/paragon/ui/button"
import { Wordmark } from "@/registry/paragon/components/wordmark"
type NavLink = { label: string; href: string }
export function SiteHeader({
links = [
{ label: "Constellation", href: "/constellation" },
{ label: "Telos", href: "/telos" },
{ label: "Research", href: "/research" },
{ label: "Company", href: "/company" },
],
cta = { label: "Talk to us", href: "/contact" },
className,
}: {
links?: NavLink[]
cta?: NavLink
className?: string
}) {
const [open, setOpen] = React.useState(false)
const menuId = React.useId()
return (
<header
className={cn(
"sticky top-0 z-40 px-inset pt-inset",
className
)}
>
<div className="mx-auto flex h-16 max-w-page items-center justify-between gap-6 rounded-card px-[calc(var(--spacing-gutter)-var(--spacing-inset))] backdrop-blur-md supports-backdrop-filter:bg-background/70">
<Link href="/" aria-label="Paragon home" className="rounded-sm outline-none focus-visible:ring-3 focus-visible:ring-ring/40">
<Wordmark />
</Link>
<nav aria-label="Main" className="hidden items-center gap-8 lg:flex">
{links.map((link) => (
<Link
key={link.href}
href={link.href}
className="text-[0.9375rem] font-medium text-foreground/75 transition-colors duration-(--duration-base) hover:text-foreground"
>
{link.label}
</Link>
))}
</nav>
<div className="flex items-center gap-2">
<Button render={<Link href={cta.href} />} nativeButton={false}>
{cta.label}
</Button>
<Button
variant="outline"
className="lg:hidden"
aria-expanded={open}
aria-controls={menuId}
onClick={() => setOpen((value) => !value)}
>
{open ? <X aria-hidden="true" /> : <Menu aria-hidden="true" />}
Menu
</Button>
</div>
</div>
<nav
id={menuId}
aria-label="Main"
hidden={!open}
className="mx-auto mt-2 max-w-page rounded-card bg-card p-2 shadow-lg ring-1 ring-border lg:hidden"
>
<ul className="flex flex-col">
{links.map((link) => (
<li key={link.href}>
<Link
href={link.href}
onClick={() => setOpen(false)}
className="flex h-12 items-center rounded-button px-4 text-lg font-medium hover:bg-foreground/5"
>
{link.label}
</Link>
</li>
))}
</ul>
</nav>
</header>
)
}