@jgamaraalv/ts-dev-kit 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 (117) hide show
  1. package/.claude-plugin/marketplace.json +24 -0
  2. package/.claude-plugin/plugin.json +24 -0
  3. package/CHANGELOG.md +24 -0
  4. package/LICENSE +21 -0
  5. package/README.md +128 -0
  6. package/agents/accessibility-pro.md +139 -0
  7. package/agents/api-builder.md +110 -0
  8. package/agents/code-reviewer.md +190 -0
  9. package/agents/database-expert.md +138 -0
  10. package/agents/debugger.md +241 -0
  11. package/agents/docker-expert.md +51 -0
  12. package/agents/multi-agent-coordinator.md +378 -0
  13. package/agents/nextjs-expert.md +136 -0
  14. package/agents/performance-engineer.md +138 -0
  15. package/agents/playwright-expert.md +126 -0
  16. package/agents/react-specialist.md +97 -0
  17. package/agents/security-scanner.md +105 -0
  18. package/agents/test-generator.md +221 -0
  19. package/agents/typescript-pro.md +253 -0
  20. package/agents/ux-optimizer.md +93 -0
  21. package/docs/rules/orchestration.md.template +126 -0
  22. package/package.json +28 -0
  23. package/skills/bullmq/SKILL.md +225 -0
  24. package/skills/bullmq/references/flows-and-schedulers.md +186 -0
  25. package/skills/bullmq/references/job-types-and-options.md +163 -0
  26. package/skills/bullmq/references/patterns.md +273 -0
  27. package/skills/bullmq/references/production.md +308 -0
  28. package/skills/composition-patterns/SKILL.md +58 -0
  29. package/skills/composition-patterns/references/architecture-avoid-boolean-props.md +87 -0
  30. package/skills/composition-patterns/references/architecture-compound-components.md +107 -0
  31. package/skills/composition-patterns/references/patterns-children-over-render-props.md +77 -0
  32. package/skills/composition-patterns/references/patterns-explicit-variants.md +87 -0
  33. package/skills/composition-patterns/references/react19-no-forwardref.md +37 -0
  34. package/skills/composition-patterns/references/state-context-interface.md +194 -0
  35. package/skills/composition-patterns/references/state-decouple-implementation.md +96 -0
  36. package/skills/composition-patterns/references/state-lift-state.md +126 -0
  37. package/skills/conventional-commits/SKILL.md +148 -0
  38. package/skills/docker/SKILL.md +55 -0
  39. package/skills/docker/references/compose-configs.md +95 -0
  40. package/skills/docker/references/monorepo-dockerfile.md +111 -0
  41. package/skills/drizzle-pg/SKILL.md +202 -0
  42. package/skills/drizzle-pg/references/advanced.md +299 -0
  43. package/skills/drizzle-pg/references/migrations.md +214 -0
  44. package/skills/drizzle-pg/references/queries.md +321 -0
  45. package/skills/drizzle-pg/references/relations.md +272 -0
  46. package/skills/drizzle-pg/references/schema-pg.md +256 -0
  47. package/skills/drizzle-pg/references/sql-operator.md +215 -0
  48. package/skills/fastify-best-practices/SKILL.md +143 -0
  49. package/skills/fastify-best-practices/references/hooks-and-lifecycle.md +122 -0
  50. package/skills/fastify-best-practices/references/plugins-and-encapsulation.md +137 -0
  51. package/skills/fastify-best-practices/references/request-reply-errors.md +189 -0
  52. package/skills/fastify-best-practices/references/routes-and-handlers.md +134 -0
  53. package/skills/fastify-best-practices/references/server-and-options.md +127 -0
  54. package/skills/fastify-best-practices/references/typescript-and-logging.md +223 -0
  55. package/skills/fastify-best-practices/references/validation-and-serialization.md +190 -0
  56. package/skills/ioredis/SKILL.md +51 -0
  57. package/skills/ioredis/references/advanced-patterns.md +312 -0
  58. package/skills/ioredis/references/cluster-sentinel.md +280 -0
  59. package/skills/ioredis/references/connection-options.md +187 -0
  60. package/skills/ioredis/references/core-api.md +179 -0
  61. package/skills/nextjs-best-practices/SKILL.md +194 -0
  62. package/skills/nextjs-best-practices/references/async-patterns.md +84 -0
  63. package/skills/nextjs-best-practices/references/bundling.md +192 -0
  64. package/skills/nextjs-best-practices/references/data-patterns.md +310 -0
  65. package/skills/nextjs-best-practices/references/debug-tricks.md +127 -0
  66. package/skills/nextjs-best-practices/references/directives.md +74 -0
  67. package/skills/nextjs-best-practices/references/error-handling.md +237 -0
  68. package/skills/nextjs-best-practices/references/file-conventions.md +152 -0
  69. package/skills/nextjs-best-practices/references/font.md +175 -0
  70. package/skills/nextjs-best-practices/references/functions.md +116 -0
  71. package/skills/nextjs-best-practices/references/hydration-error.md +86 -0
  72. package/skills/nextjs-best-practices/references/image.md +184 -0
  73. package/skills/nextjs-best-practices/references/metadata.md +305 -0
  74. package/skills/nextjs-best-practices/references/parallel-routes.md +299 -0
  75. package/skills/nextjs-best-practices/references/route-handlers.md +154 -0
  76. package/skills/nextjs-best-practices/references/rsc-boundaries.md +168 -0
  77. package/skills/nextjs-best-practices/references/runtime-selection.md +40 -0
  78. package/skills/nextjs-best-practices/references/scripts.md +148 -0
  79. package/skills/nextjs-best-practices/references/self-hosting.md +210 -0
  80. package/skills/nextjs-best-practices/references/suspense-boundaries.md +67 -0
  81. package/skills/owasp-security-review/SKILL.md +98 -0
  82. package/skills/owasp-security-review/references/a01-broken-access-control.md +78 -0
  83. package/skills/owasp-security-review/references/a02-security-misconfiguration.md +81 -0
  84. package/skills/owasp-security-review/references/a03-supply-chain-failures.md +65 -0
  85. package/skills/owasp-security-review/references/a04-cryptographic-failures.md +82 -0
  86. package/skills/owasp-security-review/references/a05-injection.md +106 -0
  87. package/skills/owasp-security-review/references/a06-insecure-design.md +76 -0
  88. package/skills/owasp-security-review/references/a07-authentication-failures.md +83 -0
  89. package/skills/owasp-security-review/references/a08-integrity-failures.md +72 -0
  90. package/skills/owasp-security-review/references/a09-logging-alerting-failures.md +76 -0
  91. package/skills/owasp-security-review/references/a10-exceptional-conditions.md +131 -0
  92. package/skills/postgresql/SKILL.md +50 -0
  93. package/skills/postgresql/references/ddl-schema.md +300 -0
  94. package/skills/postgresql/references/indexes.md +257 -0
  95. package/skills/postgresql/references/jsonb.md +261 -0
  96. package/skills/postgresql/references/performance.md +291 -0
  97. package/skills/postgresql/references/psql-cli.md +153 -0
  98. package/skills/postgresql/references/queries.md +287 -0
  99. package/skills/postgresql/references/transactions.md +280 -0
  100. package/skills/react-best-practices/SKILL.md +110 -0
  101. package/skills/react-best-practices/references/advanced-patterns.md +91 -0
  102. package/skills/react-best-practices/references/async-patterns.md +233 -0
  103. package/skills/react-best-practices/references/bundle-optimization.md +201 -0
  104. package/skills/react-best-practices/references/client-patterns.md +178 -0
  105. package/skills/react-best-practices/references/js-performance.md +210 -0
  106. package/skills/react-best-practices/references/rendering-performance.md +209 -0
  107. package/skills/react-best-practices/references/rerender-optimization.md +316 -0
  108. package/skills/react-best-practices/references/server-performance.md +274 -0
  109. package/skills/service-worker/SKILL.md +195 -0
  110. package/skills/service-worker/references/api-reference.md +114 -0
  111. package/skills/service-worker/references/caching-strategies.md +202 -0
  112. package/skills/service-worker/references/push-and-sync.md +261 -0
  113. package/skills/typescript-conventions/SKILL.md +51 -0
  114. package/skills/ui-ux-guidelines/SKILL.md +105 -0
  115. package/skills/ui-ux-guidelines/references/accessibility-and-interaction.md +74 -0
  116. package/skills/ui-ux-guidelines/references/forms-content-checklist.md +126 -0
  117. package/skills/ui-ux-guidelines/references/layout-typography-animation.md +95 -0
