@kood/claude-code 0.1.6 → 0.1.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.
Files changed (107) hide show
  1. package/dist/index.js +109 -216
  2. package/package.json +8 -2
  3. package/templates/hono/CLAUDE.md +59 -328
  4. package/templates/hono/docs/architecture/architecture.md +93 -747
  5. package/templates/hono/docs/deployment/cloudflare.md +59 -513
  6. package/templates/hono/docs/deployment/docker.md +41 -356
  7. package/templates/hono/docs/deployment/index.md +54 -190
  8. package/templates/hono/docs/deployment/railway.md +36 -306
  9. package/templates/hono/docs/deployment/vercel.md +49 -434
  10. package/templates/hono/docs/library/ai-sdk/index.md +53 -290
  11. package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
  12. package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
  13. package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
  14. package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
  15. package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
  16. package/templates/hono/docs/library/hono/env-setup.md +24 -313
  17. package/templates/hono/docs/library/hono/error-handling.md +34 -295
  18. package/templates/hono/docs/library/hono/index.md +29 -121
  19. package/templates/hono/docs/library/hono/middleware.md +21 -188
  20. package/templates/hono/docs/library/hono/rpc.md +40 -341
  21. package/templates/hono/docs/library/hono/validation.md +35 -195
  22. package/templates/hono/docs/library/pino/index.md +42 -333
  23. package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
  24. package/templates/hono/docs/library/prisma/config.md +19 -260
  25. package/templates/hono/docs/library/prisma/index.md +67 -320
  26. package/templates/hono/docs/library/zod/index.md +53 -257
  27. package/templates/npx/CLAUDE.md +62 -274
  28. package/templates/npx/docs/references/patterns.md +160 -0
  29. package/templates/tanstack-start/CLAUDE.md +100 -256
  30. package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
  31. package/templates/tanstack-start/docs/deployment/cloudflare.md +37 -424
  32. package/templates/tanstack-start/docs/deployment/index.md +57 -286
  33. package/templates/tanstack-start/docs/deployment/nitro.md +36 -318
  34. package/templates/tanstack-start/docs/deployment/railway.md +40 -409
  35. package/templates/tanstack-start/docs/deployment/vercel.md +43 -465
  36. package/templates/tanstack-start/docs/design/components.md +77 -311
  37. package/templates/tanstack-start/docs/design/index.md +113 -69
  38. package/templates/tanstack-start/docs/design/safe-area.md +51 -250
  39. package/templates/tanstack-start/docs/design/tailwind-setup.md +45 -359
  40. package/templates/tanstack-start/docs/guides/conventions.md +103 -0
  41. package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
  42. package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
  43. package/templates/tanstack-start/docs/guides/hooks.md +166 -0
  44. package/templates/tanstack-start/docs/guides/routes.md +166 -0
  45. package/templates/tanstack-start/docs/guides/services.md +143 -0
  46. package/templates/tanstack-start/docs/library/better-auth/2fa.md +27 -115
  47. package/templates/tanstack-start/docs/library/better-auth/advanced.md +22 -105
  48. package/templates/tanstack-start/docs/library/better-auth/index.md +17 -66
  49. package/templates/tanstack-start/docs/library/better-auth/plugins.md +11 -88
  50. package/templates/tanstack-start/docs/library/better-auth/session.md +12 -92
  51. package/templates/tanstack-start/docs/library/better-auth/setup.md +9 -91
  52. package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +30 -358
  53. package/templates/tanstack-start/docs/library/prisma/config.md +27 -327
  54. package/templates/tanstack-start/docs/library/prisma/crud.md +46 -174
  55. package/templates/tanstack-start/docs/library/prisma/index.md +23 -113
  56. package/templates/tanstack-start/docs/library/prisma/relations.md +31 -153
  57. package/templates/tanstack-start/docs/library/prisma/schema.md +40 -217
  58. package/templates/tanstack-start/docs/library/prisma/setup.md +12 -112
  59. package/templates/tanstack-start/docs/library/prisma/transactions.md +20 -110
  60. package/templates/tanstack-start/docs/library/tanstack-query/index.md +26 -97
  61. package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +28 -107
  62. package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +44 -146
  63. package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +33 -127
  64. package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +49 -149
  65. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +19 -112
  66. package/templates/tanstack-start/docs/library/tanstack-start/index.md +33 -80
  67. package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +28 -106
  68. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +21 -118
  69. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +34 -246
  70. package/templates/tanstack-start/docs/library/tanstack-start/setup.md +6 -39
  71. package/templates/tanstack-start/docs/library/zod/complex-types.md +32 -156
  72. package/templates/tanstack-start/docs/library/zod/index.md +31 -144
  73. package/templates/tanstack-start/docs/library/zod/transforms.md +20 -129
  74. package/templates/tanstack-start/docs/library/zod/validation.md +39 -155
  75. package/templates/hono/docs/commands/git.md +0 -145
  76. package/templates/hono/docs/mcp/context7.md +0 -106
  77. package/templates/hono/docs/mcp/index.md +0 -176
  78. package/templates/hono/docs/mcp/sequential-thinking.md +0 -101
  79. package/templates/hono/docs/mcp/serena.md +0 -269
  80. package/templates/hono/docs/mcp/sgrep.md +0 -105
  81. package/templates/hono/docs/skills/gemini-review/SKILL.md +0 -220
  82. package/templates/hono/docs/skills/gemini-review/references/checklists.md +0 -136
  83. package/templates/hono/docs/skills/gemini-review/references/prompt-templates.md +0 -303
  84. package/templates/npx/docs/commands/git.md +0 -145
  85. package/templates/npx/docs/mcp/index.md +0 -60
  86. package/templates/npx/docs/skills/gemini-review/SKILL.md +0 -220
  87. package/templates/npx/docs/skills/gemini-review/references/checklists.md +0 -134
  88. package/templates/npx/docs/skills/gemini-review/references/prompt-templates.md +0 -301
  89. package/templates/tanstack-start/docs/commands/git.md +0 -145
  90. package/templates/tanstack-start/docs/design/accessibility.md +0 -433
  91. package/templates/tanstack-start/docs/design/color.md +0 -235
  92. package/templates/tanstack-start/docs/design/spacing.md +0 -341
  93. package/templates/tanstack-start/docs/design/typography.md +0 -324
  94. package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
  95. package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
  96. package/templates/tanstack-start/docs/guides/prettier.md +0 -189
  97. package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
  98. package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -107
  99. package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -186
  100. package/templates/tanstack-start/docs/mcp/context7.md +0 -204
  101. package/templates/tanstack-start/docs/mcp/index.md +0 -177
  102. package/templates/tanstack-start/docs/mcp/sequential-thinking.md +0 -180
  103. package/templates/tanstack-start/docs/mcp/serena.md +0 -269
  104. package/templates/tanstack-start/docs/mcp/sgrep.md +0 -174
  105. package/templates/tanstack-start/docs/skills/gemini-review/SKILL.md +0 -220
  106. package/templates/tanstack-start/docs/skills/gemini-review/references/checklists.md +0 -144
  107. package/templates/tanstack-start/docs/skills/gemini-review/references/prompt-templates.md +0 -292
