Skip to content
BaseLayer Themes

Navbar 01

Sticky site header with nav links, dropdowns, and CTA

File: src/blocks/navbar/Navbar01.astro

Sticky full-bleed site header with desktop links (optional dropdowns), mobile panel, and CTA. Wired in BaseLayout. Floating alternative: Navbar 02.

For chrome-specific props and live demos, open a Navbar version. For authoring links, sections, and mega menus, see the Navigation guide.

Types: src/lib/nav.ts · Client: src/scripts/navbar.ts

Mobile: hamburger + slide panel below md. Dropdown parents expand into a vertical accordion list.

Config (identity.tsnavigation)

Logo paths and site name come from identity (name, logo assets). Edit navigation for links, dropdowns, CTA, and desktop trigger mode:

// src/config/identity.ts
navigation: {
  sticky: true,
  // Desktop dropdowns: "hover" | "click" (mobile accordion is always tap)
  dropdownTrigger: "hover",
  // Bottom stroke (Navbar 01 only)
  borderBottom: true,
  borderThickness: "sm", // "sm" | "md" | "lg"
  borderColor: "soft", // "soft" | "medium" | "hard"
  links: [
    // Simple top-level link
    { label: "Work", href: "/work/" },

    // Dropdown — children only (trigger has no own URL)
    {
      label: "Docs",
      children: [
        { label: "Get started", href: "/docs/get-started/" },
        { label: "Blocks", href: "/docs/blocks/" },
        { label: "Components", href: "/docs/components/" },
      ],
    },

    // Dropdown — parent href + children (short form)
    // Or use `sections` for mega menus — see Navbar 04
    // Label links to href; chevron opens the menu. Also drives active-state matching.
    {
      label: "Services",
      href: "/services/",
      children: [
        { label: "Strategy", href: "/services/strategy/" },
        { label: "Build", href: "/services/build/" },
        { label: "Support", href: "/services/support/" },
      ],
    },

    { label: "About", href: "/about/" },
    { label: "Contact", href: "/contact/" },
  ],
  cta: {
    label: "Hire me",
    href: "/contact/",
    size: "sm", // "sm" | "md" | "lg"
  },
},
Example Shape Result
Work { label, href } Plain link
Docs { label, children } Dropdown trigger; menu is children only
Services { label, href, children } Dropdown; href is first item + active match
import type { NavLink } from "@/lib/nav";

const links: NavLink[] = [
  { label: "Work", href: "/work/" },
  {
    label: "Docs",
    children: [
      { label: "Get started", href: "/docs/get-started/" },
      { label: "Blocks", href: "/docs/blocks/" },
    ],
  },
  {
    label: "Services",
    href: "/services/",
    children: [
      { label: "Strategy", href: "/services/strategy/" },
      { label: "Build", href: "/services/build/" },
    ],
  },
];
Field Type Notes
label string Trigger / link text
href string? Omit for dropdown-only triggers. With children / sections, the label links to this URL and the chevron opens the menu
children { label, href }[]? Short-form list → one panel section via resolveNavSections
width sm | md | lg | xl? Per-parent dropdown panel width (overrides dropdownWidth)
sections NavMegaSection[]? Modular mega columns — see Navbar 04

Resolution: link.widthdropdownWidth prop → "sm" (Navbar 01 default for single-column lists).

Preset Approx. panel width
sm 20rem (default)
md 28rem
lg 40rem
xl 56rem
{
  label: "Docs",
  href: "/docs/",
  width: "md", // this menu only
  children: [
    { label: "Get started", href: "/docs/get-started/" },
    { label: "Blocks", href: "/docs/blocks/" },
  ],
}
<Navbar01 dropdownWidth="md" />

Bottom stroke (borderBottom)

Navbar 01’s full-bleed bar can show a bottom border. Defaults match the previous look (true + sm + soft).

Value Thickness Color token
borderThickness: "sm" 1px (border-b)
borderThickness: "md" 2px (border-b-2)
borderThickness: "lg" 4px (border-b-4)
borderColor: "soft" border-line-soft
borderColor: "medium" border-line
borderColor: "hard" border-soft
navigation: {
  borderBottom: true,
  borderThickness: "md",
  borderColor: "medium",
  // …
},

Turn the stroke off:

<Navbar01 borderBottom={false} />

Or override thickness / color on the instance:

<Navbar01 borderThickness="lg" borderColor="hard" />

Desktop trigger (dropdownTrigger)

Value Behavior
"click" Open / close on click (default if unset)
"hover" Open on pointer enter, close on leave (short delay). Click still toggles for touch

Escape and outside click close open menus. Mobile always uses tap-to-expand; sub-links render as a vertical list under the parent.

navigation: {
  dropdownTrigger: "click", // or "hover"
  links: [/* … */],
  cta: { /* … */ },
},

Override per instance:

<Navbar01 dropdownTrigger="click" />

Add to a page

---
import Navbar01 from "@/blocks/navbar/Navbar01.astro";
---

<Navbar01 />

Props override matching keys from config — including inline dropdown links:

<Navbar01
  sticky={false}
  dropdownTrigger="click"
  links={[
    { label: "Home", href: "/" },
    {
      label: "Product",
      children: [
        { label: "Features", href: "/features/" },
        { label: "Pricing", href: "/pricing/" },
      ],
    },
    {
      label: "Resources",
      href: "/resources/",
      children: [
        { label: "Blog", href: "/blog/" },
        { label: "Guides", href: "/guides/" },
      ],
    },
  ]}
/>

Props

Prop Config key Type / values Default / notes
links navigation.links NavLink[] Optional children; per-parent width for panel size
dropdownWidth navigation.dropdownWidth sm | md | lg | xl Default panel width; default sm; overridable per parent via links[].width
dropdownTrigger navigation.dropdownTrigger click | hover Desktop only; default click
borderBottom navigation.borderBottom boolean Bottom stroke on/off; default true
borderThickness navigation.borderThickness sm | md | lg Stroke weight when enabled
borderColor navigation.borderColor soft | medium | hard Stroke contrast when enabled
ctaLabel navigation.cta.label string
ctaHref navigation.cta.href string
ctaSize navigation.cta.size sm | md | lg
sticky navigation.sticky boolean Pin the navbar while scrolling

← Navbar versions · Navigation guide · Blocks overview