@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
@@ -1,15 +1,166 @@
1
1
  # TanStack Router - Navigation
2
2
 
3
- <patterns>
3
+ > TanStack Router v1.159.4
4
+
5
+ 네비게이션 가이드. Link, useNavigate, Navigate 컴포넌트, router.navigate를 다룬다.
6
+
7
+ ---
8
+
9
+ <navigation_concepts>
10
+
11
+ ## 네비게이션 기본 개념
12
+
13
+ TanStack Router의 모든 네비게이션은 **상대적**이다. 항상 **origin**(from)에서 **destination**(to)으로 이동한다.
14
+
15
+ ### 핵심 인터페이스
16
+
17
+ ```typescript
18
+ // ToOptions: 모든 네비게이션 API의 기반
19
+ type ToOptions = {
20
+ from?: string // 출발 라우트 (없으면 root `/`로 간주)
21
+ to: string // 목적지 경로 (절대/상대 모두 가능)
22
+ params: object | ((prev) => object) // Path params
23
+ search: object | ((prev) => object) // Search params
24
+ hash?: string | ((prev) => string) // URL hash
25
+ state?: object | ((prev) => object) // History state (URL에 안 보임)
26
+ }
27
+
28
+ // NavigateOptions: ToOptions 확장
29
+ type NavigateOptions = ToOptions & {
30
+ replace?: boolean // history.replace 사용 여부
31
+ resetScroll?: boolean // 스크롤 상단 리셋 (기본 true)
32
+ hashScrollIntoView?: boolean | ScrollIntoViewOptions // hash 대상 스크롤
33
+ viewTransition?: boolean | ViewTransitionOptions // View Transition API
34
+ ignoreBlocker?: boolean // 네비게이션 블로커 무시
35
+ reloadDocument?: boolean // 전체 페이지 로드 (SPA 우회)
36
+ href?: string // 외부 URL 지정 (to 대신)
37
+ }
38
+
39
+ // LinkOptions: NavigateOptions 확장 (<a> 태그 전용)
40
+ type LinkOptions = NavigateOptions & {
41
+ target?: HTMLAnchorElement['target'] // 새 탭 열기 등
42
+ activeOptions?: ActiveOptions // Active 조건 설정
43
+ preload?: false | 'intent' // 사전 로딩 전략
44
+ preloadDelay?: number // 사전 로딩 지연 (ms)
45
+ disabled?: boolean // href 없이 렌더링
46
+ }
47
+ ```
48
+
49
+ ### 4가지 네비게이션 API
50
+
51
+ | API | 용도 | 특징 |
52
+ |-----|------|------|
53
+ | `<Link>` | 선언적 네비게이션 | `<a>` 태그 생성, cmd/ctrl+click 지원 |
54
+ | `useNavigate()` | 프로그래매틱 네비게이션 | 사이드이펙트 후 네비게이션 |
55
+ | `<Navigate>` | 즉시 리다이렉트 | 컴포넌트 마운트 시 즉시 이동 |
56
+ | `router.navigate()` | 어디서든 네비게이션 | 라우터 인스턴스가 있는 곳이면 가능 |
57
+
58
+ </navigation_concepts>
59
+
60
+ ---
61
+
62
+ <link_component>
63
+
64
+ ## Link: 선언적 네비게이션
65
+
66
+ 기본 사용법부터 고급 옵션까지 다룬다.
67
+
68
+ ### 기본 예시
4
69
 
