Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Build React UIs using shadcn/ui components with Tailwind CSS, Radix primitives, and proper accessibility patterns.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/nextjs-integration.md
1# shadcn/ui - Next.js Integration23## App Router Setup45Most shadcn/ui components require `"use client"` directive when used with App Router. Static display components (Card, Table) can work in Server Components without the directive.67```tsx8// src/components/ui/button.tsx — already includes "use client" after npx shadcn@latest add button9"use client"10import * as React from "react"11// ... rest of component12```1314## Root Layout with Toaster1516```tsx17// app/layout.tsx18import { Inter } from "next/font/google"19import { Toaster } from "@/components/ui/toaster"20import { cn } from "@/lib/utils"21import "./globals.css"2223const inter = Inter({ subsets: ["latin"] })2425export default function RootLayout({ children }: { children: React.ReactNode }) {26return (27<html lang="en" suppressHydrationWarning>28<body className={cn("min-h-screen bg-background font-sans antialiased", inter.className)}>29{children}30<Toaster />31</body>32</html>33)34}35```3637## Server Components with Interactive Elements3839When using interactive shadcn/ui components in Server Components, wrap them in a Client Component:4041```tsx42// app/dashboard/page.tsx — Server Component43import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"44import { ButtonClient } from "@/components/button-client"4546export default function DashboardPage() {47return (48<div className="container mx-auto p-6">49<Card>50<CardHeader>51<CardTitle>Dashboard</CardTitle>52</CardHeader>53<CardContent>54<ButtonClient>Interactive Button</ButtonClient>55</CardContent>56</Card>57</div>58)59}60```6162```tsx63// src/components/button-client.tsx — Client Component wrapper64"use client"65import { Button } from "@/components/ui/button"6667export function ButtonClient(props: React.ComponentProps<typeof Button>) {68return <Button {...props} />69}70```7172## Metadata with shadcn/ui Pages7374```tsx75// app/layout.tsx76import { Metadata } from "next"7778export const metadata: Metadata = {79title: { default: "My App", template: "%s | My App" },80description: "Built with shadcn/ui and Next.js",81}82```8384```tsx85// app/about/page.tsx86import { Metadata } from "next"87import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"8889export const metadata: Metadata = {90title: "About Us",91description: "Learn more about our company",92}9394export default function AboutPage() {95return (96<div className="container mx-auto py-8">97<Card>98<CardHeader><CardTitle>About Our Company</CardTitle></CardHeader>99<CardContent>100<p>We build amazing products with modern web technologies.</p>101</CardContent>102</Card>103</div>104)105}106```107108## Dark Mode Setup109110### With next-themes111112```bash113npm install next-themes114```115116```tsx117// components/theme-provider.tsx118"use client"119import { ThemeProvider as NextThemesProvider } from "next-themes"120121export function ThemeProvider({ children, ...props }) {122return <NextThemesProvider {...props}>{children}</NextThemesProvider>123}124```125126```tsx127// app/layout.tsx128import { ThemeProvider } from "@/components/theme-provider"129130export default function RootLayout({ children }) {131return (132<html lang="en" suppressHydrationWarning>133<body>134<ThemeProvider attribute="class" defaultTheme="system" enableSystem>135{children}136</ThemeProvider>137</body>138</html>139)140}141```142143### Theme Toggle Component144145```tsx146"use client"147import { useTheme } from "next-themes"148import { Button } from "@/components/ui/button"149import { Moon, Sun } from "lucide-react"150151export function ThemeToggle() {152const { theme, setTheme } = useTheme()153return (154<Button variant="ghost" size="icon"155onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>156<Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />157<Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />158</Button>159)160}161```162