@@ -0,0 +1,237 @@
1
+ # Error Handling
2
+
3
+ Handle errors gracefully in Next.js applications.
4
+
5
+ Reference: https://nextjs.org/docs/app/getting-started/error-handling
6
+
7
+ ## Table of Contents
8
+
9
+ - [Error Boundaries](#error-boundaries)
10
+ - [Server Actions: Navigation API Gotcha](#server-actions-navigation-api-gotcha)
11
+ - [Redirects](#redirects)
12
+ - [Auth Errors](#auth-errors)
13
+ - [Not Found](#not-found)
14
+ - [Error Hierarchy](#error-hierarchy)
15
+
16
+ ## Error Boundaries
17
+
18
+ ### `error.tsx`
19
+
20
+ Catches errors in a route segment and its children:
21
+
22
+ ```tsx
23
+ "use client";
24
+
25
+ export default function Error({
26
+ error,
27
+ reset,
28
+ }: {
29
+ error: Error & { digest?: string };
30
+ reset: () => void;
31
+ }) {
32
+ return (
33
+ <div>
34
+ <h2>Something went wrong!</h2>
35
+ <button onClick={() => reset()}>Try again</button>
36
+ </div>
37
+ );
38
+ }
39
+ ```
40
+
41
+ **Important:** `error.tsx` must be a Client Component.
42
+
43
+ ### `global-error.tsx`
44
+
45
+ Catches errors in root layout:
46
+
47
+ ```tsx
48
+ "use client";
49
+
50
+ export default function GlobalError({
51
+ error,
52
+ reset,
53
+ }: {
54
+ error: Error & { digest?: string };
55
+ reset: () => void;
56
+ }) {
57
+ return (
58
+ <html>
59
+ <body>
60
+ <h2>Something went wrong!</h2>
61
+ <button onClick={() => reset()}>Try again</button>
62
+ </body>
63
+ </html>
64
+ );
65
+ }
66
+ ```
67
+
68
+ **Important:** Must include `<html>` and `<body>` tags.
69
+
70
+ ## Server Actions: Navigation API Gotcha
71
+
72
+ **Do NOT wrap navigation APIs in try-catch.** They throw special errors that Next.js handles internally.
73
+
74
+ Reference: https://nextjs.org/docs/app/api-reference/functions/redirect#behavior
75
+
76
+ ```tsx
77
+ 'use server'
78
+
79
+ import { redirect } from 'next/navigation'
80
+ import { notFound } from 'next/navigation'
81
+
82
+ // Bad: try-catch catches the navigation "error"
83
+ async function createPost(formData: FormData) {
84
+ try {
85
+ const post = await db.post.create({ ... })
86
+ redirect(`/posts/${post.id}`) // This throws!
87
+ } catch (error) {
88
+ // redirect() throw is caught here - navigation fails!
89
+ return { error: 'Failed to create post' }
90
+ }
91
+ }
92
+
93
+ // Good: Call navigation APIs outside try-catch
94
+ async function createPost(formData: FormData) {
95
+ let post
96
+ try {
97
+ post = await db.post.create({ ... })
98
+ } catch (error) {
99
+ return { error: 'Failed to create post' }
100
+ }
101
+ redirect(`/posts/${post.id}`) // Outside try-catch
102
+ }
103
+
104
+ // Good: Re-throw navigation errors
105
+ async function createPost(formData: FormData) {
106
+ try {
107
+ const post = await db.post.create({ ... })
108
+ redirect(`/posts/${post.id}`)
109
+ } catch (error) {
110
+ if (error instanceof Error && error.message === 'NEXT_REDIRECT') {
111
+ throw error // Re-throw navigation errors
112
+ }
113
+ return { error: 'Failed to create post' }
114
+ }
115
+ }
116
+ ```
117
+
118
+ Same applies to:
119
+
120
+ - `redirect()` - 307 temporary redirect
121
+ - `permanentRedirect()` - 308 permanent redirect
122
+ - `notFound()` - 404 not found
123
+ - `forbidden()` - 403 forbidden
124
+ - `unauthorized()` - 401 unauthorized
125
+
126
+ Use `unstable_rethrow()` to re-throw these errors in catch blocks:
127
+
128
+ ```tsx
129
+ import { unstable_rethrow } from "next/navigation";
130
+
131
+ async function action() {
132
+ try {
133
+ // ...
134
+ redirect("/success");
135
+ } catch (error) {
136
+ unstable_rethrow(error); // Re-throws Next.js internal errors
137
+ return { error: "Something went wrong" };
138
+ }
139
+ }
140
+ ```
141
+
142
+ ## Redirects
143
+
144
+ ```tsx
145
+ import { redirect, permanentRedirect } from "next/navigation";
146
+
147
+ // 307 Temporary - use for most cases
148
+ redirect("/new-path");
149
+
150
+ // 308 Permanent - use for URL migrations (cached by browsers)
151
+ permanentRedirect("/new-url");
152
+ ```
153
+
154
+ ## Auth Errors
155
+
156
+ Trigger auth-related error pages:
157
+
158
+ ```tsx
159
+ import { forbidden, unauthorized } from "next/navigation";
160
+
161
+ async function Page() {
162
+ const session = await getSession();
163
+
164
+ if (!session) {
165
+ unauthorized(); // Renders unauthorized.tsx (401)
166
+ }
167
+
168
+ if (!session.hasAccess) {
169
+ forbidden(); // Renders forbidden.tsx (403)
170
+ }
171
+
172
+ return <Dashboard />;
173
+ }
174
+ ```
175
+
176
+ Create corresponding error pages:
177
+
178
+ ```tsx
179
+ // app/forbidden.tsx
180
+ export default function Forbidden() {
181
+ return <div>You don't have access to this resource</div>;
182
+ }
183
+
184
+ // app/unauthorized.tsx
185
+ export default function Unauthorized() {
186
+ return <div>Please log in to continue</div>;
187
+ }
188
+ ```
189
+
190
+ ## Not Found
191
+
192
+ ### `not-found.tsx`
193
+
194
+ Custom 404 page for a route segment:
195
+
196
+ ```tsx
197
+ export default function NotFound() {
198
+ return (
199
+ <div>
200
+ <h2>Not Found</h2>
201
+ <p>Could not find the requested resource</p>
202
+ </div>
203
+ );
204
+ }
205
+ ```
206
+
207
+ ### Triggering Not Found
208
+
209
+ ```tsx
210
+ import { notFound } from "next/navigation";
211
+
212
+ export default async function Page({ params }: { params: Promise<{ id: string }> }) {
213
+ const { id } = await params;
214
+ const post = await getPost(id);
215
+
216
+ if (!post) {
217
+ notFound(); // Renders closest not-found.tsx
218
+ }
219
+
220
+ return <div>{post.title}</div>;
221
+ }
222
+ ```
223
+
224
+ ## Error Hierarchy
225
+
226
+ Errors bubble up to the nearest error boundary:
227
+
228
+ ```
229
+ app/
230
+ ├── error.tsx # Catches errors from all children
231
+ ├── blog/
232
+ │ ├── error.tsx # Catches errors in /blog/*
233
+ │ └── [slug]/
234
+ │ ├── error.tsx # Catches errors in /blog/[slug]
235
+ │ └── page.tsx
236
+ └── layout.tsx # Errors here go to global-error.tsx
237
+ ```
@@ -0,0 +1,152 @@
1
+ # File Conventions
2
+
3
+ Next.js App Router uses file-based routing with special file conventions.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Project Structure](#project-structure)
8
+ - [Special Files](#special-files)
9
+ - [Route Segments](#route-segments)
10
+ - [Parallel Routes](#parallel-routes)
11
+ - [Intercepting Routes](#intercepting-routes)
12
+ - [Private Folders](#private-folders)
13
+ - [Middleware / Proxy](#middleware--proxy)
14
+ - [File Conventions Reference](#file-conventions-reference)
15
+
16
+ ## Project Structure
17
+
18
+ Reference: https://nextjs.org/docs/app/getting-started/project-structure
19
+
20
+ ```
21
+ app/
22
+ ├── layout.tsx # Root layout (required)
23
+ ├── page.tsx # Home page (/)
24
+ ├── loading.tsx # Loading UI
25
+ ├── error.tsx # Error UI
26
+ ├── not-found.tsx # 404 UI
27
+ ├── global-error.tsx # Global error UI
28
+ ├── route.ts # API endpoint
29
+ ├── template.tsx # Re-rendered layout
30
+ ├── default.tsx # Parallel route fallback
31
+ ├── blog/
32
+ │ ├── page.tsx # /blog
33
+ │ └── [slug]/
34
+ │ └── page.tsx # /blog/:slug
35
+ └── (group)/ # Route group (no URL impact)
36
+ └── page.tsx
37
+ ```
38
+
39
+ ## Special Files
40
+
41
+ | File | Purpose |
42
+ | --------------- | ---------------------------------------- |
43
+ | `page.tsx` | UI for a route segment |
44
+ | `layout.tsx` | Shared UI for segment and children |
45
+ | `loading.tsx` | Loading UI (Suspense boundary) |
46
+ | `error.tsx` | Error UI (Error boundary) |
47
+ | `not-found.tsx` | 404 UI |
48
+ | `route.ts` | API endpoint |
49
+ | `template.tsx` | Like layout but re-renders on navigation |
50
+ | `default.tsx` | Fallback for parallel routes |
51
+
52
+ ## Route Segments
53
+
54
+ ```
55
+ app/
56
+ ├── blog/ # Static segment: /blog
57
+ ├── [slug]/ # Dynamic segment: /:slug
58
+ ├── [...slug]/ # Catch-all: /a/b/c
59
+ ├── [[...slug]]/ # Optional catch-all: / or /a/b/c
60
+ └── (marketing)/ # Route group (ignored in URL)
61
+ ```
62
+
63
+ ## Parallel Routes
64
+
65
+ ```
66
+ app/
67
+ ├── @analytics/
68
+ │ └── page.tsx
69
+ ├── @sidebar/
70
+ │ └── page.tsx
71
+ └── layout.tsx # Receives { analytics, sidebar } as props
72
+ ```
73
+
74
+ ## Intercepting Routes
75
+
76
+ ```
77
+ app/
78
+ ├── feed/
79
+ │ └── page.tsx
80
+ ├── @modal/
81
+ │ └── (.)photo/[id]/ # Intercepts /photo/[id] from /feed
82
+ │ └── page.tsx
83
+ └── photo/[id]/
84
+ └── page.tsx
85
+ ```
86
+
87
+ Conventions:
88
+
89
+ - `(.)` - same level
90
+ - `(..)` - one level up
91
+ - `(..)(..)` - two levels up
92
+ - `(...)` - from root
93
+
94
+ ## Private Folders
95
+
96
+ ```
97
+ app/
98
+ ├── _components/ # Private folder (not a route)
99
+ │ └── Button.tsx
100
+ └── page.tsx
101
+ ```
102
+
103
+ Prefix with `_` to exclude from routing.
104
+
105
+ ## Middleware / Proxy
106
+
107
+ ### Next.js 14-15: `middleware.ts`
108
+
109
+ ```ts
110
+ // middleware.ts (root of project)
111
+ import { NextResponse } from "next/server";
112
+ import type { NextRequest } from "next/server";
113
+
114
+ export function middleware(request: NextRequest) {
115
+ // Auth, redirects, rewrites, etc.
116
+ return NextResponse.next();
117
+ }
118
+
119
+ export const config = {
120
+ matcher: ["/dashboard/:path*", "/api/:path*"],
121
+ };
122
+ ```
123
+
124
+ ### Next.js 16+: `proxy.ts`
125
+
126
+ Renamed for clarity - same capabilities, different names:
127
+
128
+ ```ts
129
+ // proxy.ts (root of project)
130
+ import { NextResponse } from "next/server";
131
+ import type { NextRequest } from "next/server";
132
+
133
+ export function proxy(request: NextRequest) {
134
+ // Same logic as middleware
135
+ return NextResponse.next();
136
+ }
137
+
138
+ export const proxyConfig = {
139
+ matcher: ["/dashboard/:path*", "/api/:path*"],
140
+ };
141
+ ```
142
+
143
+ | Version | File | Export | Config |
144
+ | ------- | --------------- | -------------- | ------------- |
145
+ | v14-15 | `middleware.ts` | `middleware()` | `config` |
146
+ | v16+ | `proxy.ts` | `proxy()` | `proxyConfig` |
147
+
148
+ **Migration**: Run `npx @next/codemod@latest upgrade` to auto-rename.
149
+
150
+ ## File Conventions Reference
151
+
152
+ Reference: https://nextjs.org/docs/app/api-reference/file-conventions
@@ -0,0 +1,175 @@
1
+ # Font Optimization
2
+
3
+ Use `next/font` for automatic font optimization with zero layout shift.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Multiple Fonts with CSS Variables](#multiple-fonts-with-css-variables)
8
+ - [Local Fonts](#local-fonts)
9
+ - [Tailwind CSS v4 Integration](#tailwind-css-v4-integration)
10
+ - [Display Strategy](#display-strategy)
11
+ - [Common Mistakes](#common-mistakes)
12
+ - [Font in Specific Components](#font-in-specific-components)
13
+
14
+ ## Multiple Fonts with CSS Variables
15
+
16
+ ```tsx
17
+ import { Inter, Roboto_Mono } from "next/font/google";
18
+
19
+ const inter = Inter({
20
+ subsets: ["latin"],
21
+ variable: "--font-inter",
22
+ });
23
+
24
+ const robotoMono = Roboto_Mono({
25
+ subsets: ["latin"],
26
+ variable: "--font-roboto-mono",
27
+ });
28
+
29
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
30
+ return (
31
+ <html lang="en" className={`${inter.variable} ${robotoMono.variable}`}>
32
+ <body>{children}</body>
33
+ </html>
34
+ );
35
+ }
36
+ ```
37
+
38
+ Use in CSS:
39
+
40
+ ```css
41
+ body {
42
+ font-family: var(--font-inter);
43
+ }
44
+
45
+ code {
46
+ font-family: var(--font-roboto-mono);
47
+ }
48
+ ```
49
+
50
+ ## Local Fonts
51
+
52
+ ```tsx
53
+ import localFont from "next/font/local";
54
+
55
+ // Single file
56
+ const myFont = localFont({
57
+ src: "./fonts/MyFont.woff2",
58
+ });
59
+
60
+ // Multiple files for different weights
61
+ const myFont = localFont({
62
+ src: [
63
+ {
64
+ path: "./fonts/MyFont-Regular.woff2",
65
+ weight: "400",
66
+ style: "normal",
67
+ },
68
+ {
69
+ path: "./fonts/MyFont-Bold.woff2",
70
+ weight: "700",
71
+ style: "normal",
72
+ },
73
+ ],
74
+ });
75
+
76
+ // Variable font with CSS variable
77
+ const myFont = localFont({
78
+ src: "./fonts/MyFont-Variable.woff2",
79
+ variable: "--font-my-font",
80
+ });
81
+ ```
82
+
83
+ ## Tailwind CSS v4 Integration
84
+
85
+ In Tailwind v4, font families are configured via CSS variables (no `tailwind.config.js` needed):
86
+
87
+ ```tsx
88
+ // app/layout.tsx
89
+ import { Inter } from "next/font/google";
90
+
91
+ const inter = Inter({
92
+ subsets: ["latin"],
93
+ variable: "--font-inter",
94
+ });
95
+
96
+ export default function RootLayout({ children }) {
97
+ return (
98
+ <html lang="en" className={inter.variable}>
99
+ <body>{children}</body>
100
+ </html>
101
+ );
102
+ }
103
+ ```
104
+
105
+ ```css
106
+ /* globals.css — Tailwind v4 */
107
+ @import "tailwindcss";
108
+
109
+ @theme {
110
+ --font-sans: var(--font-inter);
111
+ }
112
+ ```
113
+
114
+ Then use `font-sans` utility class as normal.
115
+
116
+ ## Display Strategy
117
+
118
+ Control font loading behavior:
119
+
120
+ ```tsx
121
+ const inter = Inter({
122
+ subsets: ["latin"],
123
+ display: "swap", // Default - shows fallback, swaps when loaded
124
+ });
125
+
126
+ // Options:
127
+ // 'swap' - immediate fallback, swap when ready (recommended)
128
+ // 'block' - short block period, then swap
129
+ // 'fallback' - short block, short swap, then fallback
130
+ // 'optional' - short block, no swap (use if font is optional)
131
+ ```
132
+
133
+ ## Common Mistakes
134
+
135
+ ```tsx
136
+ // Bad: Importing font in every component
137
+ // components/Button.tsx
138
+ import { Inter } from 'next/font/google'
139
+ const inter = Inter({ subsets: ['latin'] }) // Creates new instance each time!
140
+
141
+ // Good: Import once in layout, use CSS variable
142
+ // app/layout.tsx
143
+ const inter = Inter({ subsets: ['latin'], variable: '--font-inter' })
144
+
145
+ // Bad: Using @import in CSS (blocks rendering)
146
+ /* globals.css */
147
+ @import url('https://fonts.googleapis.com/css2?family=Inter');
148
+
149
+ // Good: Use next/font (self-hosted, no network request)
150
+ import { Inter } from 'next/font/google'
151
+
152
+ // Bad: Missing subset - loads all characters
153
+ const inter = Inter({})
154
+
155
+ // Good: Always specify subset
156
+ const inter = Inter({ subsets: ['latin'] })
157
+ ```
158
+
159
+ ## Font in Specific Components
160
+
161
+ ```tsx
162
+ // For component-specific fonts, export from a shared file
163
+ // lib/fonts.ts
164
+ import { Inter, Playfair_Display } from "next/font/google";
165
+
166
+ export const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
167
+ export const playfair = Playfair_Display({ subsets: ["latin"], variable: "--font-playfair" });
168
+
169
+ // components/Heading.tsx
170
+ import { playfair } from "@/lib/fonts";
171
+
172
+ export function Heading({ children }) {
173
+ return <h1 className={playfair.className}>{children}</h1>;
174
+ }
175
+ ```
@@ -0,0 +1,116 @@
1
+ # Functions
2
+
3
+ Next.js function APIs.
4
+
5
+ Reference: https://nextjs.org/docs/app/api-reference/functions
6
+
7
+ ## Table of Contents
8
+
9
+ - [Navigation Hooks (Client)](#navigation-hooks-client)
10
+ - [Server Functions](#server-functions)
11
+ - [Generate Functions](#generate-functions)
12
+ - [Request/Response](#requestresponse)
13
+ - [Common Examples](#common-examples)
14
+
15
+ ## Navigation Hooks (Client)
16
+
17
+ | Hook | Purpose | Reference |
18
+ | --------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
19
+ | `useRouter` | Programmatic navigation (`push`, `replace`, `back`, `refresh`) | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-router) |
20
+ | `usePathname` | Get current pathname | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-pathname) |
21
+ | `useSearchParams` | Read URL search parameters | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-search-params) |
22
+ | `useParams` | Access dynamic route parameters | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-params) |
23
+ | `useSelectedLayoutSegment` | Active child segment (one level) | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-selected-layout-segment) |
24
+ | `useSelectedLayoutSegments` | All active segments below layout | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-selected-layout-segments) |
25
+ | `useLinkStatus` | Check link prefetch status | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-link-status) |
26
+ | `useReportWebVitals` | Report Core Web Vitals metrics | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-report-web-vitals) |
27
+
28
+ ## Server Functions
29
+
30
+ | Function | Purpose | Reference |
31
+ | ------------ | -------------------------------------------- | ---------------------------------------------------------------------- |
32
+ | `cookies` | Read/write cookies | [Docs](https://nextjs.org/docs/app/api-reference/functions/cookies) |
33
+ | `headers` | Read request headers | [Docs](https://nextjs.org/docs/app/api-reference/functions/headers) |
34
+ | `draftMode` | Enable preview of unpublished CMS content | [Docs](https://nextjs.org/docs/app/api-reference/functions/draft-mode) |
35
+ | `after` | Run code after response finishes streaming | [Docs](https://nextjs.org/docs/app/api-reference/functions/after) |
36
+ | `connection` | Wait for connection before dynamic rendering | [Docs](https://nextjs.org/docs/app/api-reference/functions/connection) |
37
+ | `userAgent` | Parse User-Agent header | [Docs](https://nextjs.org/docs/app/api-reference/functions/userAgent) |
38
+
39
+ ## Generate Functions
40
+
41
+ | Function | Purpose | Reference |
42
+ | ----------------------- | --------------------------------------- | ----------------------------------------------------------------------------------- |
43
+ | `generateStaticParams` | Pre-render dynamic routes at build time | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-static-params) |
44
+ | `generateMetadata` | Dynamic metadata | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-metadata) |
45
+ | `generateViewport` | Dynamic viewport config | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-viewport) |
46
+ | `generateSitemaps` | Multiple sitemaps for large sites | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-sitemaps) |
47
+ | `generateImageMetadata` | Multiple OG images per route | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-image-metadata) |
48
+
49
+ ## Request/Response
50
+
51
+ | Function | Purpose | Reference |
52
+ | --------------- | ------------------------------ | -------------------------------------------------------------------------- |
53
+ | `NextRequest` | Extended Request with helpers | [Docs](https://nextjs.org/docs/app/api-reference/functions/next-request) |
54
+ | `NextResponse` | Extended Response with helpers | [Docs](https://nextjs.org/docs/app/api-reference/functions/next-response) |
55
+ | `ImageResponse` | Generate OG images | [Docs](https://nextjs.org/docs/app/api-reference/functions/image-response) |
56
+
57
+ ## Common Examples
58
+
59
+ ### Navigation
60
+
61
+ Use `next/link` for internal navigation instead of `<a>` tags.
62
+
63
+ ```tsx
64
+ // Bad: Plain anchor tag
65
+ <a href="/about">About</a>;
66
+
67
+ // Good: Next.js Link
68
+ import Link from "next/link";
69
+
70
+ <Link href="/about">About</Link>;
71
+ ```
72
+
73
+ Active link styling:
74
+
75
+ ```tsx
76
+ "use client";
77
+
78
+ import Link from "next/link";
79
+ import { usePathname } from "next/navigation";
80
+
81
+ export function NavLink({ href, children }) {
82
+ const pathname = usePathname();
83
+
84
+ return (
85
+ <Link href={href} className={pathname === href ? "active" : ""}>
86
+ {children}
87
+ </Link>
88
+ );
89
+ }
90
+ ```
91
+
92
+ ### Static Generation
93
+
94
+ ```tsx
95
+ // app/blog/[slug]/page.tsx
96
+ export async function generateStaticParams() {
97
+ const posts = await getPosts();
98
+ return posts.map((post) => ({ slug: post.slug }));
99
+ }
100
+ ```
101
+
102
+ ### After Response
103
+
104
+ ```tsx
105
+ import { after } from "next/server";
106
+
107
+ export async function POST(request: Request) {
108
+ const data = await processRequest(request);
109
+
110
+ after(async () => {
111
+ await logAnalytics(data);
112
+ });
113
+
114
+ return Response.json({ success: true });
115
+ }
116
+ ```