Shadcn Navbar: Mega Menu, Mobile Menu, Sticky Header
You want a shadcn navbar for a SaaS site: a logo, Product and Resources dropdowns with a mega menu, Pricing, Sign in, Get started, a bar that sticks while the page scrolls, and a phone menu that does not feel like an afterthought. shadcn/ui gives you the Navigation Menu (opens in a new tab) for the desktop part. Its docs page (checked November 5, 2026) covers the menu parts and wrapping the Next.js Link, and says nothing about phones. The phone menu, the sticky bar and the layout shift are left to you.
This guide builds that navbar with two Wingo UI components: the Nav Menu for a custom header and the Marketing Header when you want the whole thing ready. We build that library, so we are not neutral. Every snippet uses the real props, and both components are free.
What does a shadcn navbar need on a SaaS site?
Five things, and the last two take the most work:
- A fixed-height bar. 56 or 64px, with the logo at the start and one or two actions at the end. The height never changes after the page loads.
- Dropdown panels. A short list for Resources, a mega menu for Product: icons, one-line descriptions, two columns, maybe a featured card for the latest launch.
- Keyboard support. Tab reaches every trigger and link, arrows move between them, Escape closes a panel and returns focus.
- A real phone menu. Every link, the panels as collapsible groups, Sign in and Get started as full-width buttons, rows tall enough for a thumb.
- No layout shift. The server HTML must already show the right layout for the screen, and opening a panel or the phone menu must not move the page.
Navbar galleries sell finished layouts. shadcnblocks (opens in a new tab) lists 21+ navbar blocks next to its All Access offer, and Aceternity's Resizable Navbar (opens in a new tab) shrinks and blurs once the page scrolls, has its own mobile menu and installs with the shadcn CLI (both checked November 5, 2026). The Aceternity page documents props but says nothing about keyboard or focus handling. If you want a striking visual layout to copy, those galleries are a fine place to start. If you want the behavior in items 3 to 5 done for you, read on.
How do you build a shadcn navbar with a mega menu?
Describe the links as data and pass them to the Nav Menu: an item with items becomes a dropdown, and columns plus featured turn it into a mega menu. Install it first:
The CLI copies components/ui/nav-menu.tsx and the Wingo UI files it imports: the Sheet and Accordion for the phone menu, Button, Badge, the motion helpers and the shared navigation helpers in lib/navigation.tsx. It also installs the npm packages they need, among them @radix-ui/react-navigation-menu, motion and lucide-react.
Plain data keeps a Next.js mega menu readable. An item with only an href is a plain link in the bar.
Render <SiteHeader /> at the top of your root layout. Because Product has its own href, its panel starts with a "View all" row to /product. currentPath marks the active link (the longest matching href) and puts the active look on the top-level item above it. On Next.js you can set the link component and path once for every navigation component with a LinkProvider from @/lib/navigation, and drop linkComponent and currentPath from the call.
$ npx wingo-ui@latest add nav-menuWhich props matter most?
viewport(defaulttrue): one shared panel that glides between triggers and resizes to the new content, the Stripe-style header. Set it tofalseto open each panel as its own surface under its trigger.indicator:"pill"(default),"underline"or"none", the highlight that follows the pointer and rests on the active section.size:"md"gives a 64px bar with 36px triggers,"sm"a 56px bar with 32px triggers. Triggers grow to 44px on touch screens.mobileBreakpoint:"md"(768px, default) or"lg"(1024px) for menus that do not fit a tablet.delayDuration(150ms) andskipDelayDuration(300ms): how long a pointer rests before a panel opens, and the window in which the next one opens at once, so a cursor passing over the bar does not flash menus.
How do you make the shadcn navigation menu mobile friendly?
Below the breakpoint, replace the links with a menu button that opens a full-screen sheet holding every link, with each dropdown as an accordion section. shadcn/ui leaves this half of a responsive shadcn navbar to you; the Nav Menu does it in the same component, and its menu button also replaces the actions. Tap it and a full-screen Sheet slides in from the right:
- the logo at the top, so the menu still feels like your site;
- one accordion section per dropdown, with the section you are in already open;
- 48px rows, and the featured card as a compact row;
- your
actionsstacked full width at the bottom (passmobileActionsto use different ones there).
Choosing a link, the close button, a swipe to the right or Escape closes it. The menu traps focus and locks the page scroll while it is open; set modal={false} only for inline previews. One detail that is easy to miss: if the phone menu is open and the screen grows past the breakpoint (a tablet rotated to landscape), the Nav Menu closes it, so nobody is left with a full-screen overlay over a desktop layout.
When is a bottom drawer the better phone menu?
When the site has four or five plain links and no dropdowns. A full-screen menu is more than that needs, and a bottom sheet keeps the links near the thumb. Build it with the Drawer and close it from each link with DrawerClose:
The trigger hides itself from 768px with md:hidden; the desktop links in your bar take hidden md:flex. Both are CSS, which matters for the next question.
How do you keep a sticky navbar free of layout shift?
Decide the layout with CSS so the server HTML is already right, keep panels and scroll locks out of the page flow, pad anchor jumps by the bar's height, and keep that height constant. These are the four usual causes of shift in a Next.js responsive navbar, with the fix for each.
The server renders the wrong layout. A useIsMobile() hook is false on the server, so a phone first gets the desktop links, then swaps to the hamburger after hydration. The Nav Menu decides with CSS container queries on the bar instead, so the HTML from the server is already the phone layout on a phone. A side effect: the breakpoint follows the bar's width, so a header inside a narrow column folds even on a wide screen.
The panel pushes content. Panels render in an absolutely positioned viewport under the bar, so opening one never moves the page below it.
Scroll lock moves the page. Hiding the scrollbar when a menu opens widens the page by the scrollbar's width. The Sheet is built on Radix Dialog and the Drawer on vaul, which wraps Radix Dialog; its scroll lock adds that width back as spacing, so the page stays put.
Anchors land under the bar. Jumping to #pricing scrolls the heading to the top of the viewport, behind your sticky bar. One line of CSS fixes it:
Keep the bar's height constant too. If you want it to look different after scrolling, change its background or shadow, which do not move anything.
What about keyboard and screen reader support?
The Nav Menu is fully keyboard operable and renders a labeled nav landmark, not an application menu. It sits on the Radix navigation menu primitive, and the Radix docs (opens in a new tab) (checked November 5, 2026) explain why it deliberately avoids the WAI-ARIA menu role: menus carry composite focus management and first-character navigation that website navigation does not need. In the Nav Menu, Tab reaches every trigger and link, ArrowLeft and ArrowRight move between triggers, Enter or Space opens a panel, ArrowDown opens it and lands on its first link, and Escape closes it and returns focus to the trigger. The nav carries an aria-label ("Main" by default, in labels.navigation), the menu button switches between "Open menu" and "Close menu", and under reduced motion panels fade without sliding.
The Marketing Header adds a "Skip to content" link as the first Tab stop, pointed at #main by default through skipTo.
Should you use the Marketing Header instead?
Use it when you want a finished SaaS header rather than parts. It wraps the Nav Menu with a logo, Sign in and Get started, an optional announcement strip, the skip link and sample navigation, and adds three layouts (default, centered, pill) and three looks (glass blurs the page under the sticky bar, solid, transparent for a hero).
One difference to know: the Marketing Header folds into the phone menu below 1024px, because a full SaaS bar with two actions rarely fits a tablet. If you need the 768px switch, use the Nav Menu directly as above.
$ npx wingo-ui@latest add marketing-headerWhere does the navbar go next?
The navbar is the first thing on every page, so it pays to get it right once. The Next.js SaaS landing page guide walks through the sections under it, the SaaS website template guide covers the pages the navbar links to, and the Landing Page template ships with this Marketing Header already in place. The Build it category and its pillar, the Next.js admin dashboard tutorial, cover the screens behind the Get started button.
The Marketing Header, Nav Menu, Sheet and Drawer are all free. Run npx wingo-ui@latest add marketing-header, swap in your logo and links, and check it on a real phone.
FAQ
Does shadcn/ui have a responsive navbar?
Not as one component. shadcn/ui has a Navigation Menu for the desktop links and panels, and its docs (checked November 5, 2026) say nothing about a hamburger or phone layout, so you add a Sheet for the phone menu yourself or install a navbar block from a gallery.
How do I make a shadcn navigation menu work on mobile?
Hide the Navigation Menu below a breakpoint with CSS and render a menu button that opens a Sheet with the same links, with each dropdown as an accordion section and rows at least 44px tall. Close the sheet when a link is chosen and when the screen grows past the breakpoint.
How do I build a mega menu in Next.js?
Give a top-level item a list of child links with icons and descriptions, lay them out in two or three columns and add a featured card. With the Wingo UI Nav Menu that is data: an item with items, columns: 2 and featured: { title, href, image }.
Why does my sticky navbar hide section headings when I jump to an anchor?
The browser scrolls the target to the top of the viewport, under the sticky bar. Add scroll-padding-top to the html element with the bar's height, for example 4rem for a 64px bar.
Is the Wingo UI navbar free?
Yes. The Marketing Header, Nav Menu, Sheet and Drawer are all in the free tier, and npx wingo-ui@latest add marketing-header copies the header and everything it imports into your project as source.
- Navbar
- Navigation
- shadcn/ui
- Next.js
- Mobile UI


