@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,342 @@
|
|
|
1
|
+
# Routes
|
|
2
|
+
|
|
3
|
+
> Next.js App Router routing patterns
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Basic Routing
|
|
8
|
+
|
|
9
|
+
| File | Route |
|
|
10
|
+
|------|-------|
|
|
11
|
+
| `app/page.tsx` | `/` |
|
|
12
|
+
| `app/about/page.tsx` | `/about` |
|
|
13
|
+
| `app/blog/page.tsx` | `/blog` |
|
|
14
|
+
| `app/blog/[slug]/page.tsx` | `/blog/:slug` |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Dynamic Routes
|
|
19
|
+
|
|
20
|
+
### Single Parameter
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// app/posts/[id]/page.tsx
|
|
24
|
+
interface PageProps {
|
|
25
|
+
params: { id: string }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default async function PostPage({ params }: PageProps) {
|
|
29
|
+
const post = await prisma.post.findUnique({ where: { id: params.id } })
|
|
30
|
+
|
|
31
|
+
if (!post) notFound()
|
|
32
|
+
|
|
33
|
+
return <article>{post.title}</article>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Static generation
|
|
37
|
+
export async function generateStaticParams() {
|
|
38
|
+
const posts = await prisma.post.findMany({ select: { id: true } })
|
|
39
|
+
return posts.map(post => ({ id: post.id }))
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Catch-all
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// app/docs/[...slug]/page.tsx
|
|
47
|
+
interface PageProps {
|
|
48
|
+
params: { slug: string[] }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default function DocsPage({ params }: PageProps) {
|
|
52
|
+
// /docs/a/b/c → params.slug = ["a", "b", "c"]
|
|
53
|
+
const path = params.slug.join("/")
|
|
54
|
+
return <div>{path}</div>
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Layouts
|
|
61
|
+
|
|
62
|
+
### Root Layout (required)
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// app/layout.tsx
|
|
66
|
+
import { Providers } from "./providers"
|
|
67
|
+
|
|
68
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
69
|
+
return (
|
|
70
|
+
<html lang="en">
|
|
71
|
+
<body>
|
|
72
|
+
<Providers>{children}</Providers>
|
|
73
|
+
</body>
|
|
74
|
+
</html>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Nested Layout
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// app/dashboard/layout.tsx
|
|
83
|
+
import { auth } from "@/lib/auth"
|
|
84
|
+
import { headers } from "next/headers"
|
|
85
|
+
import { redirect } from "next/navigation"
|
|
86
|
+
|
|
87
|
+
export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
|
|
88
|
+
// Auth check
|
|
89
|
+
const session = await auth.api.getSession({ headers: headers() })
|
|
90
|
+
if (!session?.user) redirect("/login")
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<div>
|
|
94
|
+
<nav>Dashboard Nav</nav>
|
|
95
|
+
<main>{children}</main>
|
|
96
|
+
</div>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Route Groups
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
app/
|
|
107
|
+
├── (marketing)/
|
|
108
|
+
│ ├── layout.tsx # Marketing layout
|
|
109
|
+
│ ├── page.tsx # /
|
|
110
|
+
│ └── about/
|
|
111
|
+
│ └── page.tsx # /about
|
|
112
|
+
└── (shop)/
|
|
113
|
+
├── layout.tsx # Shop layout
|
|
114
|
+
└── products/
|
|
115
|
+
└── page.tsx # /products
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Purpose:** Apply different layouts without affecting URLs
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Loading & Error
|
|
123
|
+
|
|
124
|
+
### Loading UI
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// app/posts/loading.tsx
|
|
128
|
+
export default function Loading() {
|
|
129
|
+
return <div>Loading posts...</div>
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Error UI
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// app/posts/error.tsx
|
|
137
|
+
"use client"
|
|
138
|
+
|
|
139
|
+
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
|
|
140
|
+
return (
|
|
141
|
+
<div>
|
|
142
|
+
<h2>Error: {error.message}</h2>
|
|
143
|
+
<button onClick={reset}>Try again</button>
|
|
144
|
+
</div>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Not Found
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
// app/posts/[id]/not-found.tsx
|
|
153
|
+
export default function NotFound() {
|
|
154
|
+
return <div>Post not found</div>
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Metadata
|
|
161
|
+
|
|
162
|
+
### Static
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// app/about/page.tsx
|
|
166
|
+
import type { Metadata } from "next"
|
|
167
|
+
|
|
168
|
+
export const metadata: Metadata = {
|
|
169
|
+
title: "About Us",
|
|
170
|
+
description: "Learn more about our company",
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export default function AboutPage() {
|
|
174
|
+
return <div>About</div>
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Dynamic
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// app/posts/[id]/page.tsx
|
|
182
|
+
import type { Metadata } from "next"
|
|
183
|
+
|
|
184
|
+
export async function generateMetadata({ params }: { params: { id: string } }): Promise<Metadata> {
|
|
185
|
+
const post = await prisma.post.findUnique({ where: { id: params.id } })
|
|
186
|
+
|
|
187
|
+
if (!post) {
|
|
188
|
+
return {
|
|
189
|
+
title: "Post Not Found",
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
title: post.title,
|
|
195
|
+
description: post.excerpt,
|
|
196
|
+
openGraph: {
|
|
197
|
+
title: post.title,
|
|
198
|
+
description: post.excerpt,
|
|
199
|
+
images: [post.image],
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Navigation
|
|
208
|
+
|
|
209
|
+
### Link
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import Link from "next/link"
|
|
213
|
+
|
|
214
|
+
export function Navigation() {
|
|
215
|
+
return (
|
|
216
|
+
<nav>
|
|
217
|
+
<Link href="/">Home</Link>
|
|
218
|
+
<Link href="/about">About</Link>
|
|
219
|
+
<Link href="/posts">Posts</Link>
|
|
220
|
+
</nav>
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### useRouter
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
"use client"
|
|
229
|
+
|
|
230
|
+
import { useRouter } from "next/navigation"
|
|
231
|
+
|
|
232
|
+
export function LoginButton() {
|
|
233
|
+
const router = useRouter()
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
<button onClick={() => router.push("/login")}>
|
|
237
|
+
Login
|
|
238
|
+
</button>
|
|
239
|
+
)
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Auth Protection
|
|
246
|
+
|
|
247
|
+
### Check in Layout
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
// app/dashboard/layout.tsx
|
|
251
|
+
import { auth } from "@/lib/auth"
|
|
252
|
+
import { headers } from "next/headers"
|
|
253
|
+
import { redirect } from "next/navigation"
|
|
254
|
+
|
|
255
|
+
export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
|
|
256
|
+
const session = await auth.api.getSession({ headers: headers() })
|
|
257
|
+
|
|
258
|
+
if (!session?.user) {
|
|
259
|
+
redirect("/login")
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return <div>{children}</div>
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Check in Middleware
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
// middleware.ts
|
|
270
|
+
import { auth } from "@/lib/auth"
|
|
271
|
+
import { NextResponse } from "next/server"
|
|
272
|
+
import type { NextRequest } from "next/server"
|
|
273
|
+
|
|
274
|
+
export async function middleware(request: NextRequest) {
|
|
275
|
+
const session = await auth.api.getSession({ headers: request.headers })
|
|
276
|
+
|
|
277
|
+
if (!session?.user) {
|
|
278
|
+
return NextResponse.redirect(new URL("/login", request.url))
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return NextResponse.next()
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export const config = {
|
|
285
|
+
matcher: ["/dashboard/:path*", "/profile/:path*"],
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Best Practices
|
|
292
|
+
|
|
293
|
+
### ✅ DO
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// 1. Direct data fetching in Server Components
|
|
297
|
+
export default async function PostsPage() {
|
|
298
|
+
const posts = await prisma.post.findMany()
|
|
299
|
+
return <PostsList posts={posts} />
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// 2. Auth check in layout
|
|
303
|
+
export default async function DashboardLayout({ children }) {
|
|
304
|
+
const session = await auth.api.getSession({ headers: headers() })
|
|
305
|
+
if (!session?.user) redirect("/login")
|
|
306
|
+
return <div>{children}</div>
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// 3. Static generation with generateStaticParams
|
|
310
|
+
export async function generateStaticParams() {
|
|
311
|
+
const posts = await prisma.post.findMany({ select: { id: true } })
|
|
312
|
+
return posts.map(post => ({ id: post.id }))
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### ❌ DON'T
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// 1. async/await in Client Components
|
|
320
|
+
"use client"
|
|
321
|
+
export default async function PostsPage() { // ❌
|
|
322
|
+
const posts = await prisma.post.findMany()
|
|
323
|
+
return <PostsList posts={posts} />
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// 2. Repeated auth checks per page
|
|
327
|
+
export default async function Page1() {
|
|
328
|
+
const session = await auth.api.getSession({ headers: headers() }) // ❌ Duplicate
|
|
329
|
+
if (!session) redirect("/login")
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// 3. Hardcoded paths
|
|
333
|
+
<Link href="/posts/123">Post</Link> // ❌ Hardcoded
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## References
|
|
339
|
+
|
|
340
|
+
- [App Router](../library/nextjs/app-router.md)
|
|
341
|
+
- [Server Actions](server-actions.md)
|
|
342
|
+
- [Client Components](client-components.md)
|