Claude
Skills
Sign in
Back

nextjs-development

Included with Lifetime
$97 forever

Next.js 16.2.4 with TypeScript — App Router, Server Components, use cache directive, Turbopack dev, Server Actions, ISR, SSR, SSG, MCP devtools, metadata API, route handlers, instrumentation.

Web Devnextjsdevelopmenttestingqualityautomationscripts

What this skill does


# Next.js Development

> Optimized for Next.js 16+, React 19+, TypeScript 5.5+, Turbopack, and App Router-first architectures.

Comprehensive reference for [Next.js](https://nextjs.org/docs) (latest: **16.2.4**) with the App Router, TypeScript, and modern patterns. Covers project structure, Server/Client Components, data fetching, caching with the `use cache` directive, Server Actions, MCP devtools integration, and performance optimization.

- Leverage native parallel subagent dispatch and 200k+ context windows where available.


## Component Review Rubric Reference

Apply the shared [Component Review Rubric](../frontend-design/SKILL.md#component-review-rubric) before approving Next.js components, then run the Next.js-specific checks below.

## Anti-Patterns

- Mixing server and client responsibilities: Bundle size, caching, and auth decisions become harder to reason about.
- Using legacy synchronous request APIs: Modern Next.js expects async request surfaces such as `params`, `headers()`, and `cookies()`.
- Skipping route-level loading and error states: Streaming apps feel broken when only the happy path is implemented.

## Verification Protocol

Before claiming "skill applied successfully":

1. Pass/fail: The Nextjs Development guidance is tied to a concrete route, component, screen, or design artifact.
2. Pass/fail: Component states cover loading, empty, error, success, and responsive breakpoints where applicable.
3. Pass/fail: Accessibility, visual hierarchy, and interaction behavior are reviewed against the shared component rubric.
4. Pressure-test scenario: Review the component on a narrow mobile viewport, keyboard-only path, and slow-loading state.
5. Success metric: Zero generic UI approval; every approval cites rendered behavior or source evidence.


## Before and After Example

```typescript
// Before
export default function ProductPage({ params }: { params: { id: string } }) {
  const [product, setProduct] = useState<Product | null>(null);
  useEffect(() => {
    fetch(`/api/products/${params.id}`).then((r) => r.json()).then(setProduct);
  }, [params.id]);
  return product ? <ProductView product={product} /> : <Spinner />;
}

// After
export default async function ProductPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params;
  const product = await getProduct(id);
  return <ProductView product={product} />;
}
```

Moves data fetching into the server component and follows the async request API used in current Next.js releases.

## Activation Conditions

Use symptom -> action triggers: when one matches, apply this skill and verify with the protocol below.

### App Router & Routing
- Creating or modifying `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`
- Working with dynamic routes `[slug]`, catch-all `[...slug]`, optional catch-all `[[...slug]]`
- Parallel routes `@slot`, intercepting routes, route groups `(group)`
- New v15/v16 file conventions: `forbidden.tsx`, `proxy.ts`, `template.tsx`, `unauthorized.tsx`

### Server & Client Components
- Deciding when to use `"use client"` or `"use server"` directives
- Component boundary questions, RSC + RCC composition patterns
- Passing Server Components as children/props to Client Components
- `taint` API for data security

### Data Fetching & Caching
- Using `use cache` directive (replaces `cache: 'force-cache'`)
- `cacheTag()`, `cacheLife()`, `revalidateTag()`, `revalidatePath()`
- Async Request APIs: `await cookies()`, `await headers()`, `await params`, `await searchParams`
- `after()` for post-response work, `connection()` for dynamic rendering

### Server Actions & Forms
- `"use server"` in functions or module scope
- `<Form>` component with client-side navigation
- Form validation, optimistic updates, error handling
- `after()` for side-effects after action completes

### Performance & Turbopack
- `next dev` with Turbopack (default in v15+, stable)
- Image optimization with `next/image`
- Font subsetting with `next/font`
- Lazy loading, bundle optimization, `serverComponentsHmrCache`

### Next.js MCP Dev Tools
- Querying live errors, logs, routes from the running dev server
- Using `next-devtools-mcp` with coding agents (requires Next.js 16+)
- Upgrading to Next.js 16 with codemods
- Enabling Cache Components feature

---

## Part 1: Project Setup & Config

### Creating a New Project

```bash
npx create-next-app@latest my-app --typescript --tailwind --eslint --app
```

### TypeScript Config (`next.config.ts`)

```typescript
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  reactCompiler: true,          // stable in v16
  reactStrictMode: true,
  serverExternalPackages: ['sharp'],  // renamed from serverComponentsExternalPackages in v15
  experimental: {
    turbopackFileSystemCache: true,   // persist Turbopack cache across restarts
    serverComponentsHmrCache: true,   // cache fetch responses during HMR
  },
  cacheLife: {                        // custom cache profiles
    frequent: { stale: 60, revalidate: 60, expire: 3600 },
    daily: { stale: 3600, revalidate: 3600, expire: 86400 },
  },
}

export default nextConfig
```

### Project Structure

```
my-app/
├── app/
│   ├── layout.tsx          # Root layout (required)
│   ├── page.tsx            # Home page
│   ├── loading.tsx         # Streaming skeleton
│   ├── error.tsx           # Error boundary
│   ├── not-found.tsx       # 404 page
│   ├── forbidden.tsx       # 403 page (v16)
│   ├── unauthorized.tsx    # 401 page (v16)
│   ├── (marketing)/        # Route group (no URL segment)
│   │   └── about/page.tsx
│   ├── blog/
│   │   └── [slug]/page.tsx # Dynamic route
│   └── api/
│       └── route.ts        # Route Handler
├── components/             # Shared RSC/RCC components
├── lib/                    # Server utilities
├── public/                 # Static assets
├── next.config.ts          # TypeScript config (v15+)
├── .mcp.json               # MCP server config (v16)
└── instrumentation.ts      # Server lifecycle hooks (stable v15)
```

---

## Part 2: App Router Routing

### File Conventions

| File | Purpose |
|------|---------|
| `page.tsx` | UI for the route segment, makes it publicly accessible |
| `layout.tsx` | Shared UI that persists across navigations |
| `template.tsx` | Like layout, but remounts on navigation |
| `loading.tsx` | Suspense skeleton; shown while page loads |
| `error.tsx` | Isolate errors; `"use client"` required |
| `not-found.tsx` | Rendered by `notFound()` or 404 |
| `forbidden.tsx` | Rendered by `forbidden()` (v16) |
| `unauthorized.tsx` | Rendered by `unauthorized()` (v16) |
| `route.ts` | API endpoint (cannot coexist with page.tsx at same level) |
| `proxy.ts` | Lightweight HTTP proxy (v16) |
| `middleware.ts` | Runs before request completes (project root) |
| `instrumentation.ts` | Server lifecycle, OpenTelemetry (stable v15) |
| `instrumentation-client.ts` | Client-side performance monitoring (v16) |

### Dynamic Routes

```typescript
// app/blog/[slug]/page.tsx
// IMPORTANT: params is now async in Next.js 15+
export default async function BlogPost({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params  // must await in v15+
  return <h1>{slug}</h1>
}

// Generate static paths
export async function generateStaticParams() {
  const posts = await fetchPosts()
  return posts.map((post) => ({ slug: post.slug }))
}
```

### Route Groups & Parallel Routes

```
app/
├── (auth)/                 # Route group: no URL impact
│   ├── login/page.tsx      # /login
│   └── register/page.tsx   # /register
├── @modal/                 # Parallel route (slot)
│   └── photo/[id]/page.tsx
├── layout.tsx              # Receives { children, modal } props
└── page.tsx
```

### Intercepting Routes

```
app/
├── photos/[id]/page.tsx    # Full page: /photos/123
└── @modal/
    └── (.)photos/[id]/     # Intercept same-level route
        └── page.tsx        # Renders as modal without full navigation
```

#
Files: 8
Size: 65.3 KB
Complexity: 70/100
Category: Web Dev

Related in Web Dev