@@ -1,171 +1,78 @@
1
1
  # TanStack Start - 인증 패턴
2
2
 
3
- > **상위 문서**: [TanStack Start](./index.md)
4
-
5
- TanStack Start에서의 인증 구현 패턴입니다.
6
-
7
- ## 로그인
3
+ ## 기본 인증 함수
8
4
 
9
5
  ```typescript
10
- import { createServerFn } from '@tanstack/react-start'
11
- import { redirect } from '@tanstack/react-router'
12
- import bcrypt from 'bcryptjs'
13
-
6
+ // 로그인
14
7
  export const loginFn = createServerFn({ method: 'POST' })
15
8
  .inputValidator((data: { email: string; password: string }) => data)
16
9
  .handler(async ({ data }) => {
17
10
  const user = await authenticateUser(data.email, data.password)
18
-
19
- if (!user) {
20
- return { error: 'Invalid credentials' }
21
- }
11
+ if (!user) return { error: 'Invalid credentials' }
22
12
 
23
13
  const session = await useAppSession()
24
- await session.update({
25
- userId: user.id,
26
- email: user.email,
27
- })
28
-
14
+ await session.update({ userId: user.id, email: user.email })
29
15
  throw redirect({ to: '/dashboard' })
30
16
  })
31
- ```
32
17
 
