@0xsown/vibe-code-fe 1.0.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 (189) hide show
  1. package/bin/index.js +181 -0
  2. package/package.json +32 -0
  3. package/skills/claude-md-improver/SKILL.md +179 -0
  4. package/skills/claude-md-improver/references/quality-criteria.md +109 -0
  5. package/skills/claude-md-improver/references/templates.md +253 -0
  6. package/skills/claude-md-improver/references/update-guidelines.md +150 -0
  7. package/skills/find-skills/SKILL.md +133 -0
  8. package/skills/frontend-design/LICENSE.txt +177 -0
  9. package/skills/frontend-design/SKILL.md +42 -0
  10. package/skills/next-best-practices/SKILL.md +153 -0
  11. package/skills/next-best-practices/async-patterns.md +87 -0
  12. package/skills/next-best-practices/bundling.md +180 -0
  13. package/skills/next-best-practices/data-patterns.md +297 -0
  14. package/skills/next-best-practices/debug-tricks.md +105 -0
  15. package/skills/next-best-practices/directives.md +73 -0
  16. package/skills/next-best-practices/error-handling.md +227 -0
  17. package/skills/next-best-practices/file-conventions.md +140 -0
  18. package/skills/next-best-practices/font.md +245 -0
  19. package/skills/next-best-practices/functions.md +108 -0
  20. package/skills/next-best-practices/hydration-error.md +91 -0
  21. package/skills/next-best-practices/image.md +173 -0
  22. package/skills/next-best-practices/metadata.md +301 -0
  23. package/skills/next-best-practices/parallel-routes.md +287 -0
  24. package/skills/next-best-practices/route-handlers.md +146 -0
  25. package/skills/next-best-practices/rsc-boundaries.md +159 -0
  26. package/skills/next-best-practices/runtime-selection.md +39 -0
  27. package/skills/next-best-practices/scripts.md +141 -0
  28. package/skills/next-best-practices/self-hosting.md +371 -0
  29. package/skills/next-best-practices/suspense-boundaries.md +67 -0
  30. package/skills/next-cache-components/SKILL.md +411 -0
  31. package/skills/shadcn-ui/README.md +248 -0
  32. package/skills/shadcn-ui/SKILL.md +326 -0
  33. package/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
  34. package/skills/shadcn-ui/examples/data-table.tsx +313 -0
  35. package/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
  36. package/skills/shadcn-ui/resources/component-catalog.md +481 -0
  37. package/skills/shadcn-ui/resources/customization-guide.md +516 -0
  38. package/skills/shadcn-ui/resources/migration-guide.md +463 -0
  39. package/skills/shadcn-ui/resources/setup-guide.md +412 -0
  40. package/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
  41. package/skills/supabase-postgres-best-practices/AGENTS.md +68 -0
  42. package/skills/supabase-postgres-best-practices/CLAUDE.md +68 -0
  43. package/skills/supabase-postgres-best-practices/README.md +116 -0
  44. package/skills/supabase-postgres-best-practices/SKILL.md +64 -0
  45. package/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
  46. package/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
  47. package/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
  48. package/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
  49. package/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
  50. package/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
  51. package/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
  52. package/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
  53. package/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
  54. package/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
  55. package/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
  56. package/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
  57. package/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
  58. package/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
  59. package/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
  60. package/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
  61. package/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
  62. package/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
  63. package/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
  64. package/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
  65. package/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
  66. package/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
  67. package/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
  68. package/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
  69. package/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
  70. package/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
  71. package/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
  72. package/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
  73. package/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
  74. package/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
  75. package/skills/supabase-postgres-best-practices/references/security-rls-performance.md +57 -0
  76. package/skills/tailwind-design-system/SKILL.md +874 -0
  77. package/skills/vercel-composition-patterns/AGENTS.md +946 -0
  78. package/skills/vercel-composition-patterns/README.md +60 -0
  79. package/skills/vercel-composition-patterns/SKILL.md +89 -0
  80. package/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  81. package/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
  82. package/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  83. package/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
  84. package/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
  85. package/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
  86. package/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
  87. package/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
  88. package/skills/vercel-react-best-practices/AGENTS.md +2934 -0
  89. package/skills/vercel-react-best-practices/README.md +123 -0
  90. package/skills/vercel-react-best-practices/SKILL.md +136 -0
  91. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  92. package/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  93. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  94. package/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  95. package/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  96. package/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  97. package/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  98. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  99. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  100. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  101. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  102. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  103. package/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  104. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  105. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  106. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  107. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  108. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  109. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  110. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  111. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  112. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  113. package/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  114. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  115. package/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  116. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  117. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  118. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  119. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  120. package/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  121. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  122. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  123. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  124. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  125. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  126. package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  127. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  128. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  129. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  130. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  131. package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  132. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  133. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  134. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  135. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  136. package/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  137. package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  138. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  139. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  140. package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  141. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  142. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  143. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  144. package/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  145. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  146. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  147. package/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  148. package/skills/vercel-react-native-skills/AGENTS.md +2897 -0
  149. package/skills/vercel-react-native-skills/README.md +165 -0
  150. package/skills/vercel-react-native-skills/SKILL.md +121 -0
  151. package/skills/vercel-react-native-skills/rules/animation-derived-value.md +53 -0
  152. package/skills/vercel-react-native-skills/rules/animation-gesture-detector-press.md +95 -0
  153. package/skills/vercel-react-native-skills/rules/animation-gpu-properties.md +65 -0
  154. package/skills/vercel-react-native-skills/rules/design-system-compound-components.md +66 -0
  155. package/skills/vercel-react-native-skills/rules/fonts-config-plugin.md +71 -0
  156. package/skills/vercel-react-native-skills/rules/imports-design-system-folder.md +68 -0
  157. package/skills/vercel-react-native-skills/rules/js-hoist-intl.md +61 -0
  158. package/skills/vercel-react-native-skills/rules/list-performance-callbacks.md +44 -0
  159. package/skills/vercel-react-native-skills/rules/list-performance-function-references.md +132 -0
  160. package/skills/vercel-react-native-skills/rules/list-performance-images.md +53 -0
  161. package/skills/vercel-react-native-skills/rules/list-performance-inline-objects.md +97 -0
  162. package/skills/vercel-react-native-skills/rules/list-performance-item-expensive.md +94 -0
  163. package/skills/vercel-react-native-skills/rules/list-performance-item-memo.md +82 -0
  164. package/skills/vercel-react-native-skills/rules/list-performance-item-types.md +104 -0
  165. package/skills/vercel-react-native-skills/rules/list-performance-virtualize.md +67 -0
  166. package/skills/vercel-react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
  167. package/skills/vercel-react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
  168. package/skills/vercel-react-native-skills/rules/navigation-native-navigators.md +188 -0
  169. package/skills/vercel-react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
  170. package/skills/vercel-react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
  171. package/skills/vercel-react-native-skills/rules/react-state-dispatcher.md +91 -0
  172. package/skills/vercel-react-native-skills/rules/react-state-fallback.md +56 -0
  173. package/skills/vercel-react-native-skills/rules/react-state-minimize.md +65 -0
  174. package/skills/vercel-react-native-skills/rules/rendering-no-falsy-and.md +74 -0
  175. package/skills/vercel-react-native-skills/rules/rendering-text-in-text-component.md +36 -0
  176. package/skills/vercel-react-native-skills/rules/scroll-position-no-state.md +82 -0
  177. package/skills/vercel-react-native-skills/rules/state-ground-truth.md +80 -0
  178. package/skills/vercel-react-native-skills/rules/ui-expo-image.md +66 -0
  179. package/skills/vercel-react-native-skills/rules/ui-image-gallery.md +104 -0
  180. package/skills/vercel-react-native-skills/rules/ui-measure-views.md +78 -0
  181. package/skills/vercel-react-native-skills/rules/ui-menus.md +174 -0
  182. package/skills/vercel-react-native-skills/rules/ui-native-modals.md +77 -0
  183. package/skills/vercel-react-native-skills/rules/ui-pressable.md +61 -0
  184. package/skills/vercel-react-native-skills/rules/ui-safe-area-scroll.md +65 -0
  185. package/skills/vercel-react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
  186. package/skills/vercel-react-native-skills/rules/ui-styling.md +87 -0
  187. package/skills/web-design-guidelines/SKILL.md +39 -0
  188. package/templates/AGENTS.md +31 -0
  189. package/templates/CLAUDE.md +31 -0
