@kood/claude-code 0.6.6 → 0.7.0

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 (170) hide show
  1. package/dist/index.js +7 -1
  2. package/package.json +1 -1
  3. package/templates/.claude/agents/analyst.md +5 -0
  4. package/templates/.claude/agents/architect.md +5 -0
  5. package/templates/.claude/agents/build-fixer.md +1 -0
  6. package/templates/.claude/agents/code-reviewer.md +1 -0
  7. package/templates/.claude/agents/critic.md +4 -0
  8. package/templates/.claude/agents/deep-executor.md +1 -0
  9. package/templates/.claude/agents/dependency-manager.md +2 -0
  10. package/templates/.claude/agents/deployment-validator.md +2 -0
  11. package/templates/.claude/agents/designer.md +2 -0
  12. package/templates/.claude/agents/document-writer.md +3 -0
  13. package/templates/.claude/agents/explore.md +1 -0
  14. package/templates/.claude/agents/git-operator.md +2 -0
  15. package/templates/.claude/agents/implementation-executor.md +2 -0
  16. package/templates/.claude/agents/ko-to-en-translator.md +3 -0
  17. package/templates/.claude/agents/lint-fixer.md +2 -0
  18. package/templates/.claude/agents/planner.md +3 -0
  19. package/templates/.claude/agents/pm.md +349 -0
  20. package/templates/.claude/agents/qa-tester.md +1 -0
  21. package/templates/.claude/agents/refactor-advisor.md +4 -0
  22. package/templates/.claude/agents/researcher.md +9 -1
  23. package/templates/.claude/agents/scientist.md +1 -0
  24. package/templates/.claude/agents/security-reviewer.md +1 -0
  25. package/templates/.claude/agents/tdd-guide.md +1 -0
  26. package/templates/.claude/agents/vision.md +1 -0
  27. package/templates/.claude/instructions/agent-patterns/agent-teams-usage.md +376 -0
  28. package/templates/.claude/instructions/sourcing/reliable-search.md +49 -2
  29. package/templates/.claude/scripts/agent-teams/check-availability.sh +238 -0
  30. package/templates/.claude/scripts/agent-teams/setup-tmux.sh +125 -0
  31. package/templates/.claude/skills/agent-teams-setup/SKILL.md +460 -0
  32. package/templates/.claude/skills/brainstorm/SKILL.md +1 -0
  33. package/templates/.claude/skills/bug-fix/SKILL.md +1 -0
  34. package/templates/.claude/skills/crawler/SKILL.md +2 -0
  35. package/templates/.claude/skills/docs-creator/SKILL.md +1 -0
  36. package/templates/.claude/skills/docs-fetch/SKILL.md +6 -4
  37. package/templates/.claude/skills/docs-refactor/SKILL.md +1 -0
  38. package/templates/.claude/skills/elon-musk/SKILL.md +1 -0
  39. package/templates/.claude/skills/execute/SKILL.md +1 -0
  40. package/templates/.claude/skills/feedback/SKILL.md +1 -0
  41. package/templates/.claude/skills/figma-to-code/SKILL.md +1 -0
  42. package/templates/.claude/skills/genius-thinking/SKILL.md +1 -0
  43. package/templates/.claude/skills/global-uiux-design/SKILL.md +1 -0
  44. package/templates/.claude/skills/korea-uiux-design/SKILL.md +1 -0
  45. package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +1 -0
  46. package/templates/.claude/skills/plan/SKILL.md +1 -0
  47. package/templates/.claude/skills/prd/SKILL.md +1 -0
  48. package/templates/.claude/skills/project-optimizer/AGENTS.md +275 -0
  49. package/templates/.claude/skills/project-optimizer/SKILL.md +375 -0
  50. package/templates/.claude/skills/project-optimizer/rules/arch-config-centralize.md +66 -0
  51. package/templates/.claude/skills/project-optimizer/rules/arch-hot-path.md +35 -0
  52. package/templates/.claude/skills/project-optimizer/rules/arch-interface-segregation.md +51 -0
  53. package/templates/.claude/skills/project-optimizer/rules/arch-module-boundary.md +42 -0
  54. package/templates/.claude/skills/project-optimizer/rules/build-cache.md +57 -0
  55. package/templates/.claude/skills/project-optimizer/rules/build-code-split.md +56 -0
  56. package/templates/.claude/skills/project-optimizer/rules/build-incremental.md +65 -0
  57. package/templates/.claude/skills/project-optimizer/rules/build-minify.md +61 -0
  58. package/templates/.claude/skills/project-optimizer/rules/build-tree-shake.md +60 -0
  59. package/templates/.claude/skills/project-optimizer/rules/code-complexity.md +65 -0
  60. package/templates/.claude/skills/project-optimizer/rules/code-dead-elimination.md +32 -0
  61. package/templates/.claude/skills/project-optimizer/rules/code-duplication.md +54 -0
  62. package/templates/.claude/skills/project-optimizer/rules/code-error-handling.md +75 -0
  63. package/templates/.claude/skills/project-optimizer/rules/code-naming.md +52 -0
  64. package/templates/.claude/skills/project-optimizer/rules/concurrency-defer-await.md +54 -0
  65. package/templates/.claude/skills/project-optimizer/rules/concurrency-parallel.md +90 -0
  66. package/templates/.claude/skills/project-optimizer/rules/concurrency-pipeline.md +68 -0
  67. package/templates/.claude/skills/project-optimizer/rules/concurrency-pool.md +68 -0
  68. package/templates/.claude/skills/project-optimizer/rules/deps-lightweight-alt.md +37 -0
  69. package/templates/.claude/skills/project-optimizer/rules/deps-peer-align.md +44 -0
  70. package/templates/.claude/skills/project-optimizer/rules/deps-security-audit.md +45 -0
  71. package/templates/.claude/skills/project-optimizer/rules/deps-unused-removal.md +25 -0
  72. package/templates/.claude/skills/project-optimizer/rules/deps-version-pin.md +40 -0
  73. package/templates/.claude/skills/project-optimizer/rules/dx-ci-speed.md +47 -0
  74. package/templates/.claude/skills/project-optimizer/rules/dx-dev-server.md +35 -0
  75. package/templates/.claude/skills/project-optimizer/rules/dx-lint-config.md +36 -0
  76. package/templates/.claude/skills/project-optimizer/rules/dx-test-coverage.md +34 -0
  77. package/templates/.claude/skills/project-optimizer/rules/dx-type-safety.md +49 -0
  78. package/templates/.claude/skills/project-optimizer/rules/io-batch-queries.md +67 -0
  79. package/templates/.claude/skills/project-optimizer/rules/io-cache-layer.md +67 -0
  80. package/templates/.claude/skills/project-optimizer/rules/io-connection-reuse.md +67 -0
  81. package/templates/.claude/skills/project-optimizer/rules/io-serialize-minimal.md +61 -0
  82. package/templates/.claude/skills/project-optimizer/rules/io-stream.md +75 -0
  83. package/templates/.claude/skills/project-optimizer/rules/memory-bounded-cache.md +65 -0
  84. package/templates/.claude/skills/project-optimizer/rules/memory-large-data.md +64 -0
  85. package/templates/.claude/skills/project-optimizer/rules/memory-lazy-init.md +78 -0
  86. package/templates/.claude/skills/project-optimizer/rules/memory-leak-prevention.md +79 -0
  87. package/templates/.claude/skills/project-optimizer/rules/memory-pool-reuse.md +70 -0
  88. package/templates/.claude/skills/ralph/SKILL.md +1 -0
  89. package/templates/.claude/skills/refactor/SKILL.md +1 -0
  90. package/templates/.claude/skills/research/SKILL.md +1 -0
  91. package/templates/.claude/skills/sql-optimizer/SKILL.md +438 -0
  92. package/templates/.claude/skills/sql-optimizer/orm-patterns.md +218 -0
  93. package/templates/.claude/skills/startup-validator/SKILL.md +1 -0
  94. package/templates/.claude/skills/tanstack-start-react-best-practices/AGENTS.md +53 -14
  95. package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +94 -27
  96. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-defer-third-party.md +42 -19
  97. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-optimistic-updates.md +109 -0
  98. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-suspense-query.md +74 -0
  99. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-use-hook.md +81 -0
  100. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-react-compiler.md +81 -0
  101. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-beforeload-auth.md +121 -0
  102. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-file-conventions.md +104 -0
  103. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-link-navigation.md +119 -0
  104. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-nested-layouts.md +155 -0
  105. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-path-params.md +89 -0
  106. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-pending-component.md +110 -0
  107. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-preload-strategy.md +91 -0
  108. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-router-context.md +120 -0
  109. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-search-params.md +114 -0
  110. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-deferred-data.md +1 -1
  111. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-error-boundaries.md +79 -0
  112. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-middleware.md +85 -0
  113. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-serialization.md +56 -21
  114. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-streaming.md +84 -0
  115. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-validator.md +71 -0
  116. package/templates/.claude/skills/tauri-react-best-practices/AGENTS.md +527 -0
  117. package/templates/.claude/skills/tauri-react-best-practices/SKILL.md +571 -0
  118. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-barrel-imports.md +140 -0
  119. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-cargo-profile.md +96 -0
  120. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-frontend-treeshake.md +242 -0
  121. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-lazy-components.md +255 -0
  122. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-remove-unused-commands.md +160 -0
  123. package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-ci-pipeline.md +269 -0
  124. package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-signing.md +207 -0
  125. package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-updater.md +226 -0
  126. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-async-commands.md +172 -0
  127. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-batch-commands.md +133 -0
  128. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-binary-response.md +198 -0
  129. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-channel-streaming.md +186 -0
  130. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-error-handling.md +250 -0
  131. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-type-safe.md +227 -0
  132. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-derived-state.md +231 -0
  133. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-functional-setstate.md +191 -0
  134. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-index-maps.md +276 -0
  135. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-lazy-state-init.md +196 -0
  136. package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-lifecycle.md +265 -0
  137. package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-mobile-compat.md +199 -0
  138. package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-permission-scope.md +193 -0
  139. package/templates/.claude/skills/tauri-react-best-practices/rules/react-error-boundary.md +239 -0
  140. package/templates/.claude/skills/tauri-react-best-practices/rules/react-event-listener.md +151 -0
  141. package/templates/.claude/skills/tauri-react-best-practices/rules/react-file-src.md +155 -0
  142. package/templates/.claude/skills/tauri-react-best-practices/rules/react-invoke-hook.md +139 -0
  143. package/templates/.claude/skills/tauri-react-best-practices/rules/react-optimistic-update.md +211 -0
  144. package/templates/.claude/skills/tauri-react-best-practices/rules/security-capability-split.md +205 -0
  145. package/templates/.claude/skills/tauri-react-best-practices/rules/security-csp.md +207 -0
  146. package/templates/.claude/skills/tauri-react-best-practices/rules/security-least-privilege.md +106 -0
  147. package/templates/.claude/skills/tauri-react-best-practices/rules/security-no-wildcard.md +253 -0
  148. package/templates/.claude/skills/tauri-react-best-practices/rules/security-scope-paths.md +160 -0
  149. package/templates/.claude/skills/tauri-react-best-practices/rules/state-async-mutex.md +270 -0
  150. package/templates/.claude/skills/tauri-react-best-practices/rules/state-mutex-pattern.md +265 -0
  151. package/templates/.claude/skills/tauri-react-best-practices/rules/state-react-sync.md +375 -0
  152. package/templates/.claude/skills/tauri-react-best-practices/rules/state-single-container.md +275 -0
  153. package/templates/tanstack-start/docs/architecture.md +238 -167
  154. package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +777 -38
  155. package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +549 -37
  156. package/templates/tanstack-start/docs/library/tanstack-router/index.md +895 -111
  157. package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +641 -43
  158. package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +889 -38
  159. package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +891 -29
  160. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +972 -36
  161. package/templates/tanstack-start/docs/library/tanstack-start/index.md +1525 -881
  162. package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +1099 -20
  163. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +796 -30
  164. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +953 -35
  165. package/templates/tanstack-start/docs/library/tanstack-start/setup.md +371 -15
  166. package/templates/tauri/CLAUDE.md +189 -0
  167. package/templates/tauri/docs/guides/distribution.md +261 -0
  168. package/templates/tauri/docs/guides/getting-started.md +302 -0
  169. package/templates/tauri/docs/guides/mobile.md +288 -0
  170. package/templates/tauri/docs/library/tauri/index.md +510 -0