5
70
  ```tsx
6
- // Link
71
+ // 정적 라우트
7
72
  <Link to="/about">About</Link>
8
- <Link to="/posts/$postId" params={{ postId: '123' }}>Post 123</Link>
9
- <Link to="/products" search={{ page: 1, sort: 'newest' }}>Products</Link>
10
- <Link to="/products" search={prev => ({ ...prev, page: 2 })}>Next</Link>
11
73
 
12
- // Active 스타일
74
+ // 동적 파라미터 (타입 안전)
75
+ <Link to="/posts/$postId" params={{ postId: '123' }}>
76
+ Post 123
77
+ </Link>
78
+
79
+ // Search params (객체)
80
+ <Link to="/products" search={{ page: 1, sort: 'newest' }}>
81
+ Products
82
+ </Link>
83
+
84
+ // Search params (함수: 이전 값 기반)
85
+ <Link to="/products" search={prev => ({ ...prev, page: 2 })}>
86
+ Next Page
87
+ </Link>
88
+
89
+ // Hash + Replace
90
+ <Link to="/docs" hash="intro" replace>
91
+ Docs
92
+ </Link>
93
+
94
+ // History state (URL에 보이지 않는 데이터 전달)
95
+ <Link to="/checkout" state={{ fromCart: true }}>
96
+ Checkout
97
+ </Link>
98
+ ```
99
+
100
+ ### 상대 경로 네비게이션
101
+
102
+ `from`을 지정하면 상대 경로 사용 가능. 없으면 절대 경로로 간주.
103
+
104
+ ```tsx
105
+ // "." = 현재 라우트 리로드
106
+ <Link to=".">현재 라우트 리로드</Link>
107
+
108
+ // ".." = 부모 라우트로 이동
109
+ <Link to="..">뒤로 가기</Link>
110
+
111
+ // from 지정으로 상대 경로 사용
112
+ <Link from="/posts/$postId" to="../categories">
113
+ Categories
114
+ </Link>
115
+
116
+ // route.fullPath 참조 (리팩토링 안전)
117
+ import { Route as postIdRoute } from './routes/posts.$postId'
118
+ <Link from={postIdRoute.fullPath} to="../categories">
119
+ Categories
120
+ </Link>
121
+ ```
122
+
123
+ ### 선택적 파라미터 (Optional Parameters)
124
+
125
+ `{-$paramName}` 구문으로 선택적 파라미터 사용.
126
+
127
+ ```tsx
128
+ // 선택적 파라미터 설정
129
+ <Link to="/posts/{-$category}" params={{ category: 'tech' }}>
130
+ Tech Posts
131
+ </Link>
132
+
133
+ // 선택적 파라미터 제거 (undefined로 명시)
134
+ <Link to="/posts/{-$category}" params={{ category: undefined }}>
135
+ All Posts
136
+ </Link>
137
+
138
+ // 함수로 조건부 설정
139
+ <Link
140
+ to="/posts/{-$category}"
141
+ params={prev => ({
142
+ ...prev,
143
+ category: someCondition ? 'tech' : undefined,
144
+ })}
145
+ >
146
+ Conditional Category
147
+ </Link>
148
+
149
+ // 필수 + 선택 혼합
150
+ <Link
151
+ to="/users/$id/{-$tab}"
152
+ params={{ id: '123', tab: 'settings' }}
153
+ >
154
+ User Settings
155
+ </Link>
156
+ ```
157
+
158
+ ### Active 상태 스타일링
159
+
160
+ 현재 경로와 Link가 일치할 때 스타일 적용.
161
+
162
+ ```tsx
163
+ // 기본 활성화 체크
13
164
  <Link
14
165
  to="/about"
15
166
  activeProps={{ className: 'text-blue-500 font-bold' }}
@@ -17,64 +168,511 @@
17
168
  >
18
169
  About
19
170
  </Link>
20
- <Link to="/" activeOptions={{ exact: true }}>Home</Link>
21
171
 
22
- // useNavigate
172
+ // Exact match (자식 라우트 제외)
173
+ <Link to="/" activeOptions={{ exact: true }}>
174
+ Home
175
+ </Link>
176
+
177
+ // Search params 포함 매칭
178
+ <Link
179
+ to="/posts"
180
+ search={{ page: 1 }}
181
+ activeOptions={{ includeSearch: true }}
182
+ >
183
+ Posts Page 1
184
+ </Link>
185
+
186
+ // Hash 포함 매칭
187
+ <Link
188
+ to="/docs"
189
+ hash="section-1"
190
+ activeOptions={{ includeHash: true }}
191
+ >
192
+ Section 1
193
+ </Link>
194
+
195
+ // data-status 속성 활용 (CSS 스타일링)
196
+ // 활성 시 data-status="active", 비활성 시 undefined
197
+ <Link to="/about">About</Link>
198
+
199
+ // isActive를 children 함수로 전달
200
+ <Link to="/blog/post">
201
+ {({ isActive }) => (
202
+ <>
203
+ <span>My Blog Post</span>
204
+ <Icon className={isActive ? 'active' : 'inactive'} />
205
+ </>
206
+ )}
207
+ </Link>
208
+ ```
209
+
210
+ ### ActiveOptions 인터페이스
211
+
212
+ ```typescript
213
+ interface ActiveOptions {
214
+ exact?: boolean // pathname 정확 매칭 (기본 false)
215
+ includeHash?: boolean // hash 포함 매칭 (기본 false)
216
+ includeSearch?: boolean // search 포함 매칭 (기본 true)
217
+ explicitUndefined?: boolean // undefined 값도 매칭 조건에 포함 (기본 false)
218
+ }
219
+ ```
220
+
221
+ ### Preloading 전략
222
+
223
+ 사전 로딩으로 네비게이션 성능 향상.
224
+
225
+ ```tsx
226
+ // intent: 마우스 호버 또는 터치스타트 시 로드 (권장)
227
+ <Link to="/posts" preload="intent">
228
+ Posts (빠른 로드)
229
+ </Link>
230
+
231
+ // 지연 시간 커스터마이즈 (기본 50ms)
232
+ <Link to="/blog" preload="intent" preloadDelay={100}>
233
+ Blog
234
+ </Link>
235
+
236
+ // 라우터 수준에서 기본 프리로드 설정
237
+ const router = createRouter({
238
+ routeTree,
239
+ defaultPreload: 'intent', // 모든 Link에 intent 적용
240
+ defaultPreloadDelay: 100, // 기본 지연 100ms
241
+ })
242
+ ```
243
+
244
+ ### 수동 프리로딩 (router.preloadRoute)
245
+
246
+ ```tsx
247
+ const Component = () => {
248
+ const router = useRouter()
249
+
250
+ useEffect(() => {
251
+ // 특정 라우트를 수동으로 프리로드
252
+ router.preloadRoute({
253
+ to: '/posts/$postId',
254
+ params: { postId: '1' },
255
+ })
256
+ }, [router])
257
+
258
+ return <div />
259
+ }
260
+ ```
261
+
262
+ ### Link Props 참조표
263
+
264
+ | Props | 타입 | 기본값 | 설명 |
265
+ |-------|------|--------|------|
266
+ | `to` | string | - | 목적지 경로 (필수) |
267
+ | `from` | string | - | 출발 라우트 (상대 경로 사용 시) |
268
+ | `params` | object \| function | - | Path 파라미터 (타입 안전) |
269
+ | `search` | object \| function | - | Search params (함수로 이전 값 접근) |
270
+ | `hash` | string \| function | - | URL hash |
271
+ | `state` | object \| function | - | History state (URL에 안 보임) |
272
+ | `replace` | boolean | false | history.replace 사용 여부 |
273
+ | `resetScroll` | boolean | true | 스크롤을 상단으로 리셋 |
274
+ | `preload` | false \| 'intent' | - | 사전 로딩 전략 |
275
+ | `preloadDelay` | number | 50 | 사전 로딩 지연 (ms) |
276
+ | `activeProps` | object \| function | - | Active 상태 시 적용할 props |
277
+ | `inactiveProps` | object \| function | - | Inactive 상태 시 적용할 props |
278
+ | `activeOptions` | ActiveOptions | - | Active 조건 설정 |
279
+ | `disabled` | boolean | false | href 없이 렌더링 |
280
+ | `target` | string | - | 새 탭 등 표준 anchor target |
281
+ | `viewTransition` | boolean \| ViewTransitionOptions | - | View Transition API |
282
+ | `hashScrollIntoView` | boolean \| ScrollIntoViewOptions | - | hash 위치로 스크롤 |
283
+
284
+ </link_component>
285
+
286
+ ---
287
+
288
+ <use_navigate>
289
+
290
+ ## useNavigate: 프로그래매틱 네비게이션
291
+
292
+ 이벤트 핸들러나 조건부 로직에서 네비게이션 수행. Link를 쓸 수 없는 사이드이펙트 상황에 사용.
293
+
294
+ ### 기본 사용법
295
+
296
+ ```tsx
23
297
  const Component = () => {
24
298
  const navigate = useNavigate()
25
299
 
26
- const goToAbout = () => navigate({ to: '/about' })
27
- const goToPost = (id: string) => navigate({ to: '/posts/$postId', params: { postId: id } })
28
- const updateSearch = () => navigate({ to: '/products', search: prev => ({ ...prev, page: 2 }) })
29
- const replaceRoute = () => navigate({ to: '/login', replace: true })
300
+ // 정적 네비게이션
301
+ const handleNavigate = () => navigate({ to: '/about' })
302
+
303
+ // 동적 파라미터
304
+ const goToPost = (id: string) => {
305
+ navigate({ to: '/posts/$postId', params: { postId: id } })
306
+ }
307
+
308
+ // Search params 업데이트 (함수)
309
+ const nextPage = () => {
310
+ navigate({
311
+ to: '/products',
312
+ search: prev => ({ ...prev, page: (prev.page ?? 1) + 1 }),
313
+ })
314
+ }
315
+
316
+ // History replace
317
+ const redirect = () => {
318
+ navigate({ to: '/login', replace: true })
319
+ }
320
+
321
+ // 상대 경로
30
322
  const goUp = () => navigate({ to: '..' })
31
323
 
32
- return <button onClick={goToAbout}>Go</button>
324
+ return (
325
+ <div>
326
+ <button onClick={handleNavigate}>Go to About</button>
327
+ <button onClick={() => goToPost('123')}>View Post</button>
328
+ <button onClick={nextPage}>Next</button>
329
+ </div>
330
+ )
33
331
  }
332
+ ```
333
+
334
+ ### startTransition과 함께 사용
34
335
 
