Prodular UI

Layout

App shellPro

The frame of an app: navigation, top bar and the scrolling page. Four layouts share one nav model: collapsible sidebar, a rail that peeks open on hover, a double sidebar and top navigation. Phones get a sheet, and the collapsed state is remembered.

npx prodular-ui add app-shell

Part of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing

Four layouts, one nav

Switch layouts above the frame. The same nav sections, workspace switcher, user menu and breadcrumb fill each one. Narrow the window to see the phone sheet.

All invoices

Collapse the sidebar to icons from the top bar or with Cmd+B.

Outstanding
$412,800
Overdue
$61,900
Paid this month
$238,450
Days to pay
31

Anatomy

<AppShell  layout="sidebar"  nav={nav}  activeId={pathname}  linkComponent={Link}  brand={<WorkspaceSwitcher ... />}  user={<AppShellUser name="Maya Okafor" initials="MO">...</AppShellUser>}  breadcrumb={<Breadcrumb>...</Breadcrumb>}  storageKey="app">  {page}</AppShell>

Guidance

Use it when

  • The outer frame of a SaaS or AI app, once, around every signed-in page.
  • sidebar for most apps; rail when the page needs the width, like editors and boards; double for products with modules that each have several pages; topnav for apps with five or fewer areas.
  • brand for a WorkspaceSwitcher or a logo, user for AppShellUser, actions for search, notifications and one primary action.

Avoid

  • Nesting shells. Settings and detail pages go inside the page, with Settings nav or Master detail.
  • More than about nine items in a section. Group them, or move rare pages to a module in the double layout.
  • Rebuilding the nav per page. Keep one nav model and change activeId.

Rules for AI agents

Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.

  • Describe navigation once as AppNavSection[] with id, label, icon, href, badge and items for child pages, and pass the current page id as activeId.
  • For client routing pass linkComponent={Link} from next/link. onNavigate receives every click; call event.preventDefault() only when you route yourself.
  • Set storageKey (for example "app") so the collapsed sidebar and the double sidebar's page list survive reloads.
  • Use contained when the shell sits inside another layout or a preview; otherwise it takes the full viewport height.
  • Put WorkspaceSwitcher in brand and AppShellUser in user. Both size themselves for the expanded sidebar, the collapsed rail and the top navigation.
  • Cmd or Ctrl+B toggles the sidebar. Every icon-only button has a tooltip and an accessible name; do not remove labels from nav items.
  • Use fill with a Workspace or a full-bleed map or canvas, so the page area does not scroll.

API

AppShell

PropTypeDefaultDescription
layout"sidebar" | "rail" | "double" | "topnav""sidebar"Where the navigation goes.
navAppNavSection[]Sections of { id, label, icon, href, badge, items, description }.
footerNavAppNavItem[]Pinned to the bottom of the sidebar, like Help and Settings.
activeIdstringThe current page. Its parents open and highlight.
onNavigate(item, event) => voidEvery nav click.
linkComponentElementType"a"Renders links, for example Next.js Link.
brand / user / breadcrumb / actionsReactNodeSlots for the workspace, the account, the page path and top bar actions.
storageKeystringRemembers collapsed states in localStorage.
defaultCollapsedbooleantrue for railStarts with the nav as icons.
containedbooleanfalseFills the parent instead of the viewport.
fillbooleanfalseThe page area fills the space under the top bar and does not scroll, for a Workspace or a full-bleed canvas.

AppShellUser

PropTypeDefaultDescription
name / email / initials / imagestringThe signed-in person. Put DropdownMenuItems inside for the menu.