Side Dots Navigation

About this block

Side Dots NavigationPRO

A minimal top bar with the brand and a button, plus a column of section dots fixed at the right edge whose labels slide out on hover or focus; an IntersectionObserver moves the active dot as each section crosses the middle of the screen. On a phone the dots sit in a bottom row with the current section name, which opens a numbered section list above it. The list stays in the markup and is toggled with CSS.

A minimal sticky bar with the brand and one button, paired with a column of section dots fixed at the right edge of the screen. Hovering or focusing a dot slides its label out, clicking scrolls to that section, and the active dot follows the scroll on its own. On a phone the dots move into a floating row at the bottom with the current section name, which opens a numbered list of every section above it. The block renders the demo sections the dots observe.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://beste.dev/r/navbar114?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://beste.dev/r-base/navbar114?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/navbar114.tsx plus the shadcn button primitive it uses.

Quick start

The installed file exports navbar114Demo alongside the block: the exact props behind the preview above. Spread it to get a working navbar in one line.

tsx
import { Navbar114, navbar114Demo } from "@/components/beste/block/navbar114";

export default function Page() {
  return <Navbar114 {...navbar114Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Navbar114 } from "@/components/beste/block/navbar114";

export default function Page() {
  return (
    <Navbar114
      brand="Meridian"
      sections={[
        { label: "Overview", heading: "One calm place for every project", description: "Plans, files and decisions in one timeline." },
        { label: "Planning", heading: "Plans that stay honest", description: "Milestones move when the work moves." },
        { label: "Pricing", heading: "Free for teams of five", description: "One price per active seat." },
      ]}
      actions={[{ label: "Start free", href: "/signup" }]}
      labels={{ sections: "Page sections", open: "Show all sections", close: "Hide sections", goTo: "Go to" }}
    />
  );
}

Props

PropTypeDefaultDescription
brandstring–Wordmark on the left of the bar
sectionsSection[][]Page sections rendered under the bar; each one gets a dot
actionsActionButton[][]Buttons on the right of the bar
labels{ sections?: string; open?: string; close?: string; goTo?: string }{}Name of the dot navigation, names for the mobile list toggle and the prefix read before each dot label
classNamestring–Extra classes for the outer wrapper
ts
type Section = {
  label: string;
  heading: string;
  description: string;
  image?: { src: string; alt: string };
};

type ActionButton = {
  label: string;
  href: string;
  variant?: "default" | "outline" | "ghost" | "secondary";
};

Behavior notes

  • An IntersectionObserver with a -50% 0px -50% 0px root margin watches every section, so the active dot changes exactly when a section crosses the middle of the viewport.
  • Clicking a dot calls scrollIntoView, smooth unless the visitor prefers reduced motion; sections carry scroll-mt-16 so the sticky bar never covers a heading.
  • Desktop labels stay hidden until hover or keyboard focus, except the active one, and every dot sets aria-current when its section is in view.
  • The mobile section list is always rendered and toggled with CSS classes, carrying aria-hidden and inert while closed; the toggle shows the current section name with aria-expanded, and Escape closes it.
  • Choosing a section in the mobile list scrolls to it and closes the list.

More Navigation blocks

View all Navigation
PRO

navbar34

Sidebar Drawer Navbar

PRO

navbar36

Tab-Style Navbar

PRO

navbar78

Classic Navbar

Get Pro