35
- // Preloading
36
- <Link to="/posts" preload="intent">Posts</Link> // hover 시
37
- <Link to="/dashboard" preload="render">Dash</Link> // 렌더링 시
38
- <Link to="/products" preload="viewport">Prod</Link> // viewport 진입 시
336
+ 비동기 작업 완료 후 네비게이션. 폼 제출, API 호출 등에 활용.
39
337
 
40
- // 조건부 네비게이션
338
+ ```tsx
41
339
  const SubmitButton = () => {
42
340
  const navigate = useNavigate()
43
341
  const [isPending, startTransition] = useTransition()
44
342
 
45
- const handleSubmit = async () => {
46
- const result = await submitForm()
343
+ const handleSubmit = async (formData: FormData) => {
344
+ // 비동기 작업 (폼 제출, 데이터 저장 등)
345
+ const result = await submitForm(formData)
346
+
47
347
  if (result.success) {
48
- startTransition(() => navigate({ to: '/success' }))
348
+ // startTransition으로 감싸서 네비게이션
349
+ startTransition(() => {
350
+ navigate({ to: '/success', search: { id: result.id } })
351
+ })
352
+ }
353
+ }
354
+
355
+ return (
356
+ <button onClick={() => handleSubmit(new FormData())} disabled={isPending}>
357
+ {isPending ? 'Saving...' : 'Submit'}
358
+ </button>
359
+ )
360
+ }
361
+ ```
362
+
363
+ ### 타입 안전 네비게이션 (from 파라미터)
364
+
365
+ 현재 라우트를 명시해 타입 체크 활성화.
366
+
367
+ ```tsx
368
+ // 타입 안전: `/posts/$postId`에서만 호출 가능
369
+ const navigate = useNavigate({ from: '/posts/$postId' })
370
+
371
+ const goToRelated = (relatedId: string) => {
372
+ navigate({
373
+ to: '/posts/$postId',
374
+ params: { postId: relatedId }, // 타입 체크됨
375
+ })
376
+ }
377
+
378
+ // Route.useNavigate()도 동일 (from 자동 지정)
379
+ const navigate = Route.useNavigate()
380
+ ```
381
+
382
+ ### navigate() 옵션 참조표
383
+
384
+ | 옵션 | 타입 | 기본값 | 설명 |
385
+ |------|------|--------|------|
386
+ | `to` | string | - | 목적지 경로 (필수) |
387
+ | `from` | string | - | 출발 라우트 |
388
+ | `params` | object \| function | - | Path 파라미터 |
389
+ | `search` | object \| function | - | Search params |
390
+ | `hash` | string \| function | - | URL hash |
391
+ | `state` | object \| function | - | History state |
392
+ | `replace` | boolean | false | history.replace 사용 여부 |
393
+ | `resetScroll` | boolean | true | 스크롤을 상단으로 리셋 |
394
+ | `viewTransition` | boolean \| ViewTransitionOptions | - | View Transition API |
395
+ | `ignoreBlocker` | boolean | false | 네비게이션 블로커 무시 |
396
+
397
+ </use_navigate>
398
+
399
+ ---
400
+
401
+ <navigate_component>
402
+
403
+ ## Navigate 컴포넌트: 즉시 리다이렉트
404
+
405
+ 컴포넌트 마운트 시 즉시 네비게이션. 클라이언트 전용 리다이렉트에 사용.
406
+
407
+ ```tsx
408
+ import { Navigate } from '@tanstack/react-router'
409
+
410
+ // useNavigate + useEffect 대신 사용
411
+ const Component = () => {
412
+ return <Navigate to="/posts/$postId" params={{ postId: 'my-first-post' }} />
413
+ }
414
+
415
+ // 조건부 리다이렉트
416
+ const ProtectedPage = () => {
417
+ const { isAuthenticated } = useAuth()
418
+
419
+ if (!isAuthenticated) {
420
+ return <Navigate to="/login" />
421
+ }
422
+
423
+ return <div>Protected Content</div>
424
+ }
425
+ ```
426
+
427
+ > 주의: Navigate 컴포넌트는 클라이언트 전용. 서버 사이드 리다이렉트가 필요하면 beforeLoad에서 `redirect()` throw 사용.
428
+
429
+ </navigate_component>
430
+
431
+ ---
432
+
433
+ <match_route>
434
+
435
+ ## useMatchRoute / MatchRoute: 라우트 매칭 확인
436
+
437
+ 현재 경로가 특정 라우트와 매칭되는지 확인. 낙관적 UI에 유용.
438
+
439
+ ```tsx
440
+ import { MatchRoute, useMatchRoute } from '@tanstack/react-router'
441
+
442
+ // 컴포넌트 방식: pending 상태 표시
443
+ const NavItem = () => (
444
+ <Link to="/users">
445
+ Users
446
+ <MatchRoute to="/users" pending>
447
+ <Spinner />
448
+ </MatchRoute>
449
+ </Link>
450
+ )
451
+
452
+ // 함수 children 방식
453
+ const NavItem2 = () => (
454
+ <Link to="/users">
455
+ Users
456
+ <MatchRoute to="/users" pending>
457
+ {(match) => <Spinner show={match} />}
458
+ </MatchRoute>
459
+ </Link>
460
+ )
461
+
462
+ // 훅 방식: 프로그래매틱 체크
463
+ const Component = () => {
464
+ const matchRoute = useMatchRoute()
465
+
466
+ useEffect(() => {
467
+ if (matchRoute({ to: '/users', pending: true })) {
468
+ console.info('/users 라우트가 매칭되고 전환 중')
49
469
  }
470
+ })
471
+
472
+ return <div />
473
+ }
474
+ ```
475
+
476
+ </match_route>
477
+
478
+ ---
479
+
480
+ <programmatic_patterns>
481
+
482
+ ## 실전 패턴
483
+
484
+ ### 조건부 네비게이션
485
+
486
+ ```tsx
487
+ const Form = () => {
488
+ const navigate = useNavigate()
489
+ const [errors, setErrors] = useState<Record<string, string>>({})
490
+
491
+ const handleSubmit = async (data: FormData) => {
492
+ const result = await validate(data)
493
+
494
+ if (!result.success) {
495
+ setErrors(result.errors)
496
+ return // 에러 있으면 네비게이션 안 함
497
+ }
498
+
499
+ navigate({ to: '/confirmation', search: { orderId: result.id } })
500
+ }
501
+
502
+ return <form onSubmit={handleSubmit}>{/* ... */}</form>
503
+ }
504
+ ```
505
+
506
+ ### 뒤로 가기 (검증 필수)
507
+
508
+ ```tsx
509
+ const BackButton = () => {
510
+ const navigate = useNavigate()
511
+
512
+ return (
513
+ <button onClick={() => navigate({ to: '..' })}>
514
+ Back
515
+ </button>
516
+ )
517
+ }
518
+ ```
519
+
520
+ ### 폼 제출 후 상세 페이지로 이동
521
+
522
+ ```tsx
523
+ const CreatePost = () => {
524
+ const navigate = useNavigate()
525
+ const createMutation = useMutation({
526
+ mutationFn: createPost,
527
+ onSuccess: (newPost) => {
528
+ // 생성된 post ID로 상세 페이지로 이동
529
+ navigate({
530
+ to: '/posts/$postId',
531
+ params: { postId: newPost.id },
532
+ })
533
+ },
534
+ })
535
+
536
+ return (
537
+ <button onClick={() => createMutation.mutate({ title: 'New Post' })}>
538
+ Create
539
+ </button>
540
+ )
541
+ }
542
+ ```
543
+
544
+ ### Search params로 필터 상태 유지
545
+
546
+ ```tsx
547
+ const FilterableList = () => {
548
+ const navigate = useNavigate()
549
+ const { category, sort } = Route.useSearch()
550
+
551
+ const handleFilter = (newCategory: string) => {
552
+ navigate({
553
+ to: '/items',
554
+ search: prev => ({
555
+ ...prev,
556
+ category: newCategory,
557
+ page: 1, // 필터 변경 시 페이지 1로 리셋
558
+ }),
559
+ })
50
560
  }
51
561
 
52
- return <button onClick={handleSubmit} disabled={isPending}>Submit</button>
562
+ return (
563
+ <select value={category} onChange={e => handleFilter(e.target.value)}>
564
+ <option value="all">All</option>
565
+ <option value="electronics">Electronics</option>
566
+ </select>
567
+ )
53
568
  }
54
569
  ```
