or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api.mdconcepts.mdindex.mdpages-router.mdpatterns.mdspecial-files.md

index.mddocs/

0

# Next.js - Quick Reference

1

2

Next.js 16.0.0 - React framework for production with App Router (recommended) and Pages Router (legacy).

3

4

## Installation & Setup

5

6

```bash

7

npm install next@16.0.0 react@19.0.0 react-dom@19.0.0

8

```

9

10

**File Structure:**

11

```

12

app/

13

├── layout.tsx # Root layout (wraps all pages)

14

├── page.tsx # Home page route: /

15

├── loading.tsx # Loading UI fallback

16

├── error.tsx # Error boundary

17

├── not-found.tsx # 404 page

18

└── blog/

19

├── page.tsx # Blog index route: /blog

20

└── [slug]/

21

└── page.tsx # Dynamic route: /blog/[slug]

22

```

23

24

## Quick Start

25

26

### Server Component (Default)

27

```typescript

28

// app/page.tsx

29

export default async function Page() {

30

const data = await fetch('https://api.example.com', {

31

next: { revalidate: 60 } // Cache for 60s

32

});

33

return <div>{await data.json()}</div>;

34

}

35

```

36

37

### Client Component

38

```typescript

39

// app/counter.tsx

40

'use client';

41

import { useState } from 'react';

42

43

export default function Counter() {

44

const [count, setCount] = useState(0);

45

return <button onClick={() => setCount(count + 1)}>{count}</button>;

46

}

47

```

48

49

## Decision Tree: Which Approach?

50

51

**App Router vs Pages Router?**

52

- **New project?** → App Router ⚡ (better performance, modern features)

53

- **Existing Pages app?** → Continue with Pages or migrate gradually

54

55

**Server vs Client Component?**

56

- **Fetching data, accessing backend?** → Server Component ⚡ (smaller bundle, faster)

57

- **Needs interactivity (useState, onClick)?** → Client Component 🔄 (required for interactivity)

58

59

**Static vs Dynamic?**

60

- **Content doesn't change often?** → Static with ISR ⚡ (fastest, cached at edge)

61

- **User-specific or real-time?** → Dynamic ⚠️ (fresh data, slower)

62

63

## Core Patterns

64

65

### 1. Navigation (Client)

66

```typescript

67

'use client';

68

import { useRouter } from 'next/navigation';

69

import Link from 'next/link';

70

71

const router = useRouter();

72

router.push('/about');

73

74

<Link href="/about">About</Link>

75

```

76

77

### 2. Redirect (Server)

78

```typescript

79

import { redirect } from 'next/navigation';

80

81

export default async function Page() {

82

const user = await getUser();

83

if (!user) redirect('/login');

84

return <div>{user.name}</div>;

85

}

86

```

87

88

### 3. Data Fetching with Caching

89

```typescript

90

// ⚡ Time-based revalidation (ISR) - Best for predictable content

91

const res = await fetch('https://api.example.com', {

92

next: { revalidate: 3600 } // 1 hour

93

});

94

95

// ⚡ Tag-based revalidation - Best for on-demand updates

96

const posts = await fetch('https://api.example.com/posts', {

97

next: { tags: ['posts'] }

98

});

99

revalidateTag('posts'); // Later in Server Action

100

101

// ⚠️ Force fresh data - Slower, always hits server

102

const res = await fetch('https://api.example.com', {

103

cache: 'no-store'

104

});

105

```

106

107

### 4. Dynamic Routes

108

```typescript

109

// app/blog/[slug]/page.tsx

110

export default async function Post({ params }: { params: Promise<{ slug: string }> }) {

111

const { slug } = await params;

112

const post = await getPost(slug);

113

return <article>{post.title}</article>;

114

}

115

```

116

117

### 5. API Routes

118

```typescript

119

// app/api/users/route.ts

120

import { NextRequest, NextResponse } from 'next/server';

121

122

export async function GET(request: NextRequest) {

123

return NextResponse.json({ users: [] });

124

}

125

126

export async function POST(request: NextRequest) {

127

const body = await request.json();

128

return NextResponse.json(body, { status: 201 });

129

}

130

```

131

132

### 6. Server Actions

133

```typescript

134

// app/actions.ts

135

'use server';

136

137

export async function createPost(formData: FormData) {

138

const title = formData.get('title');

139

await savePost(title);

140

revalidatePath('/posts');

141

}

142

143

// app/form.tsx

144

import { createPost } from './actions';

145

146

export default function Form() {

147

return (

148

<form action={createPost}>

149

<input name="title" />

150

<button type="submit">Submit</button>

151

</form>

152

);

153

}

154

```

155

156

## Core Imports

157

158

