Reading Progress Navbar
A free sticky navbar with a scroll progress bar for Next.js and React.
- Automated axe check
- Reduced-motion tested
- SSR build verified
- CSS and React
- No runtime packages
Reading Progress Navbar is a free sticky navbar React component for Next.js, styled with Tailwind, with a thin reading-progress bar along its bottom edge that fills from left to right as the page scrolls. The fill is a pure CSS scroll timeline: a transform-only scaleX keyframe scrubbed by the document scroll position through animation-timeline: scroll(root block), so there are no scroll listeners, no animation frame loop and no client JavaScript at all.
Because the bar is driven entirely by CSS, the whole component renders on the server. Where scroll-driven timelines are unsupported the bar rests hidden at zero width and every link and the CTA keep working, so it degrades gracefully. The bar is decorative and aria-hidden, the header is a real labelled navigation landmark with real anchors and visible focus rings, and the inverted CTA keeps AA contrast. This is the scroll progress navbar for React you can drop into a Next.js layout.
Install
Add the @te registry to your components.json once:
{
"registries": {
"@te": "https://templateempire.io/r/{name}.json"
}
}Then install the component:
npx shadcn@latest add @te/nav-progress-barUsage
import { NavProgressBar } from "@/components/nav-progress-bar";
export default function SiteHeader() {
return (
<NavProgressBar
logo={<span className="font-semibold">Acme</span>}
links={[
{ label: "Features", href: "#features" },
{ label: "Pricing", href: "#pricing" },
{ label: "Docs", href: "/docs" },
]}
cta={{ label: "Get started", href: "/signup" }}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| logo | ReactNode | required | Brand slot rendered on the left of the header. |
| links | { label: string; href: string }[] | required | Navigation links, rendered inline as real anchors. They wrap to a second row on narrow viewports; in-page anchors or routes both work. |
| cta | { label: string; href: string } | undefined | Optional right-side call to action rendered with inverted tokens. |
| className | string | undefined | Additional classes merged onto the header element. |
Customisation
Reading Progress Navbar exposes two Tier 3 tokens on the progress bar. --nav-progress-size sets the bar thickness and defaults to 3px, and --nav-progress-color sets its fill and defaults to var(--color-primary), the brand token, so it retheme with the rest of the library. Keep the thickness between 2px and 3px so the bar never obscures a link hit area. Override them from :root or any ancestor:
:root {
--nav-progress-size: 3px;
--nav-progress-color: var(--color-primary);
}Frequently asked questions
- Is Reading Progress Navbar free for commercial use?
- Yes. Reading Progress Navbar is MIT licensed, so you can use it in personal and commercial projects without attribution.
- Is Reading Progress Navbar accessible and performant?
- Yes. The progress bar is a pure CSS scroll-driven animation that transforms scaleX only, with no scroll listeners and no JavaScript, so it never runs work on the main thread as you scroll. The bar is decorative and aria-hidden because it duplicates the scrollbar, and it never intercepts pointer input. The header is a real navigation landmark labelled Main, with real anchors, visible focus rings and an inverted CTA that keeps AA contrast. Under reduced motion the bar keeps reflecting scroll position, since that is position and not decorative motion, and it adds no easing transition.
- What happens in browsers without CSS scroll timelines?
- It degrades gracefully. The fill only attaches inside an @supports (animation-timeline: scroll()) guard, so on a browser that lacks scroll-driven timelines the bar rests hidden at zero width while the rest of the header, the links and the CTA all keep working. Nothing depends on JavaScript, so the navbar is fully usable either way.