55
570
 
56
- </patterns>
571
+ ### 선택적 파라미터로 필터 네비게이션
572
+
573
+ ```tsx
574
+ const FilterNav = () => {
575
+ const navigate = useNavigate()
576
+
577
+ // 필터 초기화
578
+ const clearFilters = () => {
579
+ navigate({
580
+ to: '/posts/{-$category}/{-$tag}',
581
+ params: { category: undefined, tag: undefined },
582
+ })
583
+ }
584
+
585
+ // 특정 카테고리 설정
586
+ const setCategory = (category: string) => {
587
+ navigate({
588
+ to: '/posts/{-$category}/{-$tag}',
589
+ params: prev => ({ ...prev, category }),
590
+ })
591
+ }
592
+
593
+ return (
594
+ <div>
595
+ <button onClick={() => setCategory('tech')}>Tech</button>
596
+ <button onClick={clearFilters}>Clear</button>
597
+ </div>
598
+ )
599
+ }
600
+ ```
601
+
602
+ </programmatic_patterns>
603
+
604
+ ---
605
+
606
+ <type_safe_routing>
607
+
608
+ ## 타입 안전 라우팅
609
+
610
+ TanStack Router는 경로와 파라미터를 타입 체크한다.
611
+
612
+ ### Link 타입 체크
613
+
614
+ ```tsx
615
+ // 올바른 예시
616
+ <Link to="/posts/$postId" params={{ postId: '123' }}>
617
+ // 타입 체크: postId 필수
618
+ </Link>
619
+
620
+ <Link to="/about">
621
+ // params 불필요
622
+ </Link>
623
+
624
+ // route.to로 타입 안전 참조
625
+ import { Route as aboutRoute } from './routes/about'
626
+ <Link to={aboutRoute.to}>About</Link>
627
+
628
+ // 오류 예시
629
+ <Link to="/posts/$postId">
630
+ // TS Error: params 필수
631
+ </Link>
632
+
633
+ <Link to="/posts" params={{ postId: '123' }}>
634
+ // TS Error: /posts는 파라미터 없음
635
+ </Link>
636
+ ```
637
+
638
+ ### useNavigate 타입 체크 (from 파라미터)
639
+
640
+ ```tsx
641
+ // `/posts/$postId` 라우트 내부
642
+ export const Route = createFileRoute('/posts/$postId')({
643
+ component: PostDetail,
644
+ })
645
+
646
+ const PostDetail = () => {
647
+ // from 명시: 이 라우트 내에서만 호출 가능
648
+ const navigate = useNavigate({ from: '/posts/$postId' })
649
+
650
+ const goRelated = (id: string) => {
651
+ navigate({
652
+ to: '/posts/$postId',
653
+ params: { postId: id }, // 타입 체크됨
654
+ })
655
+ }
656
+ }
657
+ ```
658
+
659
+ </type_safe_routing>
660
+
661
+ ---
57
662
 