```typescript

159

// Navigation

160

import { useRouter, usePathname, useSearchParams } from 'next/navigation';

161

import Link from 'next/link';

162

import { redirect, notFound } from 'next/navigation';

163

164

// Components

165

import Image from 'next/image';

166

import Script from 'next/script';

167

168

// Server

169

import { NextRequest, NextResponse } from 'next/server';

170

import { revalidatePath, revalidateTag } from 'next/cache';

171

import { headers, cookies } from 'next/headers';

172

173

// Fonts

174

import { Inter } from 'next/font/google';

175

import localFont from 'next/font/local';

176

```

177

178

## Image Optimization

179

180

```typescript

181

import Image from 'next/image';

182

183

<Image

184

src="/photo.jpg"

185

alt="Photo"

186

width={800}

187

height={600}

188

priority // For above-the-fold

189

placeholder="blur"

190

/>

191

```

192

193

## CLI Commands

194

195

```bash

196

next dev --turbo -p 4000 # Dev server with Turbopack on port 4000

197

next dev -H 0.0.0.0 # Dev server accessible on network

198

next build --profile # Production build with React profiling

199

next build --no-lint # Build without linting

200

next start -p 8080 # Start production server on port 8080

201

next lint --fix # Run and auto-fix linting errors

202

next info # Display system information

203

```

204

205

## Configuration

206

207

```javascript

208

// next.config.js

209

const nextConfig = {

210

reactStrictMode: true,

211

images: {

212

domains: ['example.com'],

213

},

214

};

215

216

module.exports = nextConfig;

217

```

218

219

## Route Segment Config

220

221

```typescript

222

export const revalidate = 60; // ISR: revalidate every 60s

223

export const dynamic = 'force-dynamic'; // Always SSR

224

export const runtime = 'nodejs' | 'edge';

225

```

226

227

## Performance Patterns

228

229

### ⚡ Static Generation (ISR) - Fastest

230

```typescript

231

export const revalidate = 3600; // Revalidate every hour

232

233

export default async function Page() {

234

const data = await fetch('https://api.example.com');

235

return <div>{data}</div>;

236

}

237

```

238

239

### 🔄 Streaming with Suspense - Progressive Loading

240

```typescript

241

import { Suspense } from 'react';

242

243

export default function Page() {

244

return (

245

<Suspense fallback={<div>Loading...</div>}>

246

<SlowComponent />

247

</Suspense>

248

);

249

}

250

```

251

252

## Common Solutions

253

254

### Authentication

255

```typescript

256

import { cookies } from 'next/headers';

257

import { redirect } from 'next/navigation';

258

259

export default async function Dashboard() {

260

const cookieStore = await cookies();

261

if (!cookieStore.get('token')) redirect('/login');

262

return <div>Dashboard</div>;

263

}

264

```

265

266

### Loading & Error States

267

```typescript

268

// app/loading.tsx

269

export default function Loading() {

270

return <div>Loading...</div>;

271

}

272

273

// app/error.tsx

274

'use client';

275

export default function Error({

276

error,

277

reset

278

}: {

279

error: Error & { digest?: string };

280

reset: () => void;

281

}) {

282

return (

283

<div>

284

<h2>{error.message}</h2>

285

<button onClick={reset}>Try again</button>

286

</div>

287

);

288

}

289

```

290

291

## Common Mistakes to Avoid

292

293

**Server vs Client Components:**

294

- ❌ Adding 'use client' to all components (use sparingly, only when needed)

295

- ❌ Using React hooks in Server Components (useState, useEffect not available)

296

- ✓ Keep components as Server Components by default for better performance

297

298

**Data Fetching:**

299

- ❌ Fetching data in Client Components when Server Components can do it

300

- ❌ Using useEffect for initial data loads (use Server Components instead)

301

- ✓ Fetch in Server Components, pass data as props to Client Components

302

303

**Async Params (Next.js 15+):**

304

-`const { id } = params;` (params is now a Promise)

305

-`const { id } = await params;` (must await in Next.js 15+)

306

-`const { q } = searchParams;` (searchParams is also a Promise)

307

-`const { q } = await searchParams;` (must await)

308

309

**Image Optimization:**

310

- ❌ Using `<img>` tags (missing optimization)

311

- ❌ Not configuring external domains in next.config.js

312

- ✓ Use `<Image>` component and configure `images.domains`

313

314

**Caching Issues:**

315

- ❌ Forgetting to revalidate after mutations

316

- ❌ Using `cache: 'no-store'` everywhere (loses performance benefits)

317

- ✓ Use appropriate revalidation strategy (time-based or tag-based)

318

319

**Route Handlers:**

320

- ❌ Returning multiple responses in same handler

321

- ❌ Not handling errors properly (causes "Headers already sent")

322

- ✓ Return single NextResponse per request, add try-catch blocks

323

324

## Troubleshooting Quick Fixes

325

326

