How to Build an Analytics Admin Dashboard Shell with shadcn/ui

Wait 5 sec.

In this guide, we will walk you through building a production-ready analytics admin dashboard shell using shadcn/ui, Next.js, and Base UI. You'll scaffold the full layout sidebar navigation, statistics widgets, sales charts, earnings reports, and a product data table using a single CLI command and a clean, component-driven architecture.Why Admin Dashboards Are Hard to Get RightAdmin dashboards are among the most requested UI blocks in web development and among the most underestimated.On the surface, you need a sidebar, some charts, and a data table. But the moment you start building, the complexity compounds: responsive breakpoints, accessibility in dropdowns, collapsible nav states, consistent spacing, dark mode, and making sure the whole thing doesn't fall apart when real data flows in.Most teams either spend weeks building from scratch or bolt together mismatched component libraries that fight each other in production. Neither is ideal.This is exactly the problem that shadcn/ui was designed to address, and the Shadcn Dashboard ecosystem has extended that philosophy further with a set of composable, production-grade dashboard blocks built on both Radix UI and Base UI primitives.In this guide, you'll install a complete analytics dashboard shell in minutes, then understand exactly how each piece fits together so you can customize it confidently.What You'll BuildBy the end of this tutorial, you'll have a fully functional analytics admin dashboard shell that includes:A collapsible app sidebar with a navigation menuA site header with user and notification dropdownsStatistics widgets for key metrics at a glanceA Sales Overview Chart for monthly trend visualizationAn Earning Report Chart for revenue breakdownA Top Products Table with sortable product dataA Sales by Country Widget for geographic distributionThe entire layout is built with a 12-column CSS Grid system, scales across screen sizes, and follows shadcn/ui's composable pattern, meaning you own the code and can extend it as needed.PrerequisitesBefore getting started, make sure you have:Node.js 18+ installedA Next.js project was initialized (npx create-next-app@latest)shadcn/ui configured in your project (run npx shadcn@latest init if you haven't already)A package manager of your choice: npm, pnpm, yarn, or bunIf you need a refresher on setting up shadcn/ui from scratch, the official shadcn/ui docs are the best reference.Step 1 - Install the Dashboard Shell via CLIThe dashboard-shell-01 block is available directly through the shadcn CLI. Run the appropriate command for your package manager:pnpm:pnpm dlx shadcn@latest add @shadcn-space/dashboard-shell-01npm:npx shadcn@latest add @shadcn-space/dashboard-shell-01yarn:yarn dlx shadcn@latest add @shadcn-space/dashboard-shell-01bun:bunx --bun shadcn@latest add @shadcn-space/dashboard-shell-01This single command scaffolds the complete block into your project components, types, assets, and all. No manual copy-pasting of boilerplate.Note: Getting started guides and official Shadcn CLI documentation page. Check there for version-specific instructions.Step 2 - Understand the Folder StructureAfter installation, you'll see the following structure added to your project:app/  dashboard-shell-01/    page.tsxcomponents/  shadcn-space/    blocks/      dashboard-shell-01/        app-sidebar.tsx        site-header.tsx        nav-main.tsx        statistics.tsx        sales-overview-chart.tsx        earning-report-chart.tsx        top-product-table.tsx        salesbycountrywidget.tsx        user-dropdown.tsx        notification-dropdown.tsxassets/  logo/    logo.tsxThis is a clean, flat component structure. Each file has a single responsibility, making it easy to swap out, restyle, or replace individual pieces without affecting the rest of the dashboard.Step 3 - Review the Page Entry PointThe page entry point at app/dashboard-shell-01/page.tsx controls how everything works together. It imports all the dashboard blocks and composes them into a responsive 12-column grid:import AppSidebar from "@/components/shadcn-space/blocks/dashboard-shell-01/app-sidebar";import StatisticsBlock from "@/components/shadcn-space/blocks/dashboard-shell-01/statistics";import SalesOverviewChart from "@/components/shadcn-space/blocks/dashboard-shell-01/sales-overview-chart";import EarningReportChart from "@/components/shadcn-space/blocks/dashboard-shell-01/earning-report-chart";import TopProductTable from "@/components/shadcn-space/blocks/dashboard-shell-01/top-product-table";import SalesByCountryWidget from "@/components/shadcn-space/blocks/dashboard-shell-01/salesbycountrywidget";export default function Page() {  return (                                                                                                                                                        );}Let's break down the layout decisions here.AppSidebar as the layout wrapper. The sidebar is the outermost shell. It provides the persistent navigation structure and wraps all dashboard content. This is a common pattern - your sidebar owns the layout, and your content slots in as children.Widgets stack on smaller screens and shift into a main + side layout on larger screens for a clean, structured dashboard.max-w-7xl mx-auto. The content area is capped at 7xl (1280px) and centered. This prevents the layout from becoming uncomfortably wide on very large monitors.Step 4 - Walk Through Each Componentapp-sidebar.tsx - The Layout ShellThis is the most complex component in the shell. It renders the collapsible sidebar navigation and wraps the main content area. Under the hood, it uses Base UI primitives (not just Radix) for the sidebar panel, which gives you finer control over accessibility and animation behavior.Key features to look for in this component:Sidebar open/close state managementNavigation link active stateMobile-responsive collapse behaviorSlot for the SiteHeader at the top of the content areanav-main.tsx - Navigation MenuThis component renders the sidebar's navigation items. It's separated from app-sidebar.tsx intentionally keeping nav data separate from layout logic makes it easy to swap out your routes or add role-based navigation visibility without touching the sidebar shell.In a real application, you'd feed this component your route definitions from a config file or API response.site-header.tsx - Top BarThe site header sits at the top of the main content area (not the sidebar). It typically includes:Page title or breadcrumbNotificationDropdown - for user alertsUserDropdown - for profile actions like settings and logoutBoth dropdowns are separate components, keeping the header itself clean and easy to maintain.statistics.tsx - KPI WidgetsThe statistics block renders a row of key performance indicator (KPI) cards. These typically show metrics like total revenue, active users, orders, and conversion rate, the "at a glance" numbers that executives and product teams check first thing.Each stats card is self-contained and accepts a value, label, trend indicator, and icon. You'll want to connect these to your real data layer (an API route, SWR hook, or React Query call) once you're out of the prototype phase.sales-overview-chart.tsx - Time-Series Sales ChartThis component renders a line or bar chart showing sales trends over time, typically weekly or monthly. It takes up 8 columns on desktop, making it the dominant visual on the page.The chart is built to accept time-series data arrays. Swap in your actual sales data from your backend, and the chart will reflect it automatically.earning-report-chart.tsx - Revenue BreakdownThe earnings report chart takes up the remaining 4 columns next to the sales overview. It typically shows a donut or bar chart breaking down revenue by category, channel, or product line.This component pairs naturally with the sales overview, one shows the trend, the other shows the composition.top-product-table.tsx - Data TableThe top products table is a full-featured data table with sortable columns, product names, sales figures, revenue values, and status indicators. It uses shadcn/ui's Table primitives, which are built on accessible HTML elements with clean styling applied on top.For production use, wire this up to a paginated API endpoint and add TanStack Table for server-side sorting and filtering. The TanStack Table integration guide on HackerNoon is a great next read once you have this shell running.salesbycountrywidget.tsx - Geographic DistributionThe final widget in the 4-column slot shows a breakdown of sales by country. This can be a ranked list with progress bars, a choropleth map, or a simple table, depending on your data volume and visual needs.For smaller datasets, the ranked list with inline progress bars (which this component uses by default) is the most readable format.Step 5 - Customizing the DashboardNow that the shell is running, here are the most common customizations you'll want to make.Updating Navigation ItemsOpen nav-main.tsx and update the navigation array with your actual routes:const navItems = [  { title: "Overview", href: "/dashboard", icon: LayoutDashboard },  { title: "Analytics", href: "/dashboard/analytics", icon: BarChart3 },  { title: "Orders", href: "/dashboard/orders", icon: ShoppingCart },  { title: "Customers", href: "/dashboard/customers", icon: Users },  { title: "Settings", href: "/dashboard/settings", icon: Settings },];Use Lucide React for icons, it's already included with shadcn/ui and has excellent tree-shaking support.Connecting Real DataEach widget component accepts props or uses internal state with mock data. To connect real data, create a server component wrapper or use a data-fetching hook:// Server component approach (Next.js)import { getSalesOverview } from "@/lib/api/sales";export default async function SalesOverviewWrapper() {  const data = await getSalesOverview();  return ;}For client-side data fetching, SWR or TanStack Query works cleanly with these components.ThemingThe dashboard shell respects shadcn/ui's CSS variable theming system. Update your globals.css to change the color palette::root {  --primary: 221.2 83.2% 53.3%;  --primary-foreground: 210 40% 98%;  /* ... other tokens */}Dark mode is supported out of the box via the dark class on the element.The Base UI DifferenceOne thing worth highlighting: this dashboard shell is built on both Radix UI and Base UI primitives and specifically uses the Base UI version for key interactive components.Base UI (from the MUI team) offers headless, unstyled components with a focus on accessibility and animation control. Compared to Radix alone, it gives you:More granular control over transitions and animation statesA smaller bundle footprint for complex interactive patternsStrong ARIA compliance out of the boxThis matters for dashboards because dropdowns, popovers, tooltips, and modals are core to the UX, and accessibility in these patterns is frequently underinvested. Using Base UI primitives means you're starting from a solid foundation rather than fighting with aria-* attributes manually.Viewing the Full Source CodeIf you want to preview the complete, unmodified source code for the dashboard shell before or after installation, visit this dashboard shell page.The page shows the full component code with syntax highlighting, making it easy to reference individual files without cloning your project.Live PreviewWhat to Build NextOnce your analytics dashboard shell is running with real data, here are the logical next extensions:Add authentication. Wrap your dashboard routes with a session check using NextAuth.js or Clerk. The sidebar and header already have slots for user state - connect them to your auth provider.Add a date range picker. Most analytics dashboards need temporal filtering. shadcn/ui ships a DateRangePicker component that integrates cleanly with the chart components here.Add TanStack Table for the product table. The default table component is great for static or small datasets. For server-side pagination, sorting, and filtering, TanStack Table is the standard choice in the shadcn/ui ecosystem.Add real-time updates. If your data changes frequently, consider Supabase Realtime, Pusher, or Server-Sent Events to push live updates to the statistics widgets without a full page refresh.Dark mode toggle. Add a theme toggle button to the site header's action area. The next-themes library handles this in about 10 lines of code.SummaryBuilding a production-grade analytics admin dashboard used to mean weeks of work assembling a sidebar, finding compatible chart libraries, wrestling with responsive grids, and handling accessibility edge cases in dropdowns and modals.The dashboard-shell-01 block improves things significantly. One CLI command gives you a complete, composable shell built on shadcn/ui and Base UI primitives with all the structural decisions already made correctly.The result is a dashboard you actually own (not a black-box library dependency) that you can read, understand, and extend confidently.The full block library, including this dashboard shell and others, lives at Shadcn Space, worth bookmarking if you're regularly building UI-heavy React and Next.js applications.