@kood/claude-code 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/templates/.claude/agents/code-reviewer.md +138 -123
- package/templates/.claude/agents/dependency-manager.md +99 -84
- package/templates/.claude/agents/deployment-validator.md +70 -55
- package/templates/.claude/agents/git-operator.md +78 -63
- package/templates/.claude/agents/implementation-executor.md +109 -94
- package/templates/.claude/agents/ko-to-en-translator.md +74 -0
- package/templates/.claude/agents/lint-fixer.md +93 -78
- package/templates/.claude/agents/refactor-advisor.md +136 -121
- package/templates/.claude/commands/agent-creator.md +199 -184
- package/templates/.claude/commands/bug-fix.md +207 -192
- package/templates/.claude/commands/command-creator.md +69 -53
- package/templates/.claude/commands/docs-creator.md +72 -56
- package/templates/.claude/commands/docs-refactor.md +41 -25
- package/templates/.claude/commands/execute.md +27 -11
- package/templates/.claude/commands/git-all.md +46 -31
- package/templates/.claude/commands/git-session.md +57 -41
- package/templates/.claude/commands/git.md +49 -33
- package/templates/.claude/commands/lint-fix.md +153 -137
- package/templates/.claude/commands/lint-init.md +76 -60
- package/templates/.claude/commands/plan.md +275 -259
- package/templates/.claude/commands/prd.md +39 -23
- package/templates/.claude/commands/pre-deploy.md +124 -108
- package/templates/.claude/commands/refactor.md +162 -146
- package/templates/.claude/commands/version-update.md +32 -16
- package/templates/hono/CLAUDE.md +28 -27
- package/templates/hono/docs/architecture.md +24 -24
- package/templates/hono/docs/deployment/cloudflare.md +18 -18
- package/templates/hono/docs/deployment/docker.md +13 -13
- package/templates/hono/docs/deployment/index.md +19 -19
- package/templates/hono/docs/deployment/railway.md +32 -32
- package/templates/hono/docs/deployment/vercel.md +29 -29
- package/templates/hono/docs/guides/conventions.md +57 -57
- package/templates/hono/docs/guides/env-setup.md +47 -47
- package/templates/hono/docs/guides/getting-started.md +27 -27
- package/templates/hono/docs/library/hono/error-handling.md +11 -11
- package/templates/hono/docs/library/hono/index.md +4 -4
- package/templates/hono/docs/library/hono/middleware.md +18 -18
- package/templates/hono/docs/library/hono/rpc.md +7 -7
- package/templates/hono/docs/library/hono/validation.md +6 -6
- package/templates/hono/docs/library/prisma/cloudflare-d1.md +29 -29
- package/templates/hono/docs/library/prisma/config.md +16 -16
- package/templates/hono/docs/library/prisma/index.md +32 -32
- package/templates/hono/docs/library/t3-env/index.md +22 -22
- package/templates/hono/docs/library/zod/index.md +31 -31
- package/templates/nextjs/CLAUDE.md +54 -51
- package/templates/nextjs/docs/architecture.md +812 -0
- package/templates/nextjs/docs/design.md +183 -183
- package/templates/nextjs/docs/guides/conventions.md +86 -86
- package/templates/nextjs/docs/guides/getting-started.md +28 -28
- package/templates/nextjs/docs/guides/routes.md +32 -32
- package/templates/nextjs/docs/library/better-auth/index.md +70 -70
- package/templates/nextjs/docs/library/nextjs/app-router.md +43 -43
- package/templates/nextjs/docs/library/nextjs/caching.md +73 -73
- package/templates/nextjs/docs/library/nextjs/index.md +51 -51
- package/templates/nextjs/docs/library/nextjs/middleware.md +41 -41
- package/templates/nextjs/docs/library/nextjs/route-handlers.md +31 -31
- package/templates/nextjs/docs/library/nextjs/server-actions.md +34 -34
- package/templates/nextjs/docs/library/prisma/cloudflare-d1.md +20 -20
- package/templates/nextjs/docs/library/prisma/config.md +18 -18
- package/templates/nextjs/docs/library/prisma/crud.md +17 -17
- package/templates/nextjs/docs/library/prisma/index.md +18 -18
- package/templates/nextjs/docs/library/prisma/relations.md +16 -16
- package/templates/nextjs/docs/library/prisma/schema.md +23 -23
- package/templates/nextjs/docs/library/prisma/setup.md +6 -6
- package/templates/nextjs/docs/library/prisma/transactions.md +10 -10
- package/templates/nextjs/docs/library/tanstack-query/index.md +6 -6
- package/templates/nextjs/docs/library/tanstack-query/invalidation.md +20 -20
- package/templates/nextjs/docs/library/tanstack-query/optimistic-updates.md +4 -4
- package/templates/nextjs/docs/library/tanstack-query/use-mutation.md +15 -15
- package/templates/nextjs/docs/library/tanstack-query/use-query.md +22 -22
- package/templates/nextjs/docs/library/zod/complex-types.md +11 -11
- package/templates/nextjs/docs/library/zod/index.md +8 -8
- package/templates/nextjs/docs/library/zod/transforms.md +11 -11
- package/templates/nextjs/docs/library/zod/validation.md +9 -9
- package/templates/npx/CLAUDE.md +38 -37
- package/templates/npx/docs/library/commander/index.md +12 -12
- package/templates/npx/docs/library/fs-extra/index.md +9 -9
- package/templates/npx/docs/library/prompts/index.md +3 -3
- package/templates/npx/docs/references/patterns.md +12 -12
- package/templates/tanstack-start/CLAUDE.md +54 -53
- package/templates/tanstack-start/docs/architecture.md +128 -128
- package/templates/tanstack-start/docs/design.md +169 -169
- package/templates/tanstack-start/docs/guides/conventions.md +43 -43
- package/templates/tanstack-start/docs/guides/env-setup.md +35 -35
- package/templates/tanstack-start/docs/guides/getting-started.md +19 -19
- package/templates/tanstack-start/docs/guides/hooks.md +45 -45
- package/templates/tanstack-start/docs/guides/routes.md +54 -54
- package/templates/tanstack-start/docs/guides/services.md +45 -45
- package/templates/tanstack-start/docs/library/better-auth/index.md +68 -68
- package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +19 -19
- package/templates/tanstack-start/docs/library/prisma/config.md +16 -16
- package/templates/tanstack-start/docs/library/prisma/crud.md +17 -17
- package/templates/tanstack-start/docs/library/prisma/index.md +17 -17
- package/templates/tanstack-start/docs/library/prisma/relations.md +16 -16
- package/templates/tanstack-start/docs/library/prisma/schema.md +23 -23
- package/templates/tanstack-start/docs/library/prisma/setup.md +6 -6
- package/templates/tanstack-start/docs/library/prisma/transactions.md +10 -10
- package/templates/tanstack-start/docs/library/t3-env/index.md +21 -160
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +6 -6
- package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +19 -19
- package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +4 -4
- package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +14 -14
- package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +21 -21
- package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +9 -9
- package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +11 -11
- package/templates/tanstack-start/docs/library/tanstack-router/index.md +18 -18
- package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +17 -17
- package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +5 -5
- package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +10 -10
- package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +8 -8
- package/templates/tanstack-start/docs/library/tanstack-start/index.md +15 -15
- package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +9 -9
- package/templates/tanstack-start/docs/library/tanstack-start/routing.md +6 -6
- package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +18 -18
- package/templates/tanstack-start/docs/library/tanstack-start/setup.md +4 -4
- package/templates/tanstack-start/docs/library/zod/complex-types.md +11 -11
- package/templates/tanstack-start/docs/library/zod/index.md +8 -8
- package/templates/tanstack-start/docs/library/zod/transforms.md +11 -11
- package/templates/tanstack-start/docs/library/zod/validation.md +9 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Next.js - Index
|
|
2
2
|
|
|
3
|
-
> Next.js 15 App Router
|
|
3
|
+
> Next.js 15 App Router core concepts
|
|
4
4
|
|
|
5
5
|
<context>
|
|
6
6
|
@app-router.md
|
|
@@ -12,21 +12,21 @@
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Core Concepts
|
|
16
16
|
|
|
17
|
-
|
|
|
18
|
-
|
|
19
|
-
| **App Router** |
|
|
20
|
-
| **Server Components** |
|
|
21
|
-
| **Client Components** | `"use client"`
|
|
22
|
-
| **Server Actions** | `"use server"`
|
|
23
|
-
| **Route Handlers** | REST API
|
|
17
|
+
| Concept | Description |
|
|
18
|
+
|---------|-------------|
|
|
19
|
+
| **App Router** | File-based routing (`app/` directory) |
|
|
20
|
+
| **Server Components** | Default components (server rendering) |
|
|
21
|
+
| **Client Components** | Requires `"use client"` declaration |
|
|
22
|
+
| **Server Actions** | `"use server"` functions (type-safe API) |
|
|
23
|
+
| **Route Handlers** | REST API endpoints (`app/api/`) |
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Quick Start
|
|
28
28
|
|
|
29
|
-
###
|
|
29
|
+
### Create Project
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
npx create-next-app@latest my-app --typescript --tailwind --app
|
|
@@ -34,10 +34,10 @@ cd my-app
|
|
|
34
34
|
npm run dev
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
###
|
|
37
|
+
### Basic Page
|
|
38
38
|
|
|
39
39
|
```typescript
|
|
40
|
-
// app/page.tsx (Server Component -
|
|
40
|
+
// app/page.tsx (Server Component - default)
|
|
41
41
|
export default async function HomePage() {
|
|
42
42
|
const data = await fetch('https://api.example.com/data')
|
|
43
43
|
const json = await data.json()
|
|
@@ -62,11 +62,11 @@ export function Counter() {
|
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
|
-
##
|
|
65
|
+
## File Structure
|
|
66
66
|
|
|
67
67
|
```
|
|
68
68
|
app/
|
|
69
|
-
├── layout.tsx # Root layout (
|
|
69
|
+
├── layout.tsx # Root layout (required)
|
|
70
70
|
├── page.tsx # Home (/)
|
|
71
71
|
├── about/
|
|
72
72
|
│ └── page.tsx # /about
|
|
@@ -81,33 +81,33 @@ app/
|
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
84
|
-
##
|
|
84
|
+
## Key Files
|
|
85
85
|
|
|
86
|
-
|
|
|
87
|
-
|
|
88
|
-
| `layout.tsx` |
|
|
89
|
-
| `page.tsx` |
|
|
90
|
-
| `loading.tsx` |
|
|
91
|
-
| `error.tsx` |
|
|
92
|
-
| `not-found.tsx` | 404
|
|
93
|
-
| `route.ts` | API
|
|
86
|
+
| File | Purpose |
|
|
87
|
+
|------|---------|
|
|
88
|
+
| `layout.tsx` | Shared layout (nestable) |
|
|
89
|
+
| `page.tsx` | Page component |
|
|
90
|
+
| `loading.tsx` | Loading UI (Suspense) |
|
|
91
|
+
| `error.tsx` | Error UI (Error Boundary) |
|
|
92
|
+
| `not-found.tsx` | 404 page |
|
|
93
|
+
| `route.ts` | API endpoint |
|
|
94
94
|
|
|
95
95
|
---
|
|
96
96
|
|
|
97
97
|
## Server vs Client Components
|
|
98
98
|
|
|
99
|
-
|
|
|
100
|
-
|
|
101
|
-
|
|
|
102
|
-
|
|
|
99
|
+
| Aspect | Server | Client |
|
|
100
|
+
|--------|--------|--------|
|
|
101
|
+
| Declaration | Default | `"use client"` |
|
|
102
|
+
| Data Fetching | ✅ async/await | ❌ (use useQuery) |
|
|
103
103
|
| Hooks | ❌ | ✅ useState, useEffect |
|
|
104
|
-
|
|
|
104
|
+
| Browser API | ❌ | ✅ window, localStorage |
|
|
105
105
|
| Event Handlers | ❌ | ✅ onClick, onChange |
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
- Server
|
|
109
|
-
- Server
|
|
110
|
-
- Client
|
|
107
|
+
**Rules:**
|
|
108
|
+
- Server Components are default → add `"use client"` only when needed
|
|
109
|
+
- Server Components can contain Client Components
|
|
110
|
+
- Client Components cannot contain Server Components (but can receive them as props)
|
|
111
111
|
|
|
112
112
|
---
|
|
113
113
|
|
|
@@ -183,13 +183,13 @@ export const config = {
|
|
|
183
183
|
|
|
184
184
|
---
|
|
185
185
|
|
|
186
|
-
##
|
|
186
|
+
## Data Fetching
|
|
187
187
|
|
|
188
|
-
### Server Component (
|
|
188
|
+
### Server Component (recommended)
|
|
189
189
|
|
|
190
190
|
```typescript
|
|
191
191
|
export default async function PostsPage() {
|
|
192
|
-
const posts = await prisma.post.findMany() //
|
|
192
|
+
const posts = await prisma.post.findMany() // Direct DB access
|
|
193
193
|
return <PostsList posts={posts} />
|
|
194
194
|
}
|
|
195
195
|
```
|
|
@@ -213,13 +213,13 @@ export function PostsList() {
|
|
|
213
213
|
|
|
214
214
|
---
|
|
215
215
|
|
|
216
|
-
##
|
|
216
|
+
## Caching
|
|
217
217
|
|
|
218
|
-
|
|
|
219
|
-
|
|
220
|
-
| `revalidatePath("/posts")` |
|
|
221
|
-
| `revalidateTag("posts")` |
|
|
222
|
-
| `unstable_cache()` |
|
|
218
|
+
| Function | Purpose |
|
|
219
|
+
|----------|---------|
|
|
220
|
+
| `revalidatePath("/posts")` | Invalidate specific path cache |
|
|
221
|
+
| `revalidateTag("posts")` | Invalidate tag-based cache |
|
|
222
|
+
| `unstable_cache()` | Cache function results |
|
|
223
223
|
|
|
224
224
|
```typescript
|
|
225
225
|
import { revalidatePath, revalidateTag } from "next/cache"
|
|
@@ -227,8 +227,8 @@ import { revalidatePath, revalidateTag } from "next/cache"
|
|
|
227
227
|
export async function createPost(data: PostInput) {
|
|
228
228
|
const post = await prisma.post.create({ data })
|
|
229
229
|
|
|
230
|
-
revalidatePath("/posts") // /posts
|
|
231
|
-
revalidateTag("posts") // "posts"
|
|
230
|
+
revalidatePath("/posts") // Invalidate /posts cache
|
|
231
|
+
revalidateTag("posts") // Invalidate "posts" tag cache
|
|
232
232
|
|
|
233
233
|
return post
|
|
234
234
|
}
|
|
@@ -236,7 +236,7 @@ export async function createPost(data: PostInput) {
|
|
|
236
236
|
|
|
237
237
|
---
|
|
238
238
|
|
|
239
|
-
##
|
|
239
|
+
## Environment Variables
|
|
240
240
|
|
|
241
241
|
```bash
|
|
242
242
|
# .env.local
|
|
@@ -246,15 +246,15 @@ NEXTAUTH_URL="http://localhost:3000"
|
|
|
246
246
|
NEXT_PUBLIC_API_URL="https://api.example.com"
|
|
247
247
|
```
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
- `NEXT_PUBLIC_*`:
|
|
251
|
-
-
|
|
249
|
+
**Rules:**
|
|
250
|
+
- `NEXT_PUBLIC_*`: Accessible in client
|
|
251
|
+
- Others: Server-only
|
|
252
252
|
|
|
253
253
|
---
|
|
254
254
|
|
|
255
|
-
##
|
|
255
|
+
## Deployment
|
|
256
256
|
|
|
257
|
-
### Vercel (
|
|
257
|
+
### Vercel (recommended)
|
|
258
258
|
|
|
259
259
|
```bash
|
|
260
260
|
npm i -g vercel
|
|
@@ -282,7 +282,7 @@ npm start
|
|
|
282
282
|
|
|
283
283
|
---
|
|
284
284
|
|
|
285
|
-
##
|
|
285
|
+
## References
|
|
286
286
|
|
|
287
287
|
- [App Router](app-router.md)
|
|
288
288
|
- [Server Actions](server-actions.md)
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# Middleware
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Functions executed before request processing
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Basic Usage
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
|
-
// middleware.ts (
|
|
10
|
+
// middleware.ts (root)
|
|
11
11
|
import { NextResponse } from "next/server"
|
|
12
12
|
import type { NextRequest } from "next/server"
|
|
13
13
|
|
|
14
14
|
export function middleware(request: NextRequest) {
|
|
15
|
-
//
|
|
15
|
+
// Execute logic...
|
|
16
16
|
return NextResponse.next()
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
//
|
|
19
|
+
// Matcher configuration
|
|
20
20
|
export const config = {
|
|
21
21
|
matcher: ["/dashboard/:path*", "/api/:path*"],
|
|
22
22
|
}
|
|
@@ -24,12 +24,12 @@ export const config = {
|
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
## Response
|
|
27
|
+
## Response Types
|
|
28
28
|
|
|
29
29
|
### NextResponse.next()
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
|
-
//
|
|
32
|
+
// Pass request to next middleware or route
|
|
33
33
|
export function middleware(request: NextRequest) {
|
|
34
34
|
return NextResponse.next()
|
|
35
35
|
}
|
|
@@ -38,7 +38,7 @@ export function middleware(request: NextRequest) {
|
|
|
38
38
|
### NextResponse.redirect()
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
|
-
//
|
|
41
|
+
// Redirect to different URL
|
|
42
42
|
export function middleware(request: NextRequest) {
|
|
43
43
|
return NextResponse.redirect(new URL("/login", request.url))
|
|
44
44
|
}
|
|
@@ -47,7 +47,7 @@ export function middleware(request: NextRequest) {
|
|
|
47
47
|
### NextResponse.rewrite()
|
|
48
48
|
|
|
49
49
|
```typescript
|
|
50
|
-
//
|
|
50
|
+
// Render different page while keeping URL
|
|
51
51
|
export function middleware(request: NextRequest) {
|
|
52
52
|
return NextResponse.rewrite(new URL("/dashboard/home", request.url))
|
|
53
53
|
}
|
|
@@ -55,7 +55,7 @@ export function middleware(request: NextRequest) {
|
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
58
|
-
##
|
|
58
|
+
## Authentication
|
|
59
59
|
|
|
60
60
|
```typescript
|
|
61
61
|
import { NextResponse } from "next/server"
|
|
@@ -64,7 +64,7 @@ import type { NextRequest } from "next/server"
|
|
|
64
64
|
export function middleware(request: NextRequest) {
|
|
65
65
|
const token = request.cookies.get("token")
|
|
66
66
|
|
|
67
|
-
//
|
|
67
|
+
// Redirect to login if no token
|
|
68
68
|
if (!token) {
|
|
69
69
|
return NextResponse.redirect(new URL("/login", request.url))
|
|
70
70
|
}
|
|
@@ -79,9 +79,9 @@ export const config = {
|
|
|
79
79
|
|
|
80
80
|
---
|
|
81
81
|
|
|
82
|
-
##
|
|
82
|
+
## Cookie Handling
|
|
83
83
|
|
|
84
|
-
###
|
|
84
|
+
### Reading
|
|
85
85
|
|
|
86
86
|
```typescript
|
|
87
87
|
export function middleware(request: NextRequest) {
|
|
@@ -94,7 +94,7 @@ export function middleware(request: NextRequest) {
|
|
|
94
94
|
}
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
###
|
|
97
|
+
### Setting
|
|
98
98
|
|
|
99
99
|
```typescript
|
|
100
100
|
export function middleware(request: NextRequest) {
|
|
@@ -103,7 +103,7 @@ export function middleware(request: NextRequest) {
|
|
|
103
103
|
response.cookies.set("visited", "true", {
|
|
104
104
|
httpOnly: true,
|
|
105
105
|
secure: true,
|
|
106
|
-
maxAge: 60 * 60 * 24 * 7, // 7
|
|
106
|
+
maxAge: 60 * 60 * 24 * 7, // 7 days
|
|
107
107
|
})
|
|
108
108
|
|
|
109
109
|
return response
|
|
@@ -112,9 +112,9 @@ export function middleware(request: NextRequest) {
|
|
|
112
112
|
|
|
113
113
|
---
|
|
114
114
|
|
|
115
|
-
## Headers
|
|
115
|
+
## Headers Handling
|
|
116
116
|
|
|
117
|
-
###
|
|
117
|
+
### Reading
|
|
118
118
|
|
|
119
119
|
```typescript
|
|
120
120
|
export function middleware(request: NextRequest) {
|
|
@@ -127,7 +127,7 @@ export function middleware(request: NextRequest) {
|
|
|
127
127
|
}
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
###
|
|
130
|
+
### Setting
|
|
131
131
|
|
|
132
132
|
```typescript
|
|
133
133
|
export function middleware(request: NextRequest) {
|
|
@@ -142,13 +142,13 @@ export function middleware(request: NextRequest) {
|
|
|
142
142
|
|
|
143
143
|
---
|
|
144
144
|
|
|
145
|
-
##
|
|
145
|
+
## Path-based Processing
|
|
146
146
|
|
|
147
147
|
```typescript
|
|
148
148
|
export function middleware(request: NextRequest) {
|
|
149
149
|
const { pathname } = request.nextUrl
|
|
150
150
|
|
|
151
|
-
// /api/*
|
|
151
|
+
// /api/* routes
|
|
152
152
|
if (pathname.startsWith("/api/")) {
|
|
153
153
|
const token = request.headers.get("authorization")
|
|
154
154
|
|
|
@@ -157,7 +157,7 @@ export function middleware(request: NextRequest) {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
// /admin/*
|
|
160
|
+
// /admin/* routes
|
|
161
161
|
if (pathname.startsWith("/admin/")) {
|
|
162
162
|
const role = request.cookies.get("role")?.value
|
|
163
163
|
|
|
@@ -172,9 +172,9 @@ export function middleware(request: NextRequest) {
|
|
|
172
172
|
|
|
173
173
|
---
|
|
174
174
|
|
|
175
|
-
## Matcher
|
|
175
|
+
## Matcher Configuration
|
|
176
176
|
|
|
177
|
-
###
|
|
177
|
+
### Array
|
|
178
178
|
|
|
179
179
|
```typescript
|
|
180
180
|
export const config = {
|
|
@@ -182,23 +182,23 @@ export const config = {
|
|
|
182
182
|
}
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
-
###
|
|
185
|
+
### Regex
|
|
186
186
|
|
|
187
187
|
```typescript
|
|
188
188
|
export const config = {
|
|
189
189
|
matcher: [
|
|
190
190
|
/*
|
|
191
|
-
*
|
|
192
|
-
* - _next/static (
|
|
193
|
-
* - _next/image (
|
|
194
|
-
* - favicon.ico (
|
|
191
|
+
* Exclude paths:
|
|
192
|
+
* - _next/static (static files)
|
|
193
|
+
* - _next/image (image optimization)
|
|
194
|
+
* - favicon.ico (favicon)
|
|
195
195
|
*/
|
|
196
196
|
"/((?!_next/static|_next/image|favicon.ico).*)",
|
|
197
197
|
],
|
|
198
198
|
}
|
|
199
199
|
```
|
|
200
200
|
|
|
201
|
-
###
|
|
201
|
+
### Conditional
|
|
202
202
|
|
|
203
203
|
```typescript
|
|
204
204
|
export const config = {
|
|
@@ -216,7 +216,7 @@ export const config = {
|
|
|
216
216
|
|
|
217
217
|
---
|
|
218
218
|
|
|
219
|
-
##
|
|
219
|
+
## Logging
|
|
220
220
|
|
|
221
221
|
```typescript
|
|
222
222
|
export function middleware(request: NextRequest) {
|
|
@@ -248,7 +248,7 @@ import type { NextRequest } from "next/server"
|
|
|
248
248
|
const rateLimit = new Map<string, { count: number; resetAt: number }>()
|
|
249
249
|
|
|
250
250
|
const LIMIT = 10 // 10 requests
|
|
251
|
-
const WINDOW = 60 * 1000 // 1
|
|
251
|
+
const WINDOW = 60 * 1000 // 1 minute
|
|
252
252
|
|
|
253
253
|
export function middleware(request: NextRequest) {
|
|
254
254
|
const ip = request.ip || "unknown"
|
|
@@ -296,7 +296,7 @@ export function middleware(request: NextRequest) {
|
|
|
296
296
|
|
|
297
297
|
---
|
|
298
298
|
|
|
299
|
-
## A/B
|
|
299
|
+
## A/B Testing
|
|
300
300
|
|
|
301
301
|
```typescript
|
|
302
302
|
import { NextResponse } from "next/server"
|
|
@@ -332,12 +332,12 @@ export const config = {
|
|
|
332
332
|
|
|
333
333
|
---
|
|
334
334
|
|
|
335
|
-
##
|
|
335
|
+
## Best Practices
|
|
336
336
|
|
|
337
337
|
### ✅ DO
|
|
338
338
|
|
|
339
339
|
```typescript
|
|
340
|
-
// 1.
|
|
340
|
+
// 1. Keep logic lightweight
|
|
341
341
|
export function middleware(request: NextRequest) {
|
|
342
342
|
const token = request.cookies.get("token")
|
|
343
343
|
|
|
@@ -348,7 +348,7 @@ export function middleware(request: NextRequest) {
|
|
|
348
348
|
return NextResponse.next()
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
// 2. matcher
|
|
351
|
+
// 2. Configure matcher
|
|
352
352
|
export const config = {
|
|
353
353
|
matcher: ["/dashboard/:path*"],
|
|
354
354
|
}
|
|
@@ -357,23 +357,23 @@ export const config = {
|
|
|
357
357
|
### ❌ DON'T
|
|
358
358
|
|
|
359
359
|
```typescript
|
|
360
|
-
// 1.
|
|
360
|
+
// 1. Heavy database queries
|
|
361
361
|
export async function middleware(request: NextRequest) {
|
|
362
|
-
// ❌
|
|
362
|
+
// ❌ No DB queries in middleware
|
|
363
363
|
const user = await prisma.user.findUnique({ where: { id: "..." } })
|
|
364
364
|
return NextResponse.next()
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
// 2.
|
|
367
|
+
// 2. Processing all requests without matcher
|
|
368
368
|
export function middleware(request: NextRequest) {
|
|
369
|
-
// ❌
|
|
369
|
+
// ❌ Performance degradation
|
|
370
370
|
return NextResponse.next()
|
|
371
371
|
}
|
|
372
372
|
```
|
|
373
373
|
|
|
374
374
|
---
|
|
375
375
|
|
|
376
|
-
## NextAuth.js
|
|
376
|
+
## Using with NextAuth.js
|
|
377
377
|
|
|
378
378
|
```typescript
|
|
379
379
|
// middleware.ts
|
|
@@ -386,6 +386,6 @@ export const config = {
|
|
|
386
386
|
|
|
387
387
|
---
|
|
388
388
|
|
|
389
|
-
##
|
|
389
|
+
## References
|
|
390
390
|
|
|
391
391
|
- [Next.js Middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Route Handlers
|
|
2
2
|
|
|
3
|
-
> REST API
|
|
3
|
+
> REST API endpoints (`app/api/`)
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Basic Usage
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
10
|
// app/api/posts/route.ts
|
|
@@ -24,7 +24,7 @@ export async function POST(request: NextRequest) {
|
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
## HTTP
|
|
27
|
+
## HTTP Methods
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
30
|
// app/api/posts/route.ts
|
|
@@ -39,7 +39,7 @@ export async function OPTIONS(request: NextRequest) {}
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
##
|
|
42
|
+
## Dynamic Routes
|
|
43
43
|
|
|
44
44
|
```typescript
|
|
45
45
|
// app/api/posts/[id]/route.ts
|
|
@@ -67,7 +67,7 @@ export async function DELETE(
|
|
|
67
67
|
|
|
68
68
|
---
|
|
69
69
|
|
|
70
|
-
## Request
|
|
70
|
+
## Request Processing
|
|
71
71
|
|
|
72
72
|
### Query Parameters
|
|
73
73
|
|
|
@@ -112,7 +112,7 @@ export async function POST(request: NextRequest) {
|
|
|
112
112
|
const title = formData.get("title") as string
|
|
113
113
|
const file = formData.get("file") as File
|
|
114
114
|
|
|
115
|
-
//
|
|
115
|
+
// File processing...
|
|
116
116
|
|
|
117
117
|
return NextResponse.json({ success: true })
|
|
118
118
|
}
|
|
@@ -125,7 +125,7 @@ export async function GET(request: NextRequest) {
|
|
|
125
125
|
const token = request.headers.get("authorization")
|
|
126
126
|
const userAgent = request.headers.get("user-agent")
|
|
127
127
|
|
|
128
|
-
//
|
|
128
|
+
// Use headers...
|
|
129
129
|
|
|
130
130
|
return NextResponse.json({ data: "..." })
|
|
131
131
|
}
|
|
@@ -133,7 +133,7 @@ export async function GET(request: NextRequest) {
|
|
|
133
133
|
|
|
134
134
|
---
|
|
135
135
|
|
|
136
|
-
## Response
|
|
136
|
+
## Response Processing
|
|
137
137
|
|
|
138
138
|
### JSON Response
|
|
139
139
|
|
|
@@ -178,14 +178,14 @@ import { cookies } from "next/headers"
|
|
|
178
178
|
export async function GET() {
|
|
179
179
|
const cookieStore = cookies()
|
|
180
180
|
|
|
181
|
-
//
|
|
181
|
+
// Read cookie
|
|
182
182
|
const token = cookieStore.get("token")
|
|
183
183
|
|
|
184
|
-
//
|
|
184
|
+
// Set cookie
|
|
185
185
|
cookieStore.set("token", "value", {
|
|
186
186
|
httpOnly: true,
|
|
187
187
|
secure: true,
|
|
188
|
-
maxAge: 60 * 60 * 24 * 7, // 7
|
|
188
|
+
maxAge: 60 * 60 * 24 * 7, // 7 days
|
|
189
189
|
})
|
|
190
190
|
|
|
191
191
|
return NextResponse.json({ success: true })
|
|
@@ -194,7 +194,7 @@ export async function GET() {
|
|
|
194
194
|
|
|
195
195
|
---
|
|
196
196
|
|
|
197
|
-
## Zod
|
|
197
|
+
## Zod Validation
|
|
198
198
|
|
|
199
199
|
```typescript
|
|
200
200
|
import { z } from "zod"
|
|
@@ -229,7 +229,7 @@ export async function POST(request: NextRequest) {
|
|
|
229
229
|
|
|
230
230
|
---
|
|
231
231
|
|
|
232
|
-
##
|
|
232
|
+
## Authentication
|
|
233
233
|
|
|
234
234
|
```typescript
|
|
235
235
|
import { auth } from "@/lib/auth"
|
|
@@ -286,7 +286,7 @@ export async function OPTIONS() {
|
|
|
286
286
|
|
|
287
287
|
---
|
|
288
288
|
|
|
289
|
-
##
|
|
289
|
+
## Streaming
|
|
290
290
|
|
|
291
291
|
```typescript
|
|
292
292
|
export async function GET() {
|
|
@@ -314,7 +314,7 @@ export async function GET() {
|
|
|
314
314
|
|
|
315
315
|
---
|
|
316
316
|
|
|
317
|
-
##
|
|
317
|
+
## Error Handling
|
|
318
318
|
|
|
319
319
|
```typescript
|
|
320
320
|
export async function GET(
|
|
@@ -341,17 +341,17 @@ export async function GET(
|
|
|
341
341
|
|
|
342
342
|
---
|
|
343
343
|
|
|
344
|
-
##
|
|
344
|
+
## Caching
|
|
345
345
|
|
|
346
346
|
```typescript
|
|
347
|
-
//
|
|
347
|
+
// Static response (generated at build time)
|
|
348
348
|
export const dynamic = "force-static"
|
|
349
349
|
|
|
350
|
-
//
|
|
350
|
+
// Dynamic response (every request)
|
|
351
351
|
export const dynamic = "force-dynamic"
|
|
352
352
|
|
|
353
|
-
// Revalidate (n
|
|
354
|
-
export const revalidate = 60 // 60
|
|
353
|
+
// Revalidate (regenerate every n seconds)
|
|
354
|
+
export const revalidate = 60 // 60 seconds
|
|
355
355
|
|
|
356
356
|
export async function GET() {
|
|
357
357
|
const posts = await prisma.post.findMany()
|
|
@@ -363,20 +363,20 @@ export async function GET() {
|
|
|
363
363
|
|
|
364
364
|
## Server Actions vs Route Handlers
|
|
365
365
|
|
|
366
|
-
|
|
|
367
|
-
|
|
368
|
-
|
|
|
369
|
-
|
|
|
370
|
-
|
|
|
371
|
-
|
|
|
372
|
-
|
|
|
366
|
+
| Criteria | Server Actions | Route Handlers |
|
|
367
|
+
|----------|----------------|----------------|
|
|
368
|
+
| **Purpose** | Form submissions, mutations | REST API, external integration |
|
|
369
|
+
| **Types** | ✅ Automatic type inference | ❌ Manual type definition |
|
|
370
|
+
| **Caching** | revalidatePath | export const revalidate |
|
|
371
|
+
| **Auth** | await auth() | await auth() |
|
|
372
|
+
| **Recommended** | Internal API | External API, webhooks |
|
|
373
373
|
|
|
374
|
-
|
|
375
|
-
-
|
|
376
|
-
-
|
|
374
|
+
**Recommendation:**
|
|
375
|
+
- Internal API → Server Actions
|
|
376
|
+
- External API, webhooks, third-party integration → Route Handlers
|
|
377
377
|
|
|
378
378
|
---
|
|
379
379
|
|
|
380
|
-
##
|
|
380
|
+
## References
|
|
381
381
|
|
|
382
382
|
- [Next.js Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)
|