nextjs-app-router-patterns

ak-eyther's avatarfrom ak-eyther

Build Next.js 13+ App Router applications with server components, client components, API routes, middleware, and streaming. Use when implementing Next.js features, route handlers, or RSC patterns.

⭐0stars🔀0forks📁View on GitHub🕐Updated Jan 6, 2026

When & Why to Use This Skill

This Claude skill streamlines the development of modern web applications using the Next.js 13+ App Router architecture. It provides expert guidance and code patterns for implementing React Server Components (RSC), Client Components, streaming, and advanced routing, ensuring developers follow best practices for performance, scalability, and SEO-friendly web development.

Use Cases

  • Case 1: Architecting high-performance web applications using React Server Components to minimize client-side JavaScript and improve Core Web Vitals.
  • Case 2: Implementing complex routing structures with nested layouts, loading states, and error boundaries for a seamless user experience.
  • Case 3: Developing secure and scalable API Route Handlers and Middleware for authentication, redirects, and server-side logic.
  • Case 4: Optimizing data fetching strategies with granular cache control and streaming to handle dynamic content efficiently.
namenextjs-app-router-patterns
descriptionBuild Next.js 13+ App Router applications with server components, client components, API routes, middleware, and streaming. Use when implementing Next.js features, route handlers, or RSC patterns.
short-descriptionNext.js App Router patterns

Next.js App Router Patterns

Page Structure

// app/dashboard/page.tsx
export default async function DashboardPage() {
  const data = await fetch('https://api.example.com/data')
  return <div>{/* Server Component */}</div>
}

Server vs Client Components

Server Component (default):

// No "use client" = Server Component
export default async function ServerComp() {
  const data = await fetchData() // Direct async/await
  return <div>{data}</div>
}

Client Component:

'use client'
import { useState } from 'react'

export default function ClientComp() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}

API Routes

// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
  const users = await db.user.findMany()
  return NextResponse.json(users)
}

export async function POST(request: NextRequest) {
  const body = await request.json()
  const user = await db.user.create({ data: body })
  return NextResponse.json(user, { status: 201 })
}

Layouts

// app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div className="dashboard">
      <nav>{/* Sidebar */}</nav>
      <main>{children}</main>
    </div>
  )
}

Loading & Error States

// app/dashboard/loading.tsx
export default function Loading() {
  return <div>Loading...</div>
}

// app/dashboard/error.tsx
'use client'
export default function Error({ error, reset }: {
  error: Error
  reset: () => void
}) {
  return <div>Error: {error.message}</div>
}

Data Fetching

// Server Component - Direct fetch
async function getData() {
  const res = await fetch('https://api.example.com', {
    cache: 'no-store', // or 'force-cache'
  })
  return res.json()
}

export default async function Page() {
  const data = await getData()
  return <div>{data.title}</div>
}

Middleware

// middleware.ts (root level)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const token = request.cookies.get('token')

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return NextResponse.next()
}

export const config = {
  matcher: '/dashboard/:path*',
}

Scripts

  • scripts/skill_info.py: Print skill name and description.