58
- <options>
663
+ <comparison>
59
664
 
60
- | Link Props | 타입 | 설명 |
61
- |------------|------|------|
62
- | `to` | string | 목적지 경로 |
63
- | `params` | object | Path 파라미터 |
64
- | `search` | object \| function | Search params |
65
- | `hash` | string | Hash |
66
- | `replace` | boolean | history replace |
67
- | `preload` | 'intent' \| 'render' \| 'viewport' | Preload 전략 |
68
- | `activeProps` | object | Active 시 props |
69
- | `inactiveProps` | object | Inactive 시 props |
665
+ ## Link vs useNavigate vs Navigate vs router.navigate
70
666
 
71
- | navigate 옵션 | 타입 | 설명 |
72
- |---------------|------|------|
73
- | `to` | string | 목적지 경로 |
74
- | `params` | object | Path 파라미터 |
75
- | `search` | object \| function | Search params |
76
- | `hash` | string | Hash |
77
- | `replace` | boolean | history.replace 사용 |
78
- | `resetScroll` | boolean | 스크롤 리셋 |
667
+ | 상황 | 추천 | 이유 |
668
+ |------|------|------|
669
+ | HTML 선언 | `<Link>` | 자동 타입 체크, 접근성 (href), cmd/ctrl+click |
670
+ | 이벤트 핸들러 | `useNavigate()` | 조건부 로직 가능 |
671
+ | 호버 preload | `<Link preload="intent">` | 자동으로 효율적 |
672
+ | 비동기 후 네비게이션 | `useNavigate()` + startTransition | 상태 동기화 |
673
+ | 마운트 시 즉시 리다이렉트 | `<Navigate>` | useEffect 불필요 |
674
+ | 프레임워크 외부 | `router.navigate()` | 어디서든 사용 가능 |
675
+ | 동적 파라미터 | 모두 가능 | 문맥에 따라 |
676
+ | 낙관적 pending UI | `<MatchRoute pending>` | 전환 중 스피너 |
79
677
 
80
- </options>
678
+ </comparison>