@kood/claude-code 0.3.6 → 0.3.8
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 +124 -124
- package/templates/.claude/agents/dependency-manager.md +85 -85
- package/templates/.claude/agents/deployment-validator.md +56 -56
- package/templates/.claude/agents/git-operator.md +64 -64
- package/templates/.claude/agents/implementation-executor.md +95 -95
- package/templates/.claude/agents/ko-to-en-translator.md +74 -0
- package/templates/.claude/agents/lint-fixer.md +78 -78
- package/templates/.claude/agents/refactor-advisor.md +122 -122
- package/templates/.claude/commands/agent-creator.md +185 -185
- package/templates/.claude/commands/bug-fix.md +193 -193
- package/templates/.claude/commands/command-creator.md +54 -54
- package/templates/.claude/commands/docs-creator.md +57 -57
- package/templates/.claude/commands/docs-refactor.md +26 -26
- package/templates/.claude/commands/execute.md +12 -12
- package/templates/.claude/commands/git-all.md +32 -32
- package/templates/.claude/commands/git-session.md +42 -42
- package/templates/.claude/commands/git.md +34 -34
- package/templates/.claude/commands/lint-fix.md +138 -138
- package/templates/.claude/commands/lint-init.md +61 -61
- package/templates/.claude/commands/plan.md +260 -260
- package/templates/.claude/commands/prd.md +24 -24
- package/templates/.claude/commands/pre-deploy.md +109 -109
- package/templates/.claude/commands/refactor.md +147 -147
- package/templates/.claude/commands/version-update.md +17 -17
- package/templates/hono/CLAUDE.md +27 -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 +228 -0
- package/templates/nextjs/docs/design.md +558 -0
- package/templates/nextjs/docs/guides/conventions.md +343 -0
- package/templates/nextjs/docs/guides/getting-started.md +367 -0
- package/templates/nextjs/docs/guides/routes.md +342 -0
- package/templates/nextjs/docs/library/better-auth/index.md +541 -0
- package/templates/nextjs/docs/library/nextjs/app-router.md +269 -0
- package/templates/nextjs/docs/library/nextjs/caching.md +351 -0
- package/templates/nextjs/docs/library/nextjs/index.md +291 -0
- package/templates/nextjs/docs/library/nextjs/middleware.md +391 -0
- package/templates/nextjs/docs/library/nextjs/route-handlers.md +382 -0
- package/templates/nextjs/docs/library/nextjs/server-actions.md +366 -0
- package/templates/nextjs/docs/library/prisma/cloudflare-d1.md +76 -0
- package/templates/nextjs/docs/library/prisma/config.md +77 -0
- package/templates/nextjs/docs/library/prisma/crud.md +90 -0
- package/templates/nextjs/docs/library/prisma/index.md +73 -0
- package/templates/nextjs/docs/library/prisma/relations.md +69 -0
- package/templates/nextjs/docs/library/prisma/schema.md +98 -0
- package/templates/nextjs/docs/library/prisma/setup.md +49 -0
- package/templates/nextjs/docs/library/prisma/transactions.md +50 -0
- package/templates/nextjs/docs/library/tanstack-query/index.md +66 -0
- package/templates/nextjs/docs/library/tanstack-query/invalidation.md +54 -0
- package/templates/nextjs/docs/library/tanstack-query/optimistic-updates.md +77 -0
- package/templates/nextjs/docs/library/tanstack-query/use-mutation.md +63 -0
- package/templates/nextjs/docs/library/tanstack-query/use-query.md +70 -0
- package/templates/nextjs/docs/library/zod/complex-types.md +61 -0
- package/templates/nextjs/docs/library/zod/index.md +56 -0
- package/templates/nextjs/docs/library/zod/transforms.md +51 -0
- package/templates/nextjs/docs/library/zod/validation.md +70 -0
- package/templates/npx/CLAUDE.md +37 -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 +53 -49
- 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 +63 -35
- package/templates/tanstack-start/docs/guides/routes.md +61 -42
- 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
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# Route Handlers
|
|
2
|
+
|
|
3
|
+
> REST API endpoints (`app/api/`)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Basic Usage
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// app/api/posts/route.ts
|
|
11
|
+
import { NextRequest, NextResponse } from "next/server"
|
|
12
|
+
|
|
13
|
+
export async function GET(request: NextRequest) {
|
|
14
|
+
const posts = await prisma.post.findMany()
|
|
15
|
+
return NextResponse.json(posts)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function POST(request: NextRequest) {
|
|
19
|
+
const body = await request.json()
|
|
20
|
+
const post = await prisma.post.create({ data: body })
|
|
21
|
+
return NextResponse.json(post, { status: 201 })
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## HTTP Methods
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// app/api/posts/route.ts
|
|
31
|
+
export async function GET(request: NextRequest) {}
|
|
32
|
+
export async function POST(request: NextRequest) {}
|
|
33
|
+
export async function PUT(request: NextRequest) {}
|
|
34
|
+
export async function PATCH(request: NextRequest) {}
|
|
35
|
+
export async function DELETE(request: NextRequest) {}
|
|
36
|
+
export async function HEAD(request: NextRequest) {}
|
|
37
|
+
export async function OPTIONS(request: NextRequest) {}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Dynamic Routes
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// app/api/posts/[id]/route.ts
|
|
46
|
+
export async function GET(
|
|
47
|
+
request: NextRequest,
|
|
48
|
+
{ params }: { params: { id: string } }
|
|
49
|
+
) {
|
|
50
|
+
const post = await prisma.post.findUnique({ where: { id: params.id } })
|
|
51
|
+
|
|
52
|
+
if (!post) {
|
|
53
|
+
return NextResponse.json({ error: "Not found" }, { status: 404 })
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return NextResponse.json(post)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function DELETE(
|
|
60
|
+
request: NextRequest,
|
|
61
|
+
{ params }: { params: { id: string } }
|
|
62
|
+
) {
|
|
63
|
+
await prisma.post.delete({ where: { id: params.id } })
|
|
64
|
+
return NextResponse.json({ success: true })
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Request Processing
|
|
71
|
+
|
|
72
|
+
### Query Parameters
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// GET /api/posts?page=1&limit=10
|
|
76
|
+
export async function GET(request: NextRequest) {
|
|
77
|
+
const searchParams = request.nextUrl.searchParams
|
|
78
|
+
const page = Number(searchParams.get("page") || 1)
|
|
79
|
+
const limit = Number(searchParams.get("limit") || 10)
|
|
80
|
+
|
|
81
|
+
const posts = await prisma.post.findMany({
|
|
82
|
+
skip: (page - 1) * limit,
|
|
83
|
+
take: limit,
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
return NextResponse.json(posts)
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### JSON Body
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
export async function POST(request: NextRequest) {
|
|
94
|
+
const body = await request.json()
|
|
95
|
+
|
|
96
|
+
const post = await prisma.post.create({
|
|
97
|
+
data: {
|
|
98
|
+
title: body.title,
|
|
99
|
+
content: body.content,
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
return NextResponse.json(post, { status: 201 })
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### FormData
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
export async function POST(request: NextRequest) {
|
|
111
|
+
const formData = await request.formData()
|
|
112
|
+
const title = formData.get("title") as string
|
|
113
|
+
const file = formData.get("file") as File
|
|
114
|
+
|
|
115
|
+
// File processing...
|
|
116
|
+
|
|
117
|
+
return NextResponse.json({ success: true })
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Headers
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
export async function GET(request: NextRequest) {
|
|
125
|
+
const token = request.headers.get("authorization")
|
|
126
|
+
const userAgent = request.headers.get("user-agent")
|
|
127
|
+
|
|
128
|
+
// Use headers...
|
|
129
|
+
|
|
130
|
+
return NextResponse.json({ data: "..." })
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Response Processing
|
|
137
|
+
|
|
138
|
+
### JSON Response
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
export async function GET() {
|
|
142
|
+
return NextResponse.json({ message: "Hello" }, { status: 200 })
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Response Headers
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
export async function GET() {
|
|
150
|
+
return NextResponse.json(
|
|
151
|
+
{ data: "..." },
|
|
152
|
+
{
|
|
153
|
+
status: 200,
|
|
154
|
+
headers: {
|
|
155
|
+
"Content-Type": "application/json",
|
|
156
|
+
"Cache-Control": "max-age=3600",
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Redirect
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { redirect } from "next/navigation"
|
|
167
|
+
|
|
168
|
+
export async function GET() {
|
|
169
|
+
redirect("https://example.com")
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Cookies
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { cookies } from "next/headers"
|
|
177
|
+
|
|
178
|
+
export async function GET() {
|
|
179
|
+
const cookieStore = cookies()
|
|
180
|
+
|
|
181
|
+
// Read cookie
|
|
182
|
+
const token = cookieStore.get("token")
|
|
183
|
+
|
|
184
|
+
// Set cookie
|
|
185
|
+
cookieStore.set("token", "value", {
|
|
186
|
+
httpOnly: true,
|
|
187
|
+
secure: true,
|
|
188
|
+
maxAge: 60 * 60 * 24 * 7, // 7 days
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
return NextResponse.json({ success: true })
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Zod Validation
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { z } from "zod"
|
|
201
|
+
import { NextRequest, NextResponse } from "next/server"
|
|
202
|
+
|
|
203
|
+
const createPostSchema = z.object({
|
|
204
|
+
title: z.string().min(1).max(100),
|
|
205
|
+
content: z.string().min(1),
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
export async function POST(request: NextRequest) {
|
|
209
|
+
try {
|
|
210
|
+
const body = await request.json()
|
|
211
|
+
const parsed = createPostSchema.parse(body)
|
|
212
|
+
|
|
213
|
+
const post = await prisma.post.create({ data: parsed })
|
|
214
|
+
return NextResponse.json(post, { status: 201 })
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (error instanceof z.ZodError) {
|
|
217
|
+
return NextResponse.json(
|
|
218
|
+
{ errors: error.errors },
|
|
219
|
+
{ status: 400 }
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
return NextResponse.json(
|
|
223
|
+
{ error: "Internal Server Error" },
|
|
224
|
+
{ status: 500 }
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Authentication
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { auth } from "@/lib/auth"
|
|
236
|
+
|
|
237
|
+
export async function DELETE(
|
|
238
|
+
request: NextRequest,
|
|
239
|
+
{ params }: { params: { id: string } }
|
|
240
|
+
) {
|
|
241
|
+
const session = await auth()
|
|
242
|
+
|
|
243
|
+
if (!session?.user) {
|
|
244
|
+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
await prisma.post.delete({
|
|
248
|
+
where: {
|
|
249
|
+
id: params.id,
|
|
250
|
+
userId: session.user.id,
|
|
251
|
+
},
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
return NextResponse.json({ success: true })
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## CORS
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
export async function GET(request: NextRequest) {
|
|
264
|
+
const data = await fetchData()
|
|
265
|
+
|
|
266
|
+
return NextResponse.json(data, {
|
|
267
|
+
headers: {
|
|
268
|
+
"Access-Control-Allow-Origin": "*",
|
|
269
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
270
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
271
|
+
},
|
|
272
|
+
})
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export async function OPTIONS() {
|
|
276
|
+
return new NextResponse(null, {
|
|
277
|
+
status: 204,
|
|
278
|
+
headers: {
|
|
279
|
+
"Access-Control-Allow-Origin": "*",
|
|
280
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
281
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
282
|
+
},
|
|
283
|
+
})
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Streaming
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
export async function GET() {
|
|
293
|
+
const encoder = new TextEncoder()
|
|
294
|
+
|
|
295
|
+
const stream = new ReadableStream({
|
|
296
|
+
async start(controller) {
|
|
297
|
+
for (let i = 0; i < 10; i++) {
|
|
298
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
299
|
+
controller.enqueue(encoder.encode(`data: ${i}\n\n`))
|
|
300
|
+
}
|
|
301
|
+
controller.close()
|
|
302
|
+
},
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
return new Response(stream, {
|
|
306
|
+
headers: {
|
|
307
|
+
"Content-Type": "text/event-stream",
|
|
308
|
+
"Cache-Control": "no-cache",
|
|
309
|
+
"Connection": "keep-alive",
|
|
310
|
+
},
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Error Handling
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
export async function GET(
|
|
321
|
+
request: NextRequest,
|
|
322
|
+
{ params }: { params: { id: string } }
|
|
323
|
+
) {
|
|
324
|
+
try {
|
|
325
|
+
const post = await prisma.post.findUnique({ where: { id: params.id } })
|
|
326
|
+
|
|
327
|
+
if (!post) {
|
|
328
|
+
return NextResponse.json({ error: "Not found" }, { status: 404 })
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return NextResponse.json(post)
|
|
332
|
+
} catch (error) {
|
|
333
|
+
console.error("Error fetching post:", error)
|
|
334
|
+
return NextResponse.json(
|
|
335
|
+
{ error: "Internal Server Error" },
|
|
336
|
+
{ status: 500 }
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Caching
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
// Static response (generated at build time)
|
|
348
|
+
export const dynamic = "force-static"
|
|
349
|
+
|
|
350
|
+
// Dynamic response (every request)
|
|
351
|
+
export const dynamic = "force-dynamic"
|
|
352
|
+
|
|
353
|
+
// Revalidate (regenerate every n seconds)
|
|
354
|
+
export const revalidate = 60 // 60 seconds
|
|
355
|
+
|
|
356
|
+
export async function GET() {
|
|
357
|
+
const posts = await prisma.post.findMany()
|
|
358
|
+
return NextResponse.json(posts)
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Server Actions vs Route Handlers
|
|
365
|
+
|
|
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
|
+
|
|
374
|
+
**Recommendation:**
|
|
375
|
+
- Internal API → Server Actions
|
|
376
|
+
- External API, webhooks, third-party integration → Route Handlers
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## References
|
|
381
|
+
|
|
382
|
+
- [Next.js Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)
|