33
- ## 로그아웃
34
-
35
- ```typescript
18
+ // 로그아웃
36
19
  export const logoutFn = createServerFn({ method: 'POST' })
37
20
  .handler(async () => {
38
21
  const session = await useAppSession()
39
22
  await session.clear()
40
23
  throw redirect({ to: '/' })
41
24
  })
42
- ```
43
25
 
44
- ## 현재 사용자 조회
45
-
46
- ```typescript
26
+ // 현재 사용자
47
27
  export const getCurrentUserFn = createServerFn({ method: 'GET' })
48
28
  .handler(async () => {
49
29
  const session = await useAppSession()
50
- const userId = session.data.userId
51
-
52
- if (!userId) {
53
- return null
54
- }
55
-
56
- return await getUserById(userId)
57
- })
58
- ```
59
-
60
- ## 회원가입
61
-
62
- ```typescript
63
- export const registerFn = createServerFn({ method: 'POST' })
64
- .inputValidator((data: { email: string; password: string; name: string }) => data)
65
- .handler(async ({ data }) => {
66
- const existingUser = await getUserByEmail(data.email)
67
- if (existingUser) {
68
- return { error: 'User already exists' }
69
- }
70
-
71
- const hashedPassword = await bcrypt.hash(data.password, 12)
72
-
73
- const user = await createUser({
74
- email: data.email,
75
- password: hashedPassword,
76
- name: data.name,
77
- })
78
-
79
- const session = await useAppSession()
80
- await session.update({ userId: user.id })
81
-
82
- return { success: true, user: { id: user.id, email: user.email } }
30
+ if (!session.data.userId) return null
31
+ return getUserById(session.data.userId)
83
32
  })
84
33
  ```
85
34
 
86
35
  ## 인증 미들웨어
87
36
 
88
37
  ```typescript
89
- import { createMiddleware } from '@tanstack/react-start'
90
- import { redirect } from '@tanstack/react-router'
91
-
92
38
  export const authMiddleware = createMiddleware({ type: 'function' })
93
39
  .server(async ({ next }) => {
94
40
  const session = await useAppSession()
95
-
96
- if (!session.data.userId) {
97
- throw redirect({ to: '/login' })
98
- }
99
-
41
+ if (!session.data.userId) throw redirect({ to: '/login' })
100
42
  const user = await getUserById(session.data.userId)
101
-
102
43
  return next({ context: { user } })
103
44
  })
104
- ```
105
45
 
106
- ## 보호된 Server Function
107
-
108
- ```typescript
109
- export const getProtectedData = createServerFn({ method: 'GET' })
46
+ // 사용
47
+ export const protectedFn = createServerFn({ method: 'GET' })
110
48
  .middleware([authMiddleware])
111
- .handler(async ({ context }) => {
112
- // context.user 사용 가능
113
- return {
114
- message: `Hello, ${context.user.name}!`,
115
- data: await getPrivateData(context.user.id),
116
- }
117
- })
49
+ .handler(async ({ context }) => ({ user: context.user }))
118
50
  ```
119
51
 
120
52
  ## 보호된 라우트
121
53
 
