home / skills / sickn33 / antigravity-awesome-skills / nextjs-best-practices

nextjs-best-practices skill

/skills/nextjs-best-practices

This skill helps you implement Next.js App Router best practices, balancing server and client components for scalable, high-performance apps.

This is most likely a fork of the nextjs-best-practices skill from xfstudio
npx playbooks add skill sickn33/antigravity-awesome-skills --skill nextjs-best-practices

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.7 KB
---
name: nextjs-best-practices
description: Next.js App Router principles. Server Components, data fetching, routing patterns.
allowed-tools: Read, Write, Edit, Glob, Grep
---

# Next.js Best Practices

> Principles for Next.js App Router development.

---

## 1. Server vs Client Components

### Decision Tree

```
Does it need...?
│
├── useState, useEffect, event handlers
│   └── Client Component ('use client')
│
├── Direct data fetching, no interactivity
│   └── Server Component (default)
│
└── Both? 
    └── Split: Server parent + Client child
```

### By Default

| Type | Use |
|------|-----|
| **Server** | Data fetching, layout, static content |
| **Client** | Forms, buttons, interactive UI |

---

## 2. Data Fetching Patterns

### Fetch Strategy

| Pattern | Use |
|---------|-----|
| **Default** | Static (cached at build) |
| **Revalidate** | ISR (time-based refresh) |
| **No-store** | Dynamic (every request) |

### Data Flow

| Source | Pattern |
|--------|---------|
| Database | Server Component fetch |
| API | fetch with caching |
| User input | Client state + server action |

---

## 3. Routing Principles

### File Conventions

| File | Purpose |
|------|---------|
| `page.tsx` | Route UI |
| `layout.tsx` | Shared layout |
| `loading.tsx` | Loading state |
| `error.tsx` | Error boundary |
| `not-found.tsx` | 404 page |

### Route Organization

| Pattern | Use |
|---------|-----|
| Route groups `(name)` | Organize without URL |
| Parallel routes `@slot` | Multiple same-level pages |
| Intercepting `(.)` | Modal overlays |

---

## 4. API Routes

### Route Handlers

| Method | Use |
|--------|-----|
| GET | Read data |
| POST | Create data |
| PUT/PATCH | Update data |
| DELETE | Remove data |

### Best Practices

- Validate input with Zod
- Return proper status codes
- Handle errors gracefully
- Use Edge runtime when possible

---

## 5. Performance Principles

### Image Optimization

- Use next/image component
- Set priority for above-fold
- Provide blur placeholder
- Use responsive sizes

### Bundle Optimization

- Dynamic imports for heavy components
- Route-based code splitting (automatic)
- Analyze with bundle analyzer

---

## 6. Metadata

### Static vs Dynamic

| Type | Use |
|------|-----|
| Static export | Fixed metadata |
| generateMetadata | Dynamic per-route |

### Essential Tags

- title (50-60 chars)
- description (150-160 chars)
- Open Graph images
- Canonical URL

---

## 7. Caching Strategy

### Cache Layers

| Layer | Control |
|-------|---------|
| Request | fetch options |
| Data | revalidate/tags |
| Full route | route config |

### Revalidation

| Method | Use |
|--------|-----|
| Time-based | `revalidate: 60` |
| On-demand | `revalidatePath/Tag` |
| No cache | `no-store` |

---

## 8. Server Actions

### Use Cases

- Form submissions
- Data mutations
- Revalidation triggers

### Best Practices

- Mark with 'use server'
- Validate all inputs
- Return typed responses
- Handle errors

---

## 9. Anti-Patterns

| ❌ Don't | ✅ Do |
|----------|-------|
| 'use client' everywhere | Server by default |
| Fetch in client components | Fetch in server |
| Skip loading states | Use loading.tsx |
| Ignore error boundaries | Use error.tsx |
| Large client bundles | Dynamic imports |

---

## 10. Project Structure

```
app/
├── (marketing)/     # Route group
│   └── page.tsx
├── (dashboard)/
│   ├── layout.tsx   # Dashboard layout
│   └── page.tsx
├── api/
│   └── [resource]/
│       └── route.ts
└── components/
    └── ui/
```

---

> **Remember:** Server Components are the default for a reason. Start there, add client only when needed.

Overview

This skill codifies Next.js App Router principles for building scalable, high-performance React apps. It emphasizes Server Components by default, clear data-fetching strategies, routing conventions, and performance and caching best practices. The guidance helps teams decide when to use client interactivity, server actions, and ISR versus dynamic rendering. It’s concise, actionable, and aimed at real-world app architecture.

How this skill works

The skill inspects common App Router concerns and maps them to practical patterns: component placement (server vs client), data-fetch strategies (static, ISR, no-store), and route file conventions (page, layout, loading, error, not-found). It explains API route handling, server actions, metadata generation, caching layers, and anti-patterns to avoid. Each recommendation is presented as a concrete rule or decision tree to speed architecture choices and code reviews.

When to use it

  • Use Server Components by default for data fetching, layouts, and static UI.
  • Add 'use client' only for local state, event handlers, forms, or browser-only APIs.
  • Choose ISR (revalidate) for mostly-static pages that need periodic updates.
  • Use no-store for per-request dynamic pages or personalized content.
  • Apply server actions for safe server-side mutations tied to forms or events.

Best practices

  • Split mixed concerns: server parent components with client child components for interactivity.
  • Fetch from the server for databases and backend APIs; use fetch caching options and tags for controlled revalidation.
  • Validate API and server-action inputs (e.g., Zod), return proper status codes, and handle errors with error.tsx boundaries.
  • Optimize bundles with dynamic imports, use next/image with responsive sizes and placeholders, and prioritize above-the-fold assets.
  • Use route conventions (layout.tsx, page.tsx, loading.tsx, error.tsx, not-found.tsx) and route groups/parallel routes to organize complexity.

Example use cases

  • Public marketing site: static pages with ISR, optimized images, and static metadata.
  • Authenticated dashboard: server layouts for data fetching, client components for interactive widgets, and route groups for modular sections.
  • Form-driven flows: server actions for submission handling, validation on server, and targeted revalidation.
  • API design: typed route handlers, Zod validation, edge runtime for low-latency endpoints.

FAQ

When should I mark a component with 'use client'?

Mark components 'use client' only when you need hooks, event handlers, or browser APIs. Keep parents as server components and move minimal interactive parts to client children.

How do I decide between ISR and no-store?

Use ISR (revalidate) when content can be slightly stale and benefits from caching. Use no-store for real-time, per-request, or highly personalized responses.

Where should I fetch data from?

Fetch sensitive data and DB queries in server components or API routes. For third-party APIs, use fetch with caching options and tags to control revalidation.