**"Error: Headers already sent"**

327

- Cause: Multiple responses sent in API route or middleware

328

- Fix: Ensure only one `return NextResponse` per code path, check for missing `return` statements

329

330

**Hydration Mismatch**

331

- Cause: Server-rendered HTML differs from client render

332

- Common: Using `Date.now()`, `Math.random()`, browser-only APIs in Server Components

333

- Fix: Move dynamic values to Client Components or use `suppressHydrationWarning`

334

335

**"Module not found" or Build Errors**

336

- Fix: Delete `.next` folder and `node_modules`, run `npm install`, restart dev server

337

```bash

338

rm -rf .next node_modules

339

npm install

340

next dev

341

```

342

343

**Image Optimization Failed**

344

- Cause: External domain not configured

345

- Fix: Add domain to next.config.js:

346

```javascript

347

images: {

348

domains: ['example.com', 'cdn.example.com'],

349

}

350

```

351

352

**Middleware Not Running**

353

- Cause: Incorrect matcher pattern or file location

354

- Fix: Ensure `middleware.ts` is at project root (not in app/), check matcher config

355

```typescript

356

export const config = {

357

matcher: ['/dashboard/:path*', '/((?!api|_next/static|_next/image|favicon.ico).*)'],

358

};

359

```

360

361

**Fetch Caching Issues**

362

- Cause: Next.js caches fetch by default

363

- Fix: Use `cache: 'no-store'` for dynamic data or set revalidation time

364

```typescript

365

fetch(url, { cache: 'no-store' }) // Always fresh

366

fetch(url, { next: { revalidate: 60 } }) // Cache for 60s

367

```

368

369

**TypeScript Errors with Params**

370

- Cause: Next.js 15+ made params async

371

- Fix: Update function signature and await params:

372

```typescript

373

export default async function Page({

374

params

375

}: {

376

params: Promise<{ id: string }>

377

}) {

378

const { id } = await params;

379

}

380

```

381

382

## File Organization Best Practices

383

384

**Recommended Project Structure:**

385

```

386

app/

387

├── (auth)/ # Route group (not in URL)

388

│ ├── login/

389

│ │ └── page.tsx # /login

390

│ └── register/

391

│ └── page.tsx # /register

392

├── (dashboard)/ # Route group

393

│ ├── layout.tsx # Shared dashboard layout

394

│ ├── page.tsx # /dashboard

395

│ └── settings/

396

│ └── page.tsx # /dashboard/settings

397

├── api/

398

│ └── users/

399

│ ├── route.ts # GET/POST /api/users

400

│ └── [id]/

401

│ └── route.ts # GET/PATCH/DELETE /api/users/[id]

402

├── components/ # Shared React components

403

│ ├── ui/ # UI primitives

404

│ └── features/ # Feature-specific components

405

├── actions/ # Server Actions

406

│ ├── auth.ts

407

│ └── posts.ts

408

├── lib/ # Utilities and helpers

409

│ ├── db.ts

410

│ └── utils.ts

411

├── layout.tsx # Root layout

412

└── page.tsx # Home page

413

414

middleware.ts # Root-level middleware

415

next.config.js # Next.js configuration

416

```

417

418

**Key Principles:**

419

- Use route groups `(name)` to organize without affecting URLs

420

- Colocate components, actions, and utilities with features when possible

421

- Keep shared code in top-level directories (components/, lib/)

422

- Use Server Actions in `actions/` directory for mutations

423

424

## Navigation Guide for Agents

425

426

**80% of queries:** Start with this file → Quick answers to common patterns

427

428

**Architectural decisions:** See [concepts.md](./concepts.md) for when-to-use guidance

429

430

**Complete implementations:** See [patterns.md](./patterns.md) for production-ready examples

431

432

**Detailed API reference:** See [api.md](./api.md) for exhaustive interface definitions

433

434

**Special files reference:** See [special-files.md](./special-files.md) for layout.tsx, page.tsx, etc.

435

436

**Legacy Pages Router:** See [pages-router.md](./pages-router.md) - use only for existing apps

437

438

**Progressive Loading Strategy:**

439

1. Check this file first (includes CLI commands, common mistakes, troubleshooting)

440

2. Consult concepts.md for architectural decisions

441

3. Use patterns.md for complete implementations

442

4. Reference api.md only for edge cases and complete type definitions

443

444

## Query Routing

445

446

**"How do I implement [X]?"**`patterns.md`

447

**"Should I use [X] or [Y]?"**`concepts.md`

448

**"What props does [component] accept?"**`api.md`

449

**"Show me a [pattern] example"**`patterns.md`

450

**"Why is [X] not working?"** → Check "Troubleshooting Quick Fixes" above

451

**"Am I making a mistake with [Y]?"** → Check "Common Mistakes to Avoid" above

452