122
54
  ```tsx
123
- // routes/dashboard.tsx
124
- import { createFileRoute, redirect } from '@tanstack/react-router'
125
-
126
55
  export const Route = createFileRoute('/dashboard')({
127
56
  beforeLoad: async () => {
128
57
  const user = await getCurrentUserFn()
129
-
130
- if (!user) {
131
- throw redirect({ to: '/login' })
132
- }
133
-
58
+ if (!user) throw redirect({ to: '/login' })
134
59
  return { user }
135
60
  },
136
- component: DashboardPage,
61
+ component: () => {
62
+ const { user } = Route.useRouteContext()
63
+ return <h1>Welcome, {user.name}!</h1>
64
+ },
137
65
  })
138
-
139
- function DashboardPage() {
140
- const { user } = Route.useRouteContext()
141
- return <h1>Welcome, {user.name}!</h1>
142
- }
143
66
  ```
144
67
 
145
68
  ## Better Auth 통합
146
69
 
147
70
  ```typescript
148
- // lib/auth.ts
149
- import { betterAuth } from 'better-auth'
150
- import { prismaAdapter } from 'better-auth/adapters/prisma'
151
- import { prisma } from './prisma'
152
-
153
71
  export const auth = betterAuth({
154
72
  database: prismaAdapter(prisma),
155
- emailAndPassword: {
156
- enabled: true,
157
- },
73
+ emailAndPassword: { enabled: true },
158
74
  })
159
75
 
160
- // Server Function에서 사용
161
- import { createServerFn } from '@tanstack/react-start'
162
- import { auth } from '@/lib/auth'
163
-
164
76
  export const getSession = createServerFn({ method: 'GET' })
165
- .handler(async ({ request }) => {
166
- const session = await auth.api.getSession({
167
- headers: request.headers,
168
- })
169
- return session
170
- })
77
+ .handler(async ({ request }) => auth.api.getSession({ headers: request.headers }))
171
78
  ```
@@ -1,33 +1,40 @@
1
1
  # TanStack Start
2
2
 
3
- > **Version**: 1.x | Full-stack React Framework
3
+ > 1.x | Full-stack React Framework
4
+
5
+ @setup.md
6
+ @server-functions.md
7
+ @middleware.md
8
+ @routing.md
9
+ @auth-patterns.md
4
10
 
5
11
  ---
6
12
 
7
13
  ## ⛔ 필수 규칙
8
14
 
9
- ```
10
- ❌ /api 라우터 사용 금지 → Server Functions 사용
11
- handler 내부 수동 검증 금지 → inputValidator 사용
12
- handler 내부 수동 인증 체크 금지 → middleware 사용
13
- POST/PUT/PATCH에는 반드시 inputValidator 추가
14
- ✅ 인증 필요 시 반드시 middleware 추가
15
- ```
15
+ | 금지 | 대신 |
16
+ |------|------|
17
+ | /api 라우터 | Server Functions |
18
+ | handler 수동 검증 | inputValidator |
19
+ | handler 수동 인증 | middleware |
20
+
21
+ ✅ POST/PUT/PATCH → inputValidator 필수
22
+ ✅ 인증 필요 → middleware 필수
16
23
 
17
24
  ---
18
25
 
19
- ## 🚀 Quick Reference (복사용)
26
+ ## Quick Reference
20
27
 
21
28
  ```typescript
22
- // ✅ Server Function (GET + 인증)
29
+ // GET + 인증
23
30
  export const getUsers = createServerFn({ method: 'GET' })
24
- .middleware([authMiddleware]) // ⭐ 인증 미들웨어
31
+ .middleware([authMiddleware])
25
32
  .handler(async () => prisma.user.findMany())
26
33
 
27
- // ✅ Server Function (POST + Validation + 인증)
34
+ // POST + Validation + 인증
28
35
  export const createUser = createServerFn({ method: 'POST' })
29
- .middleware([authMiddleware]) // ⭐ 인증 미들웨어
30
- .inputValidator(createUserSchema) // ⭐ Zod 스키마
36
+ .middleware([authMiddleware])
37
+ .inputValidator(createUserSchema)
31
38
  .handler(async ({ data }) => prisma.user.create({ data }))
32
39
 
33
40
  // Route with Loader
@@ -36,79 +43,25 @@ export const Route = createFileRoute('/users')({
36
43
  loader: async () => ({ users: await getUsers() }),
37
44
  })
38
45
 
39
- // Component에서 Loader 데이터 사용
46
+ // Loader 데이터 사용
40
47
  const UsersPage = (): JSX.Element => {
41
48
  const { users } = Route.useLoaderData()
42
49
  return <div>{/* render */}</div>
43
50
  }
44
51
  ```