@@ -0,0 +1,81 @@
1
+ ---
2
+ title: Leverage React Compiler for Automatic Memoization
3
+ impact: MEDIUM
4
+ impactDescription: eliminates manual memo/useMemo/useCallback
5
+ tags: rerender, react-compiler, memoization, react-19
6
+ ---
7
+
8
+ ## React Compiler로 자동 메모이제이션
9
+
10
+ React Compiler가 활성화되어 있다면 `memo()`, `useMemo()`, `useCallback()`을 수동으로 작성할 필요가 없습니다. 컴파일러가 빌드 타임에 자동으로 최적화합니다.
11
+
12
+ **React Compiler 없을 때 (수동 메모이제이션):**
13
+
14
+ ```tsx
15
+ import { memo, useMemo, useCallback } from 'react'
16
+
17
+ const UserList = memo(function UserList({ users, onSelect }: Props) {
18
+ const sorted = useMemo(
19
+ () => users.toSorted((a, b) => a.name.localeCompare(b.name)),
20
+ [users]
21
+ )
22
+
23
+ const handleSelect = useCallback((id: string) => {
24
+ onSelect(id)
25
+ }, [onSelect])
26
+
27
+ return (
28
+ <ul>
29
+ {sorted.map(user => (
30
+ <UserItem key={user.id} user={user} onSelect={handleSelect} />
31
+ ))}
32
+ </ul>
33
+ )
34
+ })
35
+ ```
36
+
37
+ **React Compiler 있을 때 (자동 최적화):**
38
+
39
+ ```tsx
40
+ function UserList({ users, onSelect }: Props) {
41
+ const sorted = users.toSorted((a, b) => a.name.localeCompare(b.name))
42
+
43
+ const handleSelect = (id: string) => {
44
+ onSelect(id)
45
+ }
46
+
47
+ return (
48
+ <ul>
49
+ {sorted.map(user => (
50
+ <UserItem key={user.id} user={user} onSelect={handleSelect} />
51
+ ))}
52
+ </ul>
53
+ )
54
+ // Compiler가 자동으로 memo, useMemo, useCallback 삽입
55
+ }
56
+ ```
57
+
58
+ **Compiler 활성화 확인:**
59
+
60
+ ```typescript
61
+ // vite.config.ts (TanStack Start)
62
+ import { defineConfig } from '@tanstack/react-start/config'
63
+
64
+ export default defineConfig({
65
+ react: {
66
+ babel: {
67
+ plugins: [['babel-plugin-react-compiler', {}]]
68
+ }
69
+ }
70
+ })
71
+ ```
72
+
73
+ **수동 메모이제이션이 여전히 필요한 경우:**
74
+ - React Compiler가 비활성화된 프로젝트
75
+ - 써드파티 라이브러리가 `===` 참조 비교를 요구하는 경우
76
+ - Effect 의존성에 대한 정확한 제어가 필요한 경우
77
+ - 함수형 setState는 정확성(stale closure 방지)을 위해 Compiler와 무관하게 권장
78
+
79
+ **성능:** Meta 프로덕션에서 평균 12% 더 빠른 로드, 2.5배 빠른 상호작용 측정.
80
+
81
+ 참고: [React Compiler](https://react.dev/learn/react-compiler)
@@ -0,0 +1,121 @@
1
+ ---
2
+ title: Use beforeLoad for Authentication Guards
3
+ impact: HIGH
4
+ impactDescription: prevents unauthorized access before data loading
5
+ tags: routing, beforeLoad, authentication, redirect, guards
6
+ ---
7
+
8
+ ## beforeLoad로 인증 가드 구현
9
+
10
+ `beforeLoad`는 loader보다 먼저 순차 실행되며, 인증 체크/리다이렉트에 최적입니다. Pathless layout(`_prefix`)과 조합하면 하위 라우트 전체를 보호합니다.
11
+
12
+ **❌ 잘못된 예시 (loader에서 인증 체크):**
13
+
14
+ ```tsx
15
+ export const Route = createFileRoute('/dashboard')({
16
+ loader: async () => {
17
+ const user = await getSession()
18
+ if (!user) throw redirect({ to: '/login' }) // 데이터 로딩 후 체크 (늦음)
19
+ const data = await fetchDashboard(user.id)
20
+ return { data }
21
+ },
22
+ })
23
+ ```
24
+
25
+ **✅ 올바른 예시 (beforeLoad + pathless layout):**
26
+
27
+ ```tsx
28
+ // src/routes/_authenticated.tsx - 인증 가드 레이아웃
29
+ import { createFileRoute, redirect, Outlet } from '@tanstack/react-router'
30
+
31
+ export const Route = createFileRoute('/_authenticated')({
32
+ beforeLoad: async ({ location }) => {
33
+ const user = await verifySession()
34
+
35
+ if (!user) {
36
+ throw redirect({
37
+ to: '/login',
38
+ search: { redirect: location.href }, // 원래 위치 보존
39
+ })
40
+ }
41
+
42
+ return { user } // context로 하위 라우트에 전달
43
+ },
44
+ component: () => <Outlet />,
45
+ })
46
+
47
+ // src/routes/_authenticated/dashboard.tsx - 보호된 라우트
48
+ export const Route = createFileRoute('/_authenticated/dashboard')({
49
+ loader: async ({ context }) => {
50
+ // context.user는 beforeLoad에서 타입 안전하게 전달됨
51
+ return { stats: await fetchDashboard(context.user.id) }
52
+ },
53
+ component: Dashboard,
54
+ })
55
+
56
+ function Dashboard() {
57
+ const { stats } = Route.useLoaderData()
58
+ return <DashboardView stats={stats} />
59
+ }
60
+ ```
61
+
62
+ **실행 순서:**
63
+
64
+ ```
65
+ 1. Root.beforeLoad() ← 순차 실행
66
+ 2. _authenticated.beforeLoad() ← 인증 실패 시 여기서 redirect
67
+ 3. Dashboard.beforeLoad() ← 인증 통과 후 실행
68
+ 4. Root.loader() ← 모든 loader 병렬 실행
69
+ 5. _authenticated.loader()
70
+ 6. Dashboard.loader()
71
+ ```
72
+
73
+ **beforeLoad vs loader:**
74
+
75
+ | 항목 | beforeLoad | loader |
76
+ |------|-----------|--------|
77
+ | 실행 | 순차 (부모→자식) | 병렬 (모든 라우트 동시) |
78
+ | 시점 | loader 전 | beforeLoad 후 |
79
+ | 용도 | 인증, 리다이렉트, context 설정 | 데이터 페칭 |
80
+ | 반환값 | context 객체 (하위 라우트 접근 가능) | 라우트 데이터 |
81
+ | 성능 | 가볍게 유지 (모든 네비게이션에서 실행) | 무거운 작업 가능 |
82
+
83
+ **선택적 인증 (인증 없어도 페이지 렌더링):**
84
+
85
+ ```tsx
86
+ export const Route = createFileRoute('/profile')({
87
+ beforeLoad: async () => {
88
+ try {
89
+ const user = await verifySession()
90
+ return { user }
91
+ } catch {
92
+ return { user: null } // 리다이렉트 없이 null 반환
93
+ }
94
+ },
95
+ component: Profile,
96
+ })
97
+
98
+ function Profile() {
99
+ const { user } = Route.useRouteContext()
100
+ return user ? <UserProfile user={user} /> : <LoginPrompt />
101
+ }
102
+ ```
103
+
104
+ **redirect에서 isRedirect 사용:**
105
+
106
+ ```tsx
107
+ import { redirect, isRedirect } from '@tanstack/react-router'
108
+
109
+ beforeLoad: async ({ location }) => {
110
+ try {
111
+ const user = await verifySession()
112
+ if (!user) throw redirect({ to: '/login' })
113
+ return { user }
114
+ } catch (error) {
115
+ if (isRedirect(error)) throw error // redirect는 그대로 전파
116
+ throw redirect({ to: '/login' }) // 다른 에러도 로그인으로
117
+ }
118
+ }
119
+ ```
120
+
121
+ 참고: [Authenticated Routes](https://tanstack.com/router/latest/docs/framework/react/guide/authenticated-routes)
@@ -0,0 +1,104 @@
1
+ ---
2
+ title: Follow File-Based Routing Conventions
3
+ impact: HIGH
4
+ impactDescription: ensures correct route generation and code splitting
5
+ tags: routing, file-conventions, file-based-routing, code-splitting
6
+ ---
7
+
8
+ ## 파일 기반 라우팅 컨벤션
9
+
10
+ TanStack Router의 파일 이름 컨벤션을 따르면 라우트 트리가 자동 생성됩니다.
11
+
12
+ **파일 이름 규칙:**
13
+
14
+ | 패턴 | 파일명 | URL | 설명 |
15
+ |------|--------|-----|------|
16
+ | **Root** | `__root.tsx` | - | 앱 최상위 레이아웃 (필수) |
17
+ | **Index** | `index.tsx` | `/` | 디렉토리 인덱스 |
18
+ | **Static** | `about.tsx` | `/about` | 정적 경로 |
19
+ | **Dynamic** | `$postId.tsx` | `/posts/:postId` | 동적 파라미터 |
20
+ | **Pathless Layout** | `_layout.tsx` | - | URL 없는 레이아웃 래퍼 |
21
+ | **Route Group** | `(group)/` | - | 파일 정리용 (URL 영향 없음) |
22
+ | **Excluded** | `-helpers.tsx` | - | 라우트 생성 제외 |
23
+ | **Lazy** | `route.lazy.tsx` | - | 코드 스플릿 컴포넌트 |
24
+
25
+ **디렉토리 구조 예시:**
26
+
27
+ ```
28
+ src/routes/
29
+ ├── __root.tsx # 루트 레이아웃 (필수)
30
+ ├── index.tsx # / (홈)
31
+ ├── about.tsx # /about
32
+ ├── posts.tsx # /posts (레이아웃)
33
+ ├── posts/
34
+ │ ├── index.tsx # /posts (목록)
35
+ │ └── $postId.tsx # /posts/:postId
36
+ ├── _authenticated.tsx # pathless 인증 가드
37
+ ├── _authenticated/
38
+ │ ├── dashboard.tsx # /dashboard
39
+ │ └── settings.tsx # /settings
40
+ ├── (marketing)/ # route group (정리용)
41
+ │ ├── pricing.tsx # /pricing
42
+ │ └── features.tsx # /features
43
+ └── -components/ # 제외 (라우트 아님)
44
+ └── Sidebar.tsx
45
+ ```
46
+
47
+ **코드 스플리팅 (lazy route):**
48
+
49
+ ```tsx
50
+ // src/routes/posts.$postId.tsx - 크리티컬 설정만
51
+ import { createFileRoute } from '@tanstack/react-router'
52
+
53
+ export const Route = createFileRoute('/posts/$postId')({
54
+ loader: async ({ params }) => {
55
+ return { post: await fetchPost(params.postId) }
56
+ },
57
+ validateSearch: zodValidator(searchSchema),
58
+ beforeLoad: async ({ context }) => { /* auth */ },
59
+ })
60
+
61
+ // src/routes/posts.$postId.lazy.tsx - 컴포넌트만 (코드 스플릿)
62
+ import { createLazyFileRoute } from '@tanstack/react-router'
63
+
64
+ export const Route = createLazyFileRoute('/posts/$postId')({
65
+ component: PostDetail,
66
+ pendingComponent: PostSkeleton,
67
+ errorComponent: PostError,
68
+ })
69
+ ```
70
+
71
+ **Flat vs Directory 스타일:**
72
+
73
+ ```
74
+ # Flat (점 구분자)
75
+ posts.tsx → /posts
76
+ posts.index.tsx → /posts (index)
77
+ posts.$postId.tsx → /posts/:postId
78
+
79
+ # Directory (폴더)
80
+ posts/
81
+ route.tsx → /posts
82
+ index.tsx → /posts (index)
83
+ $postId.tsx → /posts/:postId
84
+ ```
85
+
86
+ **tsr.config.json 설정:**
87
+
88
+ ```json
89
+ {
90
+ "routesDirectory": "./src/routes",
91
+ "generatedRouteTree": "./src/routeTree.gen.ts",
92
+ "routeFileIgnorePrefix": "-",
93
+ "indexToken": "index",
94
+ "routeToken": "route"
95
+ }
96
+ ```
97
+
98
+ **주의사항:**
99
+ - `routeTree.gen.ts`는 자동 생성 파일 → 직접 수정 금지
100
+ - `__root.tsx`는 반드시 존재해야 함
101
+ - `_prefix`는 pathless layout, `(group)`은 정리 전용 (레이아웃 불가)
102
+ - lazy 파일에는 `loader`, `beforeLoad`, `validateSearch` 넣지 않음
103
+
104
+ 참고: [File-Based Routing](https://tanstack.com/router/latest/docs/framework/react/routing/file-based-routing), [File Naming Conventions](https://tanstack.com/router/latest/docs/framework/react/routing/file-naming-conventions)
@@ -0,0 +1,119 @@
1
+ ---
2
+ title: Use Link Component and useNavigate for Type-Safe Navigation
3
+ impact: HIGH
4
+ impactDescription: type-safe navigation prevents runtime route errors
5
+ tags: routing, navigation, link, useNavigate, type-safety
6
+ ---
7
+
8
+ ## Link와 useNavigate로 타입 안전한 네비게이션
9
+
10
+ TanStack Router는 `<Link>`(선언적)와 `useNavigate()`(명령적) 두 가지 네비게이션 방식을 제공합니다. 모든 라우트 경로, params, search가 자동 타입 추론됩니다.
11
+
12
+ **❌ 잘못된 예시 (타입 안전성 없는 네비게이션):**
13
+
14
+ ```tsx
15
+ // 문자열 하드코딩 - 오타 감지 불가
16
+ <a href="/posts/123">Post</a>
17
+
18
+ // useNavigate에서 from 없이 사용
19
+ const navigate = useNavigate()
20
+ navigate({ to: '/posts/$postId', params: { postId: '123' } })
21
+ ```
22
+
23
+ **✅ 올바른 예시 (Link 컴포넌트):**
24
+
25
+ ```tsx
26
+ import { Link } from '@tanstack/react-router'
27
+
28
+ // 기본 네비게이션 - to, params 모두 타입 추론
29
+ <Link to="/posts/$postId" params={{ postId: '123' }}>
30
+ Post Detail
31
+ </Link>
32
+
33
+ // search params 병합 (함수형 - 기존 params 유지)
34
+ <Link to="/posts" search={(prev) => ({ ...prev, page: 2 })}>
35
+ Next Page
36
+ </Link>
37
+
38
+ // 활성 링크 스타일링
39
+ <Link
40
+ to="/dashboard"
41
+ activeProps={{ className: 'font-bold text-blue-600' }}
42
+ activeOptions={{ exact: true }}
43
+ >
44
+ Dashboard
45
+ </Link>
46
+
47
+ // 프리로딩 - hover 시 미리 로드
48
+ <Link to="/posts/$postId" params={{ postId: '123' }} preload="intent">
49
+ View Post
50
+ </Link>
51
+ ```
52
+
53
+ **✅ 올바른 예시 (useNavigate):**
54
+
55
+ ```tsx
56
+ import { useNavigate } from '@tanstack/react-router'
57
+
58
+ function PostActions({ postId }: { postId: string }) {
59
+ // from을 지정하면 상대 경로 + 타입 추론 향상
60
+ const navigate = useNavigate({ from: '/posts/$postId' })
61
+
62
+ const handleDelete = async () => {
63
+ await deletePost(postId)
64
+ navigate({ to: '/posts', replace: true })
65
+ }
66
+
67
+ const handleEdit = () => {
68
+ navigate({
69
+ to: '/posts/$postId/edit',
70
+ params: { postId },
71
+ })
72
+ }
73
+
74
+ return (
75
+ <div>
76
+ <button onClick={handleEdit}>Edit</button>
77
+ <button onClick={handleDelete}>Delete</button>
78
+ </div>
79
+ )
80
+ }
81
+ ```
82
+
83
+ **search params 주의사항:**
84
+
85
+ ```tsx
86
+ // ❌ 기존 search params 덮어쓰기
87
+ <Link to="/posts" search={{ page: 2 }}>Next</Link>
88
+
89
+ // ✅ 기존 search params 유지 + 병합
90
+ <Link to="/posts" search={(prev) => ({ ...prev, page: 2 })}>Next</Link>
91
+
92
+ // ✅ 모든 search params 유지
93
+ <Link to="/about" search={true}>About</Link>
94
+ ```
95
+
96
+ **activeOptions 설정:**
97
+
98
+ ```tsx
99
+ <Link
100
+ to="/products"
101
+ search={{ category: 'electronics' }}
102
+ activeOptions={{
103
+ exact: false, // 하위 경로도 활성 처리
104
+ includeSearch: true, // search params도 매칭 조건에 포함
105
+ }}
106
+ activeProps={{ className: 'active' }}
107
+ >
108
+ Electronics
109
+ </Link>
110
+
111
+ // children render function으로 동적 콘텐츠
112
+ <Link to="/profile">
113
+ {({ isActive }) => (
114
+ <span className={isActive ? 'font-bold' : ''}>Profile</span>
115
+ )}
116
+ </Link>
117
+ ```
118
+
119
+ 참고: [Navigation Guide](https://tanstack.com/router/latest/docs/framework/react/guide/navigation), [Link Options](https://tanstack.com/router/latest/docs/framework/react/guide/link-options)
@@ -0,0 +1,155 @@
1
+ ---
2
+ title: Use Outlet and Pathless Layouts for Nested UI
3
+ impact: HIGH
4
+ impactDescription: enables shared UI structure without prop drilling
5
+ tags: routing, outlet, layouts, createRootRoute, nesting
6
+ ---
7
+
8
+ ## Outlet과 Pathless Layout으로 중첩 UI 구현
9
+
10
+ `<Outlet />`으로 하위 라우트를 렌더링하고, pathless layout(`_prefix`)으로 URL 변경 없이 공유 UI를 적용합니다.
11
+
12
+ **❌ 잘못된 예시 (레이아웃 중복):**
13
+
14
+ ```tsx
15
+ // routes/dashboard/overview.tsx
16
+ function OverviewPage() {
17
+ return (
18
+ <div className="dashboard">
19
+ <Sidebar /> {/* 중복 */}
20
+ <main><Overview /></main>
21
+ </div>
22
+ )
23
+ }
24
+
25
+ // routes/dashboard/analytics.tsx
26
+ function AnalyticsPage() {
27
+ return (
28
+ <div className="dashboard">
29
+ <Sidebar /> {/* 중복 */}
30
+ <main><Analytics /></main>
31
+ </div>
32
+ )
33
+ }
34
+ ```
35
+
36
+ **✅ 올바른 예시 (Outlet으로 레이아웃 공유):**
37
+
38
+ ```tsx
39
+ // src/routes/__root.tsx
40
+ import { createRootRoute, Outlet } from '@tanstack/react-router'
41
+
42
+ export const Route = createRootRoute({
43
+ component: () => (
44
+ <div>
45
+ <Header />
46
+ <Outlet /> {/* 하위 라우트가 여기에 렌더링 */}
47
+ <Footer />
48
+ </div>
49
+ ),
50
+ })
51
+
52
+ // src/routes/dashboard.tsx - 레이아웃 라우트
53
+ export const Route = createFileRoute('/dashboard')({
54
+ component: DashboardLayout,
55
+ })
56
+
57
+ function DashboardLayout() {
58
+ return (
59
+ <div className="dashboard">
60
+ <Sidebar />
61
+ <main>
62
+ <Outlet /> {/* dashboard/overview, dashboard/analytics 렌더링 */}
63
+ </main>
64
+ </div>
65
+ )
66
+ }
67
+
68
+ // src/routes/dashboard/overview.tsx
69
+ export const Route = createFileRoute('/dashboard/overview')({
70
+ component: () => <Overview />, // DashboardLayout 안에 렌더링
71
+ })
72
+
73
+ // src/routes/dashboard/analytics.tsx
74
+ export const Route = createFileRoute('/dashboard/analytics')({
75
+ component: () => <Analytics />,
76
+ })
77
+ ```
78
+
79
+ **Pathless Layout (URL 없는 레이아웃):**
80
+
81
+ ```
82
+ src/routes/
83
+ ├── _public.tsx ← /없음 (pathless, navbar+footer만)
84
+ ├── _public/
85
+ │ ├── index.tsx → /
86
+ │ ├── about.tsx → /about
87
+ │ └── pricing.tsx → /pricing
88
+ ├── _dashboard.tsx ← /없음 (pathless, sidebar 레이아웃)
89
+ └── _dashboard/
90
+ ├── overview.tsx → /overview
91
+ ├── analytics.tsx → /analytics
92
+ └── settings.tsx → /settings
93
+ ```
94
+
95
+ ```tsx
96
+ // src/routes/_dashboard.tsx
97
+ export const Route = createFileRoute('/_dashboard')({
98
+ component: () => (
99
+ <div className="flex">
100
+ <Sidebar />
101
+ <main className="flex-1">
102
+ <Outlet />
103
+ </main>
104
+ </div>
105
+ ),
106
+ })
107
+
108
+ // src/routes/_dashboard/overview.tsx
109
+ export const Route = createFileRoute('/_dashboard/overview')({
110
+ component: () => <h1>Overview</h1>, // URL: /overview
111
+ })
112
+ ```
113
+
114
+ **Route Group vs Pathless Layout:**
115
+
116
+ | 패턴 | 문법 | URL 영향 | 레이아웃 |
117
+ |------|------|---------|---------|
118
+ | **Route Group** | `(groupName)/` | 없음 | ❌ 불가 |
119
+ | **Pathless Layout** | `_layoutName.tsx` | 없음 | ✅ 가능 |
120
+
121
+ - Route Group `(public)/`: 파일 정리용, 레이아웃 없음
122
+ - Pathless Layout `_public.tsx`: 공유 UI 래핑 가능
123
+
124
+ **createRootRouteWithContext:**
125
+
126
+ ```tsx
127
+ // 타입 안전한 전역 context
128
+ interface RouterContext {
129
+ queryClient: QueryClient
130
+ auth: AuthState
131
+ }
132
+
133
+ export const Route = createRootRouteWithContext<RouterContext>()({
134
+ component: () => <Outlet />,
135
+ })
136
+
137
+ // 하위 라우트에서 context 접근
138
+ export const Route = createFileRoute('/dashboard')({
139
+ beforeLoad: ({ context }) => {
140
+ // context.queryClient, context.auth 타입 안전
141
+ },
142
+ })
143
+ ```
144
+
145
+ **component 생략 시 자동 Outlet:**
146
+
147
+ ```tsx
148
+ // component를 지정하지 않으면 자동으로 <Outlet /> 렌더링
149
+ export const Route = createFileRoute('/app')({
150
+ // component 생략 → Outlet 자동 렌더링
151
+ beforeLoad: async ({ context }) => { /* ... */ },
152
+ })
153
+ ```
154
+
155
+ 참고: [Outlets Guide](https://tanstack.com/router/latest/docs/framework/react/guide/outlets), [Route Trees](https://tanstack.com/router/latest/docs/framework/react/guide/route-trees)
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: Use Type-Safe Path Params with useParams and getRouteApi
3
+ impact: HIGH
4
+ impactDescription: ensures correct param types across code-split components
5
+ tags: routing, path-params, useParams, getRouteApi, type-safety
6
+ ---
7
+
8
+ ## useParams와 getRouteApi로 타입 안전한 Path Params
9
+
10
+ TanStack Router의 `useParams`와 `getRouteApi`로 동적 라우트 파라미터를 타입 안전하게 접근합니다.
11
+
12
+ **❌ 잘못된 예시 (타입 안전성 없음):**
13
+
14
+ ```tsx
15
+ // strict: false는 타입 추론 약화
16
+ function PostDetail() {
17
+ const params = useParams({ strict: false })
18
+ const postId = params.postId // any 타입
19
+ }
20
+ ```
21
+
22
+ **✅ 올바른 예시 (Route 바인딩):**
23
+
24
+ ```tsx
25
+ import { createFileRoute } from '@tanstack/react-router'
26
+
27
+ export const Route = createFileRoute('/posts/$postId')({
28
+ loader: async ({ params }) => {
29
+ // params.postId는 string 타입으로 자동 추론
30
+ return { post: await getPost(params.postId) }
31
+ },
32
+ component: PostDetail,
33
+ })
34
+
35
+ function PostDetail() {
36
+ // Route에 바인딩된 useParams - 완전한 타입 추론
37
+ const { postId } = Route.useParams()
38
+ const { post } = Route.useLoaderData()
39
+
40
+ return <div>{post.title}</div>
41
+ }
42
+ ```
43
+
44
+ **✅ 올바른 예시 (getRouteApi - 코드 스플릿 컴포넌트):**
45
+
46
+ ```tsx
47
+ // components/PostDetail.tsx (별도 파일)
48
+ import { getRouteApi } from '@tanstack/react-router'
49
+
50
+ // Route import 없이 타입 안전하게 접근
51
+ const routeApi = getRouteApi('/posts/$postId')
52
+
53
+ export function PostDetail() {
54
+ const { postId } = routeApi.useParams()
55
+ const { post } = routeApi.useLoaderData()
56
+ const search = routeApi.useSearch()
57
+ const context = routeApi.useRouteContext()
58
+
59
+ return <div>{post.title}</div>
60
+ }
61
+ ```
62
+
63
+ **select로 리렌더 최적화:**
64
+
65
+ ```tsx
66
+ // postId만 변경 시 리렌더
67
+ const postId = useParams({
68
+ from: '/posts/$postId',
69
+ select: (params) => params.postId,
70
+ })
71
+ ```
72
+
73
+ **from으로 타입 컨텍스트 지정:**
74
+
75
+ ```tsx
76
+ // 다른 라우트의 params 접근
77
+ const { postId } = useParams({ from: '/posts/$postId' })
78
+
79
+ // 현재 라우트 컨텍스트에서 접근 (Route 바인딩)
80
+ const { postId } = Route.useParams()
81
+ ```
82
+
83
+ **타입 안전성 순위:**
84
+ 1. `Route.useParams()` - 라우트에 직접 바인딩, 최고 타입 안전성
85
+ 2. `getRouteApi('/path').useParams()` - 코드 스플릿 시 사용, 순환 의존성 방지
86
+ 3. `useParams({ from: '/path' })` - from으로 타입 컨텍스트 지정
87
+ 4. `useParams({ strict: false })` - 전역 접근, 타입 약화 (비권장)
88
+
89
+ 참고: [Path Params Guide](https://tanstack.com/router/latest/docs/framework/react/guide/path-params), [getRouteApi](https://tanstack.com/router/latest/docs/framework/react/api/router/getRouteApiFunction)