@@ -0,0 +1,287 @@
1
+ # Parallel & Intercepting Routes
2
+
3
+ Parallel routes render multiple pages in the same layout. Intercepting routes show a different UI when navigating from within your app vs direct URL access. Together they enable modal patterns.
4
+
5
+ ## File Structure
6
+
7
+ ```
8
+ app/
9
+ ├── @modal/ # Parallel route slot
10
+ │ ├── default.tsx # Required! Returns null
11
+ │ ├── (.)photos/ # Intercepts /photos/*
12
+ │ │ └── [id]/
13
+ │ │ └── page.tsx # Modal content
14
+ │ └── [...]catchall/ # Optional: catch unmatched
15
+ │ └── page.tsx
16
+ ├── photos/
17
+ │ └── [id]/
18
+ │ └── page.tsx # Full page (direct access)
19
+ ├── layout.tsx # Renders both children and @modal
20
+ └── page.tsx
21
+ ```
22
+
23
+ ## Step 1: Root Layout with Slot
24
+
25
+ ```tsx
26
+ // app/layout.tsx
27
+ export default function RootLayout({
28
+ children,
29
+ modal,
30
+ }: {
31
+ children: React.ReactNode;
32
+ modal: React.ReactNode;
33
+ }) {
34
+ return (
35
+ <html>
36
+ <body>
37
+ {children}
38
+ {modal}
39
+ </body>
40
+ </html>
41
+ );
42
+ }
43
+ ```
44
+
45
+ ## Step 2: Default File (Critical!)
46
+
47
+ **Every parallel route slot MUST have a `default.tsx`** to prevent 404s on hard navigation.
48
+
49
+ ```tsx
50
+ // app/@modal/default.tsx
51
+ export default function Default() {
52
+ return null;
53
+ }
54
+ ```
55
+
56
+ Without this file, refreshing any page will 404 because Next.js can't determine what to render in the `@modal` slot.
57
+
58
+ ## Step 3: Intercepting Route (Modal)
59
+
60
+ The `(.)` prefix intercepts routes at the same level.
61
+
62
+ ```tsx
63
+ // app/@modal/(.)photos/[id]/page.tsx
64
+ import { Modal } from '@/components/modal';
65
+
66
+ export default async function PhotoModal({
67
+ params
68
+ }: {
69
+ params: Promise<{ id: string }>
70
+ }) {
71
+ const { id } = await params;
72
+ const photo = await getPhoto(id);
73
+
74
+ return (
75
+ <Modal>
76
+ <img src={photo.url} alt={photo.title} />
77
+ </Modal>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ## Step 4: Full Page (Direct Access)
83
+
84
+ ```tsx
85
+ // app/photos/[id]/page.tsx
86
+ export default async function PhotoPage({
87
+ params
88
+ }: {
89
+ params: Promise<{ id: string }>
90
+ }) {
91
+ const { id } = await params;
92
+ const photo = await getPhoto(id);
93
+
94
+ return (
95
+ <div className="full-page">
96
+ <img src={photo.url} alt={photo.title} />
97
+ <h1>{photo.title}</h1>
98
+ </div>
99
+ );
100
+ }
101
+ ```
102
+
103
+ ## Step 5: Modal Component with Correct Closing
104
+
105
+ **Critical: Use `router.back()` to close modals, NOT `router.push()` or `<Link>`.**
106
+
107
+ ```tsx
108
+ // components/modal.tsx
109
+ 'use client';
110
+
111
+ import { useRouter } from 'next/navigation';
112
+ import { useCallback, useEffect, useRef } from 'react';
113
+
114
+ export function Modal({ children }: { children: React.ReactNode }) {
115
+ const router = useRouter();
116
+ const overlayRef = useRef<HTMLDivElement>(null);
117
+
118
+ // Close on escape key
119
+ useEffect(() => {
120
+ function onKeyDown(e: KeyboardEvent) {
121
+ if (e.key === 'Escape') {
122
+ router.back(); // Correct
123
+ }
124
+ }
125
+ document.addEventListener('keydown', onKeyDown);
126
+ return () => document.removeEventListener('keydown', onKeyDown);
127
+ }, [router]);
128
+
129
+ // Close on overlay click
130
+ const handleOverlayClick = useCallback((e: React.MouseEvent) => {
131
+ if (e.target === overlayRef.current) {
132
+ router.back(); // Correct
133
+ }
134
+ }, [router]);
135
+
136
+ return (
137
+ <div
138
+ ref={overlayRef}
139
+ onClick={handleOverlayClick}
140
+ className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
141
+ >
142
+ <div className="bg-white rounded-lg p-6 max-w-2xl w-full mx-4">
143
+ <button
144
+ onClick={() => router.back()} // Correct!
145
+ className="absolute top-4 right-4"
146
+ >
147
+ Close
148
+ </button>
149
+ {children}
150
+ </div>
151
+ </div>
152
+ );
153
+ }
154
+ ```
155
+
156
+ ### Why NOT `router.push('/')` or `<Link href="/">`?
157
+
158
+ Using `push` or `Link` to "close" a modal:
159
+ 1. Adds a new history entry (back button shows modal again)
160
+ 2. Doesn't properly clear the intercepted route
161
+ 3. Can cause the modal to flash or persist unexpectedly
162
+
163
+ `router.back()` correctly:
164
+ 1. Removes the intercepted route from history
165
+ 2. Returns to the previous page
166
+ 3. Properly unmounts the modal
167
+
168
+ ## Route Matcher Reference
169
+
170
+ Matchers match **route segments**, not filesystem paths:
171
+
172
+ | Matcher | Matches | Example |
173
+ |---------|---------|---------|
174
+ | `(.)` | Same level | `@modal/(.)photos` intercepts `/photos` |
175
+ | `(..)` | One level up | `@modal/(..)settings` from `/dashboard/@modal` intercepts `/settings` |
176
+ | `(..)(..)` | Two levels up | Rarely used |
177
+ | `(...)` | From root | `@modal/(...)photos` intercepts `/photos` from anywhere |
178
+
179
+ **Common mistake**: Thinking `(..)` means "parent folder" - it means "parent route segment".
180
+
181
+ ## Handling Hard Navigation
182
+
183
+ When users directly visit `/photos/123` (bookmark, refresh, shared link):
184
+ - The intercepting route is bypassed
185
+ - The full `photos/[id]/page.tsx` renders
186
+ - Modal doesn't appear (expected behavior)
187
+
188
+ If you want the modal to appear on direct access too, you need additional logic:
189
+
190
+ ```tsx
191
+ // app/photos/[id]/page.tsx
192
+ import { Modal } from '@/components/modal';
193
+
194
+ export default async function PhotoPage({ params }) {
195
+ const { id } = await params;
196
+ const photo = await getPhoto(id);
197
+
198
+ // Option: Render as modal on direct access too
199
+ return (
200
+ <Modal>
201
+ <img src={photo.url} alt={photo.title} />
202
+ </Modal>
203
+ );
204
+ }
205
+ ```
206
+
207
+ ## Common Gotchas
208
+
209
+ ### 1. Missing `default.tsx` → 404 on Refresh
210
+
211
+ Every `@slot` folder needs a `default.tsx` that returns `null` (or appropriate content).
212
+
213
+ ### 2. Modal Persists After Navigation
214
+
215
+ You're using `router.push()` instead of `router.back()`.
216
+
217
+ ### 3. Nested Parallel Routes Need Defaults Too
218
+
219
+ If you have `@modal` inside a route group, each level needs its own `default.tsx`:
220
+
221
+ ```
222
+ app/
223
+ ├── (marketing)/
224
+ │ ├── @modal/
225
+ │ │ └── default.tsx # Needed!
226
+ │ └── layout.tsx
227
+ └── layout.tsx
228
+ ```
229
+
230
+ ### 4. Intercepted Route Shows Wrong Content
231
+
232
+ Check your matcher:
233
+ - `(.)photos` intercepts `/photos` from the same route level
234
+ - If your `@modal` is in `app/dashboard/@modal`, use `(.)photos` to intercept `/dashboard/photos`, not `/photos`
235
+
236
+ ### 5. TypeScript Errors with `params`
237
+
238
+ In Next.js 15+, `params` is a Promise:
239
+
240
+ ```tsx
241
+ // Correct
242
+ export default async function Page({ params }: { params: Promise<{ id: string }> }) {
243
+ const { id } = await params;
244
+ }
245
+ ```
246
+
247
+ ## Complete Example: Photo Gallery Modal
248
+
249
+ ```
250
+ app/
251
+ ├── @modal/
252
+ │ ├── default.tsx
253
+ │ └── (.)photos/
254
+ │ └── [id]/
255
+ │ └── page.tsx
256
+ ├── photos/
257
+ │ ├── page.tsx # Gallery grid
258
+ │ └── [id]/
259
+ │ └── page.tsx # Full photo page
260
+ ├── layout.tsx
261
+ └── page.tsx
262
+ ```
263
+
264
+ Links in the gallery:
265
+
266
+ ```tsx
267
+ // app/photos/page.tsx
268
+ import Link from 'next/link';
269
+
270
+ export default async function Gallery() {
271
+ const photos = await getPhotos();
272
+
273
+ return (
274
+ <div className="grid grid-cols-3 gap-4">
275
+ {photos.map(photo => (
276
+ <Link key={photo.id} href={`/photos/${photo.id}`}>
277
+ <img src={photo.thumbnail} alt={photo.title} />
278
+ </Link>
279
+ ))}
280
+ </div>
281
+ );
282
+ }
283
+ ```
284
+
285
+ Clicking a photo → Modal opens (intercepted)
286
+ Direct URL → Full page renders
287
+ Refresh while modal open → Full page renders
@@ -0,0 +1,146 @@
1
+ # Route Handlers
2
+
3
+ Create API endpoints with `route.ts` files.
4
+
5
+ ## Basic Usage
6
+
7
+ ```tsx
8
+ // app/api/users/route.ts
9
+ export async function GET() {
10
+ const users = await getUsers()
11
+ return Response.json(users)
12
+ }
13
+
14
+ export async function POST(request: Request) {
15
+ const body = await request.json()
16
+ const user = await createUser(body)
17
+ return Response.json(user, { status: 201 })
18
+ }
19
+ ```
20
+
21
+ ## Supported Methods
22
+
23
+ `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`
24
+
25
+ ## GET Handler Conflicts with page.tsx
26
+
27
+ **A `route.ts` and `page.tsx` cannot coexist in the same folder.**
28
+
29
+ ```
30
+ app/
31
+ ├── api/
32
+ │ └── users/
33
+ │ └── route.ts # /api/users
34
+ └── users/
35
+ ├── page.tsx # /users (page)
36
+ └── route.ts # Warning: Conflicts with page.tsx!
37
+ ```
38
+
39
+ If you need both a page and an API at the same path, use different paths:
40
+
41
+ ```
42
+ app/
43
+ ├── users/
44
+ │ └── page.tsx # /users (page)
45
+ └── api/
46
+ └── users/
47
+ └── route.ts # /api/users (API)
48
+ ```
49
+
50
+ ## Environment Behavior
51
+
52
+ Route handlers run in a **Server Component-like environment**:
53
+
54
+ - Yes: Can use `async/await`
55
+ - Yes: Can access `cookies()`, `headers()`
56
+ - Yes: Can use Node.js APIs
57
+ - No: Cannot use React hooks
58
+ - No: Cannot use React DOM APIs
59
+ - No: Cannot use browser APIs
60
+
61
+ ```tsx
62
+ // Bad: This won't work - no React DOM in route handlers
63
+ import { renderToString } from 'react-dom/server'
64
+
65
+ export async function GET() {
66
+ const html = renderToString(<Component />) // Error!
67
+ return new Response(html)
68
+ }
69
+ ```
70
+
71
+ ## Dynamic Route Handlers
72
+
73
+ ```tsx
74
+ // app/api/users/[id]/route.ts
75
+ export async function GET(
76
+ request: Request,
77
+ { params }: { params: Promise<{ id: string }> }
78
+ ) {
79
+ const { id } = await params
80
+ const user = await getUser(id)
81
+
82
+ if (!user) {
83
+ return Response.json({ error: 'Not found' }, { status: 404 })
84
+ }
85
+
86
+ return Response.json(user)
87
+ }
88
+ ```
89
+
90
+ ## Request Helpers
91
+
92
+ ```tsx
93
+ export async function GET(request: Request) {
94
+ // URL and search params
95
+ const { searchParams } = new URL(request.url)
96
+ const query = searchParams.get('q')
97
+
98
+ // Headers
99
+ const authHeader = request.headers.get('authorization')
100
+
101
+ // Cookies (Next.js helper)
102
+ const cookieStore = await cookies()
103
+ const token = cookieStore.get('token')
104
+
105
+ return Response.json({ query, token })
106
+ }
107
+ ```
108
+
109
+ ## Response Helpers
110
+
111
+ ```tsx
112
+ // JSON response
113
+ return Response.json({ data })
114
+
115
+ // With status
116
+ return Response.json({ error: 'Not found' }, { status: 404 })
117
+
118
+ // With headers
119
+ return Response.json(data, {
120
+ headers: {
121
+ 'Cache-Control': 'max-age=3600',
122
+ },
123
+ })
124
+
125
+ // Redirect
126
+ return Response.redirect(new URL('/login', request.url))
127
+
128
+ // Stream
129
+ return new Response(stream, {
130
+ headers: { 'Content-Type': 'text/event-stream' },
131
+ })
132
+ ```
133
+
134
+ ## When to Use Route Handlers vs Server Actions
135
+
136
+ | Use Case | Route Handlers | Server Actions |
137
+ |----------|----------------|----------------|
138
+ | Form submissions | No | Yes |
139
+ | Data mutations from UI | No | Yes |
140
+ | Third-party webhooks | Yes | No |
141
+ | External API consumption | Yes | No |
142
+ | Public REST API | Yes | No |
143
+ | File uploads | Both work | Both work |
144
+
145
+ **Prefer Server Actions** for mutations triggered from your UI.
146
+ **Use Route Handlers** for external integrations and public APIs.
@@ -0,0 +1,159 @@
1
+ # RSC Boundaries
2
+
3
+ Detect and prevent invalid patterns when crossing Server/Client component boundaries.
4
+
5
+ ## Detection Rules
6
+
7
+ ### 1. Async Client Components Are Invalid
8
+
9
+ Client components **cannot** be async functions. Only Server Components can be async.
10
+
11
+ **Detect:** File has `'use client'` AND component is `async function` or returns `Promise`
12
+
13
+ ```tsx
14
+ // Bad: async client component
15
+ 'use client'
16
+ export default async function UserProfile() {
17
+ const user = await getUser() // Cannot await in client component
18
+ return <div>{user.name}</div>
19
+ }
20
+
21
+ // Good: Remove async, fetch data in parent server component
22
+ // page.tsx (server component - no 'use client')
23
+ export default async function Page() {
24
+ const user = await getUser()
25
+ return <UserProfile user={user} />
26
+ }
27
+
28
+ // UserProfile.tsx (client component)
29
+ 'use client'
30
+ export function UserProfile({ user }: { user: User }) {
31
+ return <div>{user.name}</div>
32
+ }
33
+ ```
34
+
35
+ ```tsx
36
+ // Bad: async arrow function client component
37
+ 'use client'
38
+ const Dashboard = async () => {
39
+ const data = await fetchDashboard()
40
+ return <div>{data}</div>
41
+ }
42
+
43
+ // Good: Fetch in server component, pass data down
44
+ ```
45
+
46
+ ### 2. Non-Serializable Props to Client Components
47
+
48
+ Props passed from Server → Client must be JSON-serializable.
49
+
50
+ **Detect:** Server component passes these to a client component:
51
+ - Functions (except Server Actions with `'use server'`)
52
+ - `Date` objects
53
+ - `Map`, `Set`, `WeakMap`, `WeakSet`
54
+ - Class instances
55
+ - `Symbol` (unless globally registered)
56
+ - Circular references
57
+
58
+ ```tsx
59
+ // Bad: Function prop
60
+ // page.tsx (server)
61
+ export default function Page() {
62
+ const handleClick = () => console.log('clicked')
63
+ return <ClientButton onClick={handleClick} />
64
+ }
65
+
66
+ // Good: Define function inside client component
67
+ // ClientButton.tsx
68
+ 'use client'
69
+ export function ClientButton() {
70
+ const handleClick = () => console.log('clicked')
71
+ return <button onClick={handleClick}>Click</button>
72
+ }
73
+ ```
74
+
75
+ ```tsx
76
+ // Bad: Date object (silently becomes string, then crashes)
77
+ // page.tsx (server)
78
+ export default async function Page() {
79
+ const post = await getPost()
80
+ return <PostCard createdAt={post.createdAt} /> // Date object
81
+ }
82
+
83
+ // PostCard.tsx (client) - will crash on .getFullYear()
84
+ 'use client'
85
+ export function PostCard({ createdAt }: { createdAt: Date }) {
86
+ return <span>{createdAt.getFullYear()}</span> // Runtime error!
87
+ }
88
+
89
+ // Good: Serialize to string on server
90
+ // page.tsx (server)
91
+ export default async function Page() {
92
+ const post = await getPost()
93
+ return <PostCard createdAt={post.createdAt.toISOString()} />
94
+ }
95
+
96
+ // PostCard.tsx (client)
97
+ 'use client'
98
+ export function PostCard({ createdAt }: { createdAt: string }) {
99
+ const date = new Date(createdAt)
100
+ return <span>{date.getFullYear()}</span>
101
+ }
102
+ ```
103
+
104
+ ```tsx
105
+ // Bad: Class instance
106
+ const user = new UserModel(data)
107
+ <ClientProfile user={user} /> // Methods will be stripped
108
+
109
+ // Good: Pass plain object
110
+ const user = await getUser()
111
+ <ClientProfile user={{ id: user.id, name: user.name }} />
112
+ ```
113
+
114
+ ```tsx
115
+ // Bad: Map/Set
116
+ <ClientComponent items={new Map([['a', 1]])} />
117
+
118
+ // Good: Convert to array/object
119
+ <ClientComponent items={Object.fromEntries(map)} />
120
+ <ClientComponent items={Array.from(set)} />
121
+ ```
122
+
123
+ ### 3. Server Actions Are the Exception
124
+
125
+ Functions marked with `'use server'` CAN be passed to client components.
126
+
127
+ ```tsx
128
+ // Valid: Server Action can be passed
129
+ // actions.ts
130
+ 'use server'
131
+ export async function submitForm(formData: FormData) {
132
+ // server-side logic
133
+ }
134
+
135
+ // page.tsx (server)
136
+ import { submitForm } from './actions'
137
+ export default function Page() {
138
+ return <ClientForm onSubmit={submitForm} /> // OK!
139
+ }
140
+
141
+ // ClientForm.tsx (client)
142
+ 'use client'
143
+ export function ClientForm({ onSubmit }: { onSubmit: (data: FormData) => Promise<void> }) {
144
+ return <form action={onSubmit}>...</form>
145
+ }
146
+ ```
147
+
148
+ ## Quick Reference
149
+
150
+ | Pattern | Valid? | Fix |
151
+ |---------|--------|-----|
152
+ | `'use client'` + `async function` | No | Fetch in server parent, pass data |
153
+ | Pass `() => {}` to client | No | Define in client or use server action |
154
+ | Pass `new Date()` to client | No | Use `.toISOString()` |
155
+ | Pass `new Map()` to client | No | Convert to object/array |
156
+ | Pass class instance to client | No | Pass plain object |
157
+ | Pass server action to client | Yes | - |
158
+ | Pass `string/number/boolean` | Yes | - |
159
+ | Pass plain object/array | Yes | - |
@@ -0,0 +1,39 @@
1
+ # Runtime Selection
2
+
3
+ ## Use Node.js Runtime by Default
4
+
5
+ Use the default Node.js runtime for new routes and pages. Only use Edge runtime if the project already uses it or there's a specific requirement.
6
+
7
+ ```tsx
8
+ // Good: Default - no runtime config needed (uses Node.js)
9
+ export default function Page() { ... }
10
+
11
+ // Caution: Only if already used in project or specifically required
12
+ export const runtime = 'edge'
13
+ ```
14
+
15
+ ## When to Use Each
16
+
17
+ ### Node.js Runtime (Default)
18
+
19
+ - Full Node.js API support
20
+ - File system access (`fs`)
21
+ - Full `crypto` support
22
+ - Database connections
23
+ - Most npm packages work
24
+
25
+ ### Edge Runtime
26
+
27
+ - Only for specific edge-location latency requirements
28
+ - Limited API (no `fs`, limited `crypto`)
29
+ - Smaller cold start
30
+ - Geographic distribution needs
31
+
32
+ ## Detection
33
+
34
+ **Before adding `runtime = 'edge'`**, check:
35
+ 1. Does the project already use Edge runtime?
36
+ 2. Is there a specific latency requirement?
37
+ 3. Are all dependencies Edge-compatible?
38
+
39
+ If unsure, use Node.js runtime.