45
52
 
46
- ### 라우트 파일 구조
47
-
48
- ```
49
- routes/
50
- ├── __root.tsx # Root layout
51
- ├── index.tsx # /
52
- ├── about.tsx # /about
53
- └── users/
54
- ├── index.tsx # /users
55
- ├── $id.tsx # /users/:id
56
- ├── -components/ # 페이지 전용 컴포넌트
57
- └── -functions/ # 페이지 전용 Server Functions ⭐
58
- ```
59
-
60
- ### Server Functions 위치
61
-
62
- ```
63
- 공통 함수 (여러 라우트) → @/functions/
64
- 라우트 전용 함수 → routes/[경로]/-functions/
65
- ```
66
-
67
- ---
68
-
69
- ## 문서 구조
70
-
71
- - [설치 및 설정](./setup.md) - 패키지 설치, Vite 설정, TypeScript 설정
72
- - [Server Functions](./server-functions.md) - 서버 함수 정의 및 사용법
73
- - [Middleware](./middleware.md) - 미들웨어 정의 및 적용
74
- - [Routing](./routing.md) - 파일 기반 라우팅, 동적 라우트, SSR
75
- - [인증 패턴](./auth-patterns.md) - 로그인, 로그아웃, 세션 관리
76
-
77
- ## 빠른 시작
78
-
79
- ```bash
80
- yarn add @tanstack/react-start @tanstack/react-router vinxi
81
- yarn add -D vite @vitejs/plugin-react vite-tsconfig-paths
82
- ```
83
-
84
- ## 핵심 개념
85
-
86
- ### Server Functions
87
- 서버에서만 실행되는 타입 안전한 함수를 정의합니다.
88
-
89
- ```typescript
90
- import { createServerFn } from '@tanstack/react-start'
91
-
92
- export const getData = createServerFn({ method: 'GET' })
93
- .handler(async () => {
94
- return { message: 'Hello from server' }
95
- })
96
- ```
97
-
98
- ### File-based Routing
99
- 파일 시스템 기반의 자동 라우팅을 지원합니다.
53
+ ### 구조
100
54
 
101
55
  ```
102
56
  routes/
103
- ├── index.tsx /
104
- ├── about.tsx /about
105
- └── users/
106
- ├── index.tsx /users
107
- └── $id.tsx /users/:id
57
+ ├── __root.tsx # Root layout
58
+ ├── index.tsx # /
59
+ ├── users/
60
+ ├── index.tsx # /users
61
+ │ ├── $id.tsx # /users/:id
62
+ │ ├── -components/ # 페이지 전용
63
+ │ └── -functions/ # 페이지 전용 Server Functions
64
+
65
+ 공통 함수 → @/functions/
66
+ 라우트 전용 → routes/[경로]/-functions/
108
67
  ```
109
-
110
- ## 참고 자료
111
-
112
- - [TanStack Start 공식 문서](https://tanstack.com/start/latest)
113
- - [TanStack Router 문서](https://tanstack.com/router/latest)
114
- - [Vinxi 문서](https://vinxi.dev)
@@ -1,142 +1,64 @@
1
1
  # TanStack Start - Middleware
2
2
 
3
- > **상위 문서**: [TanStack Start](./index.md)
3
+ Server Function 라우트에 공통 로직 적용.
4
4
 
5
- 미들웨어는 Server Function 및 라우트 핸들러에 공통 로직을 적용합니다.
6
-
7
- ## Server Function Middleware
5
+ ## 기본 패턴
8
6
 
9
7
  ```typescript
10
- import { createMiddleware, createServerFn } from '@tanstack/react-start'
11
-
12
8
  // 미들웨어 정의
13
9
  const loggingMiddleware = createMiddleware({ type: 'function' })
14
- .client(() => {
15
- console.log('Client: Server function called')
16
- })
17
10
  .server(({ next }) => {
18
- console.log('Server: Processing request')
11
+ console.log('Processing request')
19
12
  return next()
20
13
  })
21
14
 
22
- // 미들웨어 적용
15
+ // 적용
23
16
  const fn = createServerFn()
24
17
  .middleware([loggingMiddleware])
25
- .handler(async () => {
26
- return { message: 'Hello' }
27
- })
18
+ .handler(async () => ({ message: 'Hello' }))
28
19
  ```
29
20
 
30
- ## Zod Validation Middleware
21
+ ## 인증 미들웨어
31
22
 
32
23
  ```typescript
33
- import { createMiddleware } from '@tanstack/react-start'
34
- import { zodValidator } from '@tanstack/react-start/validators'
35
- import { z } from 'zod'
36
-
37
- const mySchema = z.object({
38
- workspaceId: z.string(),
39
- })
40
-
41
- const workspaceMiddleware = createMiddleware({ type: 'function' })
42
- .inputValidator(zodValidator(mySchema))
43
- .server(({ next, data }) => {
44
- console.log('Workspace ID:', data.workspaceId)
45
- return next()
24
+ const authMiddleware = createMiddleware({ type: 'function' })
25
+ .server(async ({ next }) => {
26
+ const session = await getSession()
27
+ if (!session) throw redirect({ to: '/login' })
28
+ return next({ context: { user: session.user } })
46
29
  })
47
- ```
48
30
 
49
- ## Global Request Middleware
50
-
51
- ```typescript
52
- // src/start.ts
53
- import { createStart, createMiddleware } from '@tanstack/react-start'
54
-
55
- const myGlobalMiddleware = createMiddleware().server(({ next }) => {
56
- console.log('Global middleware running')
57
- return next()
58
- })
59
-
60
- export const startInstance = createStart(() => {
61
- return {
62
- requestMiddleware: [myGlobalMiddleware],
63
- }
64
- })
31
+ // 사용
32
+ export const protectedFn = createServerFn({ method: 'GET' })
33
+ .middleware([authMiddleware])
34
+ .handler(async ({ context }) => ({ user: context.user }))
65
35
  ```
66
36
 
67
- ## Global Server Function Middleware
37
+ ## Zod Validation Middleware
68
38
 
69
39
  ```typescript
70
- // src/start.ts
71
- import { createStart } from '@tanstack/react-start'
72
- import { loggingMiddleware } from './middleware'
73
-
74
- export const startInstance = createStart(() => {
75
- return {
76
- functionMiddleware: [loggingMiddleware],
77
- }
78
- })
40
+ const workspaceMiddleware = createMiddleware({ type: 'function' })
41
+ .inputValidator(zodValidator(z.object({ workspaceId: z.string() })))
42
+ .server(({ next, data }) => next())
79
43
  ```
80
44
 
81
- ## Route-Level Middleware
45
+ ## Global Middleware
82
46
 
83
47
  ```typescript
84
- export const Route = createFileRoute('/hello')({
85
- server: {
86
- middleware: [authMiddleware, loggerMiddleware], // 모든 핸들러에 적용
87
- handlers: {
88
- GET: async ({ request }) => {
89
- return new Response('Hello, World! from ' + request.url)
90
- },
91
- POST: async ({ request }) => {
92
- const body = await request.json()
93
- return new Response(`Hello, ${body.name}!`)
94
- },
95
- },
96
- },
97
- })
48
+ // src/start.ts
49
+ export const startInstance = createStart(() => ({
50
+ requestMiddleware: [globalMiddleware], // 모든 요청
51
+ functionMiddleware: [loggingMiddleware], // 모든 Server Function
52
+ }))
98
53
  ```
99
54
 
100
- ## Handler-Specific Middleware
55
+ ## Route-Level
101
56
 
102
57
  ```typescript
103
58
  export const Route = createFileRoute('/hello')({
104
59
  server: {
105
- handlers: ({ createHandlers }) =>
106
- createHandlers({
107
- GET: {
108
- middleware: [loggerMiddleware], // GET에만 적용
109
- handler: async ({ request }) => {
110
- return new Response('Hello, World! from ' + request.url)
111
- },
112
- },
113
- }),
60
+ middleware: [authMiddleware], // 모든 핸들러
61
+ handlers: { GET: async ({ request }) => new Response('Hello') },
114
62
  },
115
63
  })
116
64
  ```
117
-
118
- ## 인증 미들웨어 예시
119
-
120
- ```typescript
121
- import { createMiddleware } from '@tanstack/react-start'
122
- import { redirect } from '@tanstack/react-router'
123
-
124
- const authMiddleware = createMiddleware({ type: 'function' })
125
- .server(async ({ next }) => {
126
- const session = await getSession()
127
-
128
- if (!session) {
129
- throw redirect({ to: '/login' })
130
- }
131
-
132
- return next({ context: { user: session.user } })
133
- })
134
-
135
- // 사용
136
- export const protectedFn = createServerFn({ method: 'GET' })
137
- .middleware([authMiddleware])
138
- .handler(async ({ context }) => {
139
- // context.user 사용 가능
140
- return { user: context.user }
141
- })
142
- ```
@@ -1,163 +1,66 @@
1
1
  # TanStack Start - Routing
2
2
 
3
- > **상위 문서**: [TanStack Start](./index.md)
3
+ 파일 기반 라우팅.
4
4
 
5
- TanStack Start는 파일 기반 라우팅을 지원합니다.
6
-
7
- ## 기본 라우트
5
+ ## 기본 패턴
8
6
 
9
7
  ```tsx
10
8
  // routes/about.tsx
11
- import { createFileRoute } from '@tanstack/react-router'
12
-
13
9
  export const Route = createFileRoute('/about')({
14
10
  component: AboutPage,
15
11
  })
16
12
 
17
- function AboutPage() {
18
- return <h1>About</h1>
19
- }
20
- ```
21
-
22
- ## Loader를 사용한 데이터 로딩
23
-
24
- ```tsx
25
- // routes/index.tsx
26
- import { createFileRoute } from '@tanstack/react-router'
27
-
13
+ // Loader
28
14
  export const Route = createFileRoute('/')({
29
15
  component: Page,
30
- loader: async () => {
31
- const res = await fetch('https://api.example.com/posts')
32
- return res.json()
33
- },
16
+ loader: async () => fetch('/api/posts').then(r => r.json()),
34
17
  })
35
18
 
36
19
  function Page() {
37
20
  const posts = Route.useLoaderData()
38
- return (
39
- <ul>
40
- {posts.map((post) => (
41
- <li key={post.id}>{post.title}</li>
42
- ))}
43
- </ul>
44
- )
21
+ return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
45
22
  }
46
- ```
47
-
48
- ## 동적 라우트
49
-
50
- ```tsx
51
- // routes/users/$id.tsx
52
- import { createFileRoute } from '@tanstack/react-router'
53
23
 
24
+ // 동적 라우트
54
25
  export const Route = createFileRoute('/users/$id')({
55
- loader: async ({ params }) => {
56
- const user = await getUserById(params.id)
57
- return { user }
58
- },
59
- component: UserDetailPage,
60
- })
61
-
62
- function UserDetailPage() {
63
- const { user } = Route.useLoaderData()
64
- return <h1>{user.name}</h1>
65
- }
66
- ```
67
-
68
- ## SSR 설정
69
-
70
- ```tsx
71
- // routes/posts/$postId.tsx
72
- export const Route = createFileRoute('/posts/$postId')({
73
- ssr: true, // SSR 활성화
74
- beforeLoad: () => {
75
- console.log('서버에서 초기 요청 시 실행')
76
- },
77
- loader: () => {
78
- console.log('서버에서 초기 요청 시 실행')
26
+ loader: async ({ params }) => ({ user: await getUserById(params.id) }),
27
+ component: () => {
28
+ const { user } = Route.useLoaderData()
29
+ return <h1>{user.name}</h1>
79
30
  },
80
- component: () => <div>서버에서 렌더링됨</div>,
81
31
  })
82
32
  ```
83
33
 
84
- ### SSR 옵션
34
+ ## SSR 옵션
85
35
 
86
36
  ```typescript
87
- // ssr: true - 전체 SSR (기본값)
88
- // ssr: false - 클라이언트 사이드만
89
- // ssr: 'data-only' - 데이터만 서버에서 로드, 렌더링은 클라이언트
37
+ ssr: true // 전체 SSR (기본값)
38
+ ssr: false // 클라이언트만
39
+ ssr: 'data-only' // 데이터만 서버, 렌더링은 클라이언트
90
40
  ```
91
41
 
92
42
  ## Server Routes (API)
93
43
 
94
- ### 기본 API 라우트
95
-
96
44
  ```typescript
97
- // routes/api/hello.ts
98
- import { createFileRoute } from '@tanstack/react-router'
99
-
100
45
  export const Route = createFileRoute('/api/hello')({
101
46
  server: {
102
47
  handlers: {
103
- GET: async ({ request }) => {
104
- return new Response('Hello, World!')
105
- },
48
+ GET: async () => new Response('Hello'),
106
49
  POST: async ({ request }) => {
107
50
  const body = await request.json()
108
- return new Response(`Hello, ${body.name}!`)
51
+ return json({ name: body.name })
109
52
  },
110
53
  },
111
54
  },
112
55
  })
113
56
  ```
114
57
 
115
- ### JSON 응답
116
-
117
- ```typescript
118
- import { createFileRoute } from '@tanstack/react-router'
119
- import { json } from '@tanstack/react-start'
120
-
121
- export const Route = createFileRoute('/api/users')({
122
- server: {
123
- handlers: {
124
- GET: async ({ request }) => {
125
- const users = await getUsers()
126
- return json({ users })
127
- },
128
- },
129
- },
130
- })
131
- ```
132
-
133
- ## 라우트 파일 구조
58
+ ## 구조
134
59
 
135
60
  ```
136
61
  routes/
137
- ├── __root.tsx → Root layout
138
- ├── index.tsx → /
139
- ├── about.tsx → /about
140
- ├── users/
141
- │ ├── index.tsx → /users
142
- │ └── $id.tsx → /users/:id
143
- ├── posts/
144
- │ ├── index.tsx → /posts
145
- │ ├── $postId.tsx → /posts/:postId
146
- │ └── new.tsx → /posts/new
147
- └── api/
148
- ├── hello.ts → /api/hello
149
- └── users.ts → /api/users
150
- ```
151
-
152
- ## Catch-All 라우트
153
-
154
- ```tsx
155
- // routes/$.tsx - 모든 매칭되지 않는 경로 처리
156
- export const Route = createFileRoute('/$')({
157
- component: NotFoundPage,
158
- })
159
-
160
- function NotFoundPage() {
161
- return <h1>404 - Page Not Found</h1>
162
- }
62
+ ├── __root.tsx → Root layout
63
+ ├── index.tsx → /
64
+ ├── users/$id.tsx → /users/:id
65
+ ├── $.tsx → Catch-all (404)
163
66
  ```