--- name: frontend-nextjs-app-router description: | Use when working with Next.js App Router tasks - creating pages in /app/, setting up dynamic routes ([id]/page.tsx), implementing nested layouts/templates (layout.tsx), optimizing Server/Client components, or building ERP role-based pages (admin/teacher/student dashboards). Auto-use for all /app/ directory operations, dynamic routing, and App Router-specific features. --- # Next.js App Router Expert ## Overview Expert guidance for Next.js App Router development including page creation, dynamic routing, nested layouts, Server/Client component optimization, and ERP role-based dashboards. ## Core Capabilities ### 1. Page Creation (`/app/.../page.tsx`) **Rules:** - Use **Server Components** by default (no 'use client' directive) - Async data fetching with `fetch()` or ORM queries directly - No `useEffect` for initial data load - Use `Suspense` boundaries for loading states - SEO metadata via `generateMetadata()` **Template:** ```typescript // app/dashboard/page.tsx import { Suspense } from 'react'; import { TaskList } from '@/components/TaskList'; import { TaskListSkeleton } from '@/components/TaskListSkeleton'; export const metadata = { title: 'Dashboard', description: 'Your task management dashboard', }; export default async function DashboardPage() { const tasks = await fetchTasks(); return (

Dashboard

}>
); } ``` ### 2. Dynamic Routes (`[slug]/page.tsx`) **When to use:** - Student profiles: `app/students/[studentId]/page.tsx` - Task details: `app/tasks/[taskId]/page.tsx` - Course pages: `app/courses/[courseId]/page.tsx` **Rules:** - Extract params from `params` prop (read-only) - Use `generateMetadata()` for SEO - Handle 404 with `not-found.tsx` **Template:** ```typescript // app/students/[studentId]/page.tsx import { notFound } from 'next/navigation'; type Params = Promise<{ studentId: string }>; export async function generateMetadata({ params }: { params: Params }) { const { studentId } = await params; const student = await getStudent(studentId); if (!student) return { title: 'Student Not Found' }; return { title: `${student.name} - Student Profile`, }; } export default async function StudentProfile({ params }: { params: Params }) { const { studentId } = await params; const student = await getStudent(studentId); if (!student) notFound(); return ; } ``` ### 3. Parallel Routes (`@folder`) **When to use:** - Dashboard variants: `app/dashboard@(admin|teacher)/page.tsx` - Split layouts: `app/settings@(user|organization)/layout.tsx` **Template:** ```typescript // app/dashboard/@admin/page.tsx - Admin dashboard export default function AdminDashboard() { return ; } // app/dashboard/@teacher/page.tsx - Teacher dashboard export default function TeacherDashboard() { return ; } ``` ### 4. Layouts & Templates **Root Layout (`app/layout.tsx`):** ```typescript import { Providers } from '@/components/Providers'; import './globals.css'; export const metadata = { title: 'Todo Evolution', description: 'Task management for education', }; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` **Nested Layout (`app/dashboard/layout.tsx`):** ```typescript import { DashboardNav } from '@/components/DashboardNav'; export default function DashboardLayout({ children, }: { children: React.ReactNode; }) { return (
{children}
); } ``` **Template (`app/tasks/template.tsx`):** ```typescript // Re-executes on navigation, preserves form state export default function TasksTemplate({ children }: { children: React.ReactNode }) { return (

Tasks

{children}
); } ``` ### 5. Server vs Client Components **Use Server Components for:** - Data fetching - Direct database queries - Static content - Server-only operations **Use Client Components (`'use client'`) for:** - Browser APIs (`window`, `localStorage`) - Event handlers (`onClick`, `onSubmit`) - React hooks (`useState`, `useEffect`) - State management (Zustand, Redux) - Interactivity ```typescript // Server Component (default) export default async function TaskList() { const tasks = await fetchTasks(); // Direct DB query return
{tasks.map(/* ... */)}
; } // Client Component 'use client'; import { useTaskStore } from '@/store/tasks'; export function TaskFilter() { const { filter, setFilter } = useTaskStore(); return ; } ``` ### 6. ERP Role-Based Pages **Role Guards:** ```typescript // app/admin/page.tsx import { requireRole } from '@/lib/auth'; import { redirect } from 'next/navigation'; export default async function AdminPage() { const session = await getSession(); if (session?.role !== 'admin') { redirect('/unauthorized'); } return ; } ``` **KPI Dashboard (Recharts):** ```typescript 'use client'; import { BarChart, Bar, XAxis, YAxis, Tooltip } from 'recharts'; export function TaskKPIChart({ data }: { data: TaskStats[] }) { return ( ); } ``` ### 7. Error & Loading States **Error Boundary (`error.tsx`):** ```typescript 'use client'; export default function Error({ error, reset, }: { error: Error & { digest?: string }; reset: () => void; }) { return (

Something went wrong!

); } ``` **Loading State (`loading.tsx`):** ```typescript export default function Loading() { return
Loading...
; } // Or with Suspense: export default async function Page() { return ( }> ); } ``` ### 8. shadcn/ui Integration **Installation:** ```bash npx shadcn@latest add button card input dialog ``` **Usage in Server Components:** ```typescript import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader } from '@/components/ui/card'; export default async function TaskPage() { const tasks = await getTasks(); return ( Tasks {tasks.map(task => (
{task.title}
))}
); } ``` ## Workflow Decision Tree **User Request** → **Analyze** → **Implementation Path** 1. **"Dashboard/Admin page banao"** → Server Component with `page.tsx` → Async data fetch → Add `layout.tsx` if navigation needed 2. **"Dynamic student profile"** → Create `[studentId]/page.tsx` → Extract params → Add `generateMetadata()` → Create `not-found.tsx` if needed 3. **"Shared layout add karo"** → Create `layout.tsx` in target folder → Wrap with providers if needed → Maintain children render 4. **"Form add karo"** → `'use client'` component → useState for form data → Server Action for submission OR API route 5. **"KPI charts/Analytics"** → `'use client'` for Recharts → Server Component parent with data fetch → Pass data as props ## Quality Checklist Before marking task complete: - [ ] TypeScript strict mode enabled - [ ] Server Components used by default - [ ] `'use client'` only when necessary - [ ] `generateMetadata()` for SEO - [ ] Suspense boundaries for async data - [ ] Error boundaries (`error.tsx`) where needed - [ ] No hydration mismatches - [ ] Performance optimized (no blocking renders) - [ ] Mobile-first responsive design - [ ] Accessible (ARIA labels, keyboard nav) ## Common Patterns **Pattern 1: Server Component + Client Component Mix** ```typescript // Server Component export default async function Page() { const tasks = await fetchTasks(); return ; // Client component for interactivity } 'use client'; function TaskList({ tasks }: { tasks: Task[] }) { const [filter, setFilter] = useState('all'); const filtered = tasks.filter(/* ... */); return
{filtered.map(/* ... */)}
; } ``` **Pattern 2: Route Groups for Organization** ``` app/ (marketing)/ # Group: no URL segment about/page.tsx contact/page.tsx (dashboard)/ # Group: no URL segment layout.tsx page.tsx ``` **Pattern 3: API Routes (Route Handlers)** ```typescript // app/api/tasks/route.ts import { NextResponse } from 'next/server'; export async function GET() { const tasks = await db.query.tasks.findMany(); return NextResponse.json(tasks); } export async function POST(request: Request) { const body = await request.json(); const task = await createTask(body); return NextResponse.json(task, { status: 201 }); } ``` ## Trigger Examples - "Dashboard page banao" → Generate `app/dashboard/page.tsx` with server component - "Dynamic student profile route" → `app/students/[studentId]/page.tsx` with params and metadata - "Shared layout add karo" → `app/dashboard/layout.tsx` with children - "Admin panel with charts" → Server component + Client chart component - "Login page banao" → `'use client'` form component + API route - "404 page customize karo" → `app/not-found.tsx` - "Error handle karo" → `app/dashboard/error.tsx` ## References See `references/app-router-patterns.md` for advanced patterns and `references/api-routes.md` for route handler examples.