kaddidlehopper 0.1.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 (183) hide show
  1. package/CONTEXT.md +139 -0
  2. package/README.md +47 -0
  3. package/add-ons/ai/README.md +34 -0
  4. package/add-ons/ai/assets/_dot_env.local.append +13 -0
  5. package/add-ons/ai/assets/src/components/AIAssistant.tsx +149 -0
  6. package/add-ons/ai/assets/src/lib/ai-hook.ts +21 -0
  7. package/add-ons/ai/assets/src/lib/weather-tools.ts +30 -0
  8. package/add-ons/ai/assets/src/routes/api.chat.ts +94 -0
  9. package/add-ons/ai/assets/src/routes/chat.css +175 -0
  10. package/add-ons/ai/assets/src/routes/chat.tsx +141 -0
  11. package/add-ons/ai/info.json +27 -0
  12. package/add-ons/ai/package.json +17 -0
  13. package/add-ons/ai/small-logo.svg +8 -0
  14. package/dist/cli.js +251 -0
  15. package/dist/index.js +33 -0
  16. package/dist/types/cli.d.ts +8 -0
  17. package/dist/types/index.d.ts +2 -0
  18. package/dist/types/types.d.ts +14 -0
  19. package/dist/types.js +1 -0
  20. package/examples/blog/README.md +60 -0
  21. package/examples/blog/assets/content/posts/beach.md +12 -0
  22. package/examples/blog/assets/content/posts/jungle.md.ejs +12 -0
  23. package/examples/blog/assets/content/posts/mountains.md.ejs +12 -0
  24. package/examples/blog/assets/content/posts/snorkeling.md.ejs +12 -0
  25. package/examples/blog/assets/content/posts/waterfall.md.ejs +12 -0
  26. package/examples/blog/assets/content-collections.ts +30 -0
  27. package/examples/blog/assets/public/beach.jpg +0 -0
  28. package/examples/blog/assets/public/jungle.jpg +0 -0
  29. package/examples/blog/assets/public/mountains.jpg +0 -0
  30. package/examples/blog/assets/public/snorkeling.jpg +0 -0
  31. package/examples/blog/assets/public/waterfall.jpg +0 -0
  32. package/examples/blog/assets/src/components/Header.tsx +52 -0
  33. package/examples/blog/assets/src/components/VacayAssistant.tsx +205 -0
  34. package/examples/blog/assets/src/components/blog-posts.tsx +78 -0
  35. package/examples/blog/assets/src/components/ui/card.tsx +92 -0
  36. package/examples/blog/assets/src/lib/blog-ai-hook.ts +25 -0
  37. package/examples/blog/assets/src/lib/blog-tools.ts +111 -0
  38. package/examples/blog/assets/src/lib/utils.ts +6 -0
  39. package/examples/blog/assets/src/routes/__root.tsx +57 -0
  40. package/examples/blog/assets/src/routes/api.blog-chat.ts +117 -0
  41. package/examples/blog/assets/src/routes/category.$category.tsx +19 -0
  42. package/examples/blog/assets/src/routes/index.tsx +19 -0
  43. package/examples/blog/assets/src/routes/posts.$slug.tsx +63 -0
  44. package/examples/blog/assets/src/styles.css +138 -0
  45. package/examples/blog/info.json +43 -0
  46. package/examples/blog/package.json +23 -0
  47. package/examples/events/README.md +110 -0
  48. package/examples/events/assets/content/speakers/andre-costa.md +22 -0
  49. package/examples/events/assets/content/speakers/hans-mueller.md.ejs +22 -0
  50. package/examples/events/assets/content/speakers/isabella-martinez.md.ejs +22 -0
  51. package/examples/events/assets/content/speakers/kenji-nakamura.md.ejs +22 -0
  52. package/examples/events/assets/content/speakers/marie-dubois.md.ejs +20 -0
  53. package/examples/events/assets/content/speakers/priya-sharma.md.ejs +22 -0
  54. package/examples/events/assets/content/talks/croissant-lamination-secrets.md +39 -0
  55. package/examples/events/assets/content/talks/french-macaron-mastery.md.ejs +39 -0
  56. package/examples/events/assets/content/talks/neapolitan-pizza-tradition-meets-innovation.md.ejs +39 -0
  57. package/examples/events/assets/content/talks/savory-breads-of-the-mediterranean.md.ejs +39 -0
  58. package/examples/events/assets/content/talks/sourdough-from-starter-to-masterpiece.md.ejs +36 -0
  59. package/examples/events/assets/content/talks/the-art-of-the-perfect-tart.md.ejs +32 -0
  60. package/examples/events/assets/content/talks/the-science-of-sugar.md.ejs +39 -0
  61. package/examples/events/assets/content/talks/umami-in-pastry-east-meets-west.md.ejs +39 -0
  62. package/examples/events/assets/content-collections.ts +56 -0
  63. package/examples/events/assets/public/background-1.jpg +0 -0
  64. package/examples/events/assets/public/background-2.jpg +0 -0
  65. package/examples/events/assets/public/background-3.jpg +0 -0
  66. package/examples/events/assets/public/background-4.jpg +0 -0
  67. package/examples/events/assets/public/conference-logo.png +0 -0
  68. package/examples/events/assets/public/favicon.ico +0 -0
  69. package/examples/events/assets/public/speakers/andre-costa.jpg +0 -0
  70. package/examples/events/assets/public/speakers/hans-mueller.jpg +0 -0
  71. package/examples/events/assets/public/speakers/isabella-martinez.jpg +0 -0
  72. package/examples/events/assets/public/speakers/kenji-nakamura.jpg +0 -0
  73. package/examples/events/assets/public/speakers/marie-dubois.jpg +0 -0
  74. package/examples/events/assets/public/speakers/priya-sharma.jpg +0 -0
  75. package/examples/events/assets/public/talks/croissant-lamination-secrets.jpg +0 -0
  76. package/examples/events/assets/public/talks/french-macaron-mastery.jpg +0 -0
  77. package/examples/events/assets/public/talks/neapolitan-pizza-tradition-meets-innovation.jpg +0 -0
  78. package/examples/events/assets/public/talks/savory-breads-of-the-mediterranean.jpg +0 -0
  79. package/examples/events/assets/public/talks/sourdough-from-starter-to-masterpiece.jpg +0 -0
  80. package/examples/events/assets/public/talks/the-art-of-the-perfect-tart.jpg +0 -0
  81. package/examples/events/assets/public/talks/the-science-of-sugar.jpg +0 -0
  82. package/examples/events/assets/public/talks/umami-in-pastry-east-meets-west.jpg +0 -0
  83. package/examples/events/assets/public/tanstack-circle-logo.png +0 -0
  84. package/examples/events/assets/public/tanstack-word-logo-white.svg +1 -0
  85. package/examples/events/assets/src/components/Header.tsx +59 -0
  86. package/examples/events/assets/src/components/HeaderNav.tsx +67 -0
  87. package/examples/events/assets/src/components/HeroCarousel.tsx +61 -0
  88. package/examples/events/assets/src/components/RemyAssistant.tsx +207 -0
  89. package/examples/events/assets/src/components/SpeakerCard.tsx +67 -0
  90. package/examples/events/assets/src/components/TalkCard.tsx +77 -0
  91. package/examples/events/assets/src/components/ui/card.tsx +92 -0
  92. package/examples/events/assets/src/lib/conference-ai-hook.ts +26 -0
  93. package/examples/events/assets/src/lib/conference-tools.ts +210 -0
  94. package/examples/events/assets/src/lib/model-selection.ts +1 -0
  95. package/examples/events/assets/src/lib/utils.ts +6 -0
  96. package/examples/events/assets/src/routes/__root.tsx +70 -0
  97. package/examples/events/assets/src/routes/api.remy-chat.ts +119 -0
  98. package/examples/events/assets/src/routes/index.tsx +192 -0
  99. package/examples/events/assets/src/routes/schedule.index.tsx +274 -0
  100. package/examples/events/assets/src/routes/speakers.$slug.tsx +122 -0
  101. package/examples/events/assets/src/routes/speakers.index.tsx +40 -0
  102. package/examples/events/assets/src/routes/talks.$slug.tsx +116 -0
  103. package/examples/events/assets/src/routes/talks.index.tsx +40 -0
  104. package/examples/events/assets/src/styles.css +182 -0
  105. package/examples/events/info.json +74 -0
  106. package/examples/events/package.json +23 -0
  107. package/examples/marketing/README.md +60 -0
  108. package/examples/marketing/assets/public/logo.png +0 -0
  109. package/examples/marketing/assets/public/motorcycle-adventure.jpg +0 -0
  110. package/examples/marketing/assets/public/motorcycle-cruiser.jpg +0 -0
  111. package/examples/marketing/assets/public/motorcycle-scooter.jpg +0 -0
  112. package/examples/marketing/assets/public/motorcycle-sport.jpg +0 -0
  113. package/examples/marketing/assets/public/motorcycle-supersport.jpg +0 -0
  114. package/examples/marketing/assets/src/components/Header.tsx +36 -0
  115. package/examples/marketing/assets/src/components/MotorcycleAIAssistant.tsx +162 -0
  116. package/examples/marketing/assets/src/components/MotorcycleRecommendation.tsx +53 -0
  117. package/examples/marketing/assets/src/data/motorcycles.ts.ejs +77 -0
  118. package/examples/marketing/assets/src/lib/motorcycle-ai-hook.ts +24 -0
  119. package/examples/marketing/assets/src/lib/motorcycle-tools.ts +42 -0
  120. package/examples/marketing/assets/src/routes/__root.tsx +57 -0
  121. package/examples/marketing/assets/src/routes/api.motorcycle-chat.ts +78 -0
  122. package/examples/marketing/assets/src/routes/index.tsx +72 -0
  123. package/examples/marketing/assets/src/routes/motorcycles/$motorcycleId.tsx +56 -0
  124. package/examples/marketing/assets/src/store/motorcycle-assistant.ts +3 -0
  125. package/examples/marketing/assets/src/styles.css +212 -0
  126. package/examples/marketing/info.json +38 -0
  127. package/examples/marketing/package.json +14 -0
  128. package/examples/resume/README.md +82 -0
  129. package/examples/resume/assets/content/education/code-school.md +17 -0
  130. package/examples/resume/assets/content/jobs/freelance.md.ejs +13 -0
  131. package/examples/resume/assets/content/jobs/initech-junior.md +20 -0
  132. package/examples/resume/assets/content/jobs/initech-lead.md.ejs +29 -0
  133. package/examples/resume/assets/content/jobs/initrode-senior.md.ejs +28 -0
  134. package/examples/resume/assets/content-collections.ts +36 -0
  135. package/examples/resume/assets/public/headshot-on-white.jpg +0 -0
  136. package/examples/resume/assets/src/components/Header.tsx +33 -0
  137. package/examples/resume/assets/src/components/ResumeAssistant.tsx +193 -0
  138. package/examples/resume/assets/src/components/ui/badge.tsx +46 -0
  139. package/examples/resume/assets/src/components/ui/card.tsx +92 -0
  140. package/examples/resume/assets/src/components/ui/checkbox.tsx +30 -0
  141. package/examples/resume/assets/src/components/ui/hover-card.tsx +44 -0
  142. package/examples/resume/assets/src/components/ui/separator.tsx +26 -0
  143. package/examples/resume/assets/src/lib/resume-ai-hook.ts +21 -0
  144. package/examples/resume/assets/src/lib/resume-tools.ts +165 -0
  145. package/examples/resume/assets/src/lib/utils.ts +6 -0
  146. package/examples/resume/assets/src/routes/api.resume-chat.ts +110 -0
  147. package/examples/resume/assets/src/routes/index.tsx +220 -0
  148. package/examples/resume/assets/src/styles.css +138 -0
  149. package/examples/resume/info.json +25 -0
  150. package/examples/resume/package.json +26 -0
  151. package/package.json +39 -0
  152. package/project/base/_dot_claude/skills/content-collections/SKILL.md +505 -0
  153. package/project/base/_dot_claude/skills/netlify-blobs/SKILL.md +410 -0
  154. package/project/base/_dot_claude/skills/netlify-db/SKILL.md +424 -0
  155. package/project/base/_dot_claude/skills/netlify-debugging/SKILL.md +419 -0
  156. package/project/base/_dot_claude/skills/netlify-forms/SKILL.md +243 -0
  157. package/project/base/_dot_claude/skills/netlify-functions/SKILL.md +372 -0
  158. package/project/base/_dot_claude/skills/tanstack-start-api-routes/SKILL.md +421 -0
  159. package/project/base/_dot_claude/skills/tanstack-start-loaders/SKILL.md +426 -0
  160. package/project/base/_dot_claude/skills/tanstack-start-project-setup/SKILL.md +493 -0
  161. package/project/base/_dot_claude/skills/tanstack-start-routes/SKILL.md +430 -0
  162. package/project/base/_dot_claude/skills/tanstack-start-server-functions/SKILL.md +445 -0
  163. package/project/base/_dot_claude/skills/tanstack-start-typesafe-routing/SKILL.md +494 -0
  164. package/project/base/_dot_gitignore +8 -0
  165. package/project/base/netlify.toml +7 -0
  166. package/project/base/package.json +33 -0
  167. package/project/base/public/favicon.ico +0 -0
  168. package/project/base/public/tanstack-circle-logo.png +0 -0
  169. package/project/base/public/tanstack-word-logo-white.svg +1 -0
  170. package/project/base/src/components/Header.tsx +17 -0
  171. package/project/base/src/components/HeaderNav.tsx.ejs +179 -0
  172. package/project/base/src/router.tsx +15 -0
  173. package/project/base/src/routes/__root.tsx +57 -0
  174. package/project/base/src/routes/index.tsx +48 -0
  175. package/project/base/src/styles.css +15 -0
  176. package/project/base/tsconfig.json +28 -0
  177. package/project/base/vite.config.ts.ejs +25 -0
  178. package/project/packages.json +22 -0
  179. package/scripts/check-outdated-packages.js +421 -0
  180. package/src/cli.ts +343 -0
  181. package/src/index.ts +49 -0
  182. package/src/types.ts +15 -0
  183. package/tsconfig.json +17 -0
@@ -0,0 +1,419 @@
1
+ ---
2
+ name: netlify-debugging
3
+ description: Debug Netlify deployments, functions, and builds. Use when troubleshooting build failures, function errors, deployment issues, or monitoring logs on Netlify.
4
+ license: Apache-2.0
5
+ metadata:
6
+ author: netlify
7
+ version: "1.0"
8
+ ---
9
+
10
+ # Netlify Debugging
11
+
12
+ Guide to debugging builds, functions, deployments, and runtime issues on Netlify.
13
+
14
+ ## When to Use
15
+
16
+ - Build failures or timeouts
17
+ - Function errors or timeouts
18
+ - Deployment not working as expected
19
+ - Environment variable issues
20
+ - Redirect/rewrite problems
21
+ - Performance troubleshooting
22
+
23
+ ## Function Logs
24
+
25
+ ### Viewing in Netlify UI
26
+
27
+ 1. Go to your site dashboard
28
+ 2. Navigate to **Logs** → **Functions**
29
+ 3. Select a function to view its logs
30
+ 4. Filter by time range or search for specific errors
31
+
32
+ ### Streaming Logs with CLI
33
+
34
+ ```bash
35
+ # Stream all function logs
36
+ netlify functions:log
37
+
38
+ # Stream logs for a specific function
39
+ netlify functions:log --name=my-function
40
+
41
+ # Stream with tail (follow mode)
42
+ netlify functions:log --tail
43
+
44
+ # Filter by level
45
+ netlify functions:log --level=error
46
+ ```
47
+
48
+ ### Adding Logs to Functions
49
+
50
+ ```typescript
51
+ // netlify/functions/api.ts
52
+ export default async (request: Request, context: Context) => {
53
+ console.log("Request received:", {
54
+ method: request.method,
55
+ url: request.url,
56
+ headers: Object.fromEntries(request.headers),
57
+ });
58
+
59
+ try {
60
+ const result = await processRequest(request);
61
+ console.log("Request processed successfully:", result);
62
+ return Response.json(result);
63
+ } catch (error) {
64
+ console.error("Error processing request:", error);
65
+ return new Response("Internal error", { status: 500 });
66
+ }
67
+ };
68
+ ```
69
+
70
+ ### Structured Logging
71
+
72
+ ```typescript
73
+ function log(level: "info" | "warn" | "error", message: string, data?: object) {
74
+ const entry = {
75
+ timestamp: new Date().toISOString(),
76
+ level,
77
+ message,
78
+ ...data,
79
+ };
80
+
81
+ if (level === "error") {
82
+ console.error(JSON.stringify(entry));
83
+ } else {
84
+ console.log(JSON.stringify(entry));
85
+ }
86
+ }
87
+
88
+ // Usage
89
+ log("info", "User logged in", { userId: "123" });
90
+ log("error", "Database connection failed", { error: err.message });
91
+ ```
92
+
93
+ ## Build Logs
94
+
95
+ ### Viewing Build Logs
96
+
97
+ 1. Go to **Deploys** in site dashboard
98
+ 2. Click on a deploy
99
+ 3. View **Deploy log** for full build output
100
+
101
+ ### Local Build Testing
102
+
103
+ ```bash
104
+ # Run the build command locally
105
+ npm run build
106
+
107
+ # Test with Netlify CLI (simulates Netlify environment)
108
+ netlify build
109
+
110
+ # Build with specific context
111
+ netlify build --context=deploy-preview
112
+ ```
113
+
114
+ ### Common Build Issues
115
+
116
+ #### Out of Memory
117
+
118
+ ```toml
119
+ # netlify.toml - Increase Node.js memory
120
+ [build.environment]
121
+ NODE_OPTIONS = "--max_old_space_size=4096"
122
+ ```
123
+
124
+ #### Missing Dependencies
125
+
126
+ ```bash
127
+ # Ensure all dependencies are in package.json
128
+ npm install missing-package --save
129
+
130
+ # Clear cache if issues persist
131
+ # In Netlify UI: Deploys → Trigger deploy → Clear cache and deploy site
132
+ ```
133
+
134
+ #### Build Timeout
135
+
136
+ ```toml
137
+ # netlify.toml - Check your build command
138
+ [build]
139
+ command = "npm run build"
140
+ publish = "dist"
141
+
142
+ # Consider:
143
+ # - Splitting build into smaller chunks
144
+ # - Using build caching
145
+ # - Optimizing slow operations
146
+ ```
147
+
148
+ ## Environment Variables
149
+
150
+ ### Debugging Environment Variables
151
+
152
+ ```typescript
153
+ // Log available environment variables (be careful with secrets!)
154
+ console.log("NODE_ENV:", process.env.NODE_ENV);
155
+ console.log("CONTEXT:", process.env.CONTEXT);
156
+ console.log("DEPLOY_URL:", process.env.DEPLOY_URL);
157
+
158
+ // Check if variable exists
159
+ if (!process.env.API_KEY) {
160
+ console.error("API_KEY is not set!");
161
+ }
162
+ ```
163
+
164
+ ### Netlify-Provided Variables
165
+
166
+ | Variable | Description |
167
+ |----------|-------------|
168
+ | `CONTEXT` | Build context: `production`, `deploy-preview`, `branch-deploy` |
169
+ | `DEPLOY_URL` | URL of the current deploy |
170
+ | `DEPLOY_PRIME_URL` | Primary URL for the deploy |
171
+ | `URL` | Main site URL |
172
+ | `SITE_ID` | Netlify site ID |
173
+ | `SITE_NAME` | Site name |
174
+ | `BUILD_ID` | Unique build ID |
175
+ | `COMMIT_REF` | Git commit SHA |
176
+ | `BRANCH` | Git branch name |
177
+
178
+ ### Testing Different Environments
179
+
180
+ ```bash
181
+ # Run locally with production environment
182
+ netlify dev --context production
183
+
184
+ # Check what variables are available
185
+ netlify env:list
186
+ ```
187
+
188
+ ## Debugging Redirects
189
+
190
+ ### Testing Redirects Locally
191
+
192
+ ```bash
193
+ # netlify dev respects _redirects and netlify.toml
194
+ netlify dev
195
+ ```
196
+
197
+ ### Common Redirect Issues
198
+
199
+ ```toml
200
+ # netlify.toml
201
+
202
+ # Order matters - first match wins
203
+ [[redirects]]
204
+ from = "/api/*"
205
+ to = "/.netlify/functions/api/:splat"
206
+ status = 200
207
+
208
+ # SPA fallback (should be LAST)
209
+ [[redirects]]
210
+ from = "/*"
211
+ to = "/index.html"
212
+ status = 200
213
+ ```
214
+
215
+ ### Debugging with Headers
216
+
217
+ ```toml
218
+ # Add debug headers to see which rule matched
219
+ [[headers]]
220
+ for = "/*"
221
+ [headers.values]
222
+ X-Debug = "true"
223
+ ```
224
+
225
+ ## Function Debugging
226
+
227
+ ### Local Function Development
228
+
229
+ ```bash
230
+ # Run functions locally with hot reload
231
+ netlify dev
232
+
233
+ # Functions available at:
234
+ # http://localhost:8888/.netlify/functions/function-name
235
+ ```
236
+
237
+ ### Debugging Timeouts
238
+
239
+ ```typescript
240
+ // Check how long operations take
241
+ export default async (request: Request, context: Context) => {
242
+ const start = Date.now();
243
+
244
+ try {
245
+ const result = await someOperation();
246
+ console.log(`Operation took ${Date.now() - start}ms`);
247
+ return Response.json(result);
248
+ } catch (error) {
249
+ console.error(`Failed after ${Date.now() - start}ms:`, error);
250
+ throw error;
251
+ }
252
+ };
253
+ ```
254
+
255
+ ### Memory Issues
256
+
257
+ ```typescript
258
+ // Monitor memory usage
259
+ export default async (request: Request) => {
260
+ const memBefore = process.memoryUsage();
261
+ console.log("Memory before:", {
262
+ heapUsed: Math.round(memBefore.heapUsed / 1024 / 1024) + "MB",
263
+ heapTotal: Math.round(memBefore.heapTotal / 1024 / 1024) + "MB",
264
+ });
265
+
266
+ // ... your code ...
267
+
268
+ const memAfter = process.memoryUsage();
269
+ console.log("Memory after:", {
270
+ heapUsed: Math.round(memAfter.heapUsed / 1024 / 1024) + "MB",
271
+ });
272
+
273
+ return new Response("OK");
274
+ };
275
+ ```
276
+
277
+ ## Edge Function Debugging
278
+
279
+ ### Edge Function Logs
280
+
281
+ ```bash
282
+ # View edge function logs
283
+ netlify logs:function --edge
284
+
285
+ # Or in the UI: Logs → Edge Functions
286
+ ```
287
+
288
+ ### Local Edge Function Testing
289
+
290
+ ```bash
291
+ # Edge functions run locally with netlify dev
292
+ netlify dev
293
+
294
+ # Test specific paths configured in netlify.toml
295
+ ```
296
+
297
+ ## Deploy Previews
298
+
299
+ ### Debugging Deploy Previews
300
+
301
+ 1. Each PR gets a unique deploy preview URL
302
+ 2. Check the deploy log for the specific PR
303
+ 3. Test the preview URL to reproduce issues
304
+
305
+ ```bash
306
+ # Get deploy preview URL
307
+ netlify deploy --build
308
+ # Outputs: Draft URL: https://abc123--sitename.netlify.app
309
+ ```
310
+
311
+ ## CLI Debugging Commands
312
+
313
+ ```bash
314
+ # Check Netlify CLI status
315
+ netlify status
316
+
317
+ # View site info
318
+ netlify sites:list
319
+
320
+ # Check linked site
321
+ netlify link --status
322
+
323
+ # View current environment
324
+ netlify env:list
325
+
326
+ # Test function locally
327
+ netlify functions:invoke function-name --payload '{"key": "value"}'
328
+
329
+ # Open site dashboard
330
+ netlify open
331
+
332
+ # Open function logs
333
+ netlify open:logs
334
+ ```
335
+
336
+ ## Troubleshooting Checklist
337
+
338
+ ### Build Failures
339
+
340
+ - [ ] Check build logs for error messages
341
+ - [ ] Verify `build.command` in `netlify.toml`
342
+ - [ ] Ensure all dependencies are in `package.json`
343
+ - [ ] Check Node.js version compatibility
344
+ - [ ] Try clearing cache and redeploying
345
+ - [ ] Test build locally with `netlify build`
346
+
347
+ ### Function Issues
348
+
349
+ - [ ] Check function logs for errors
350
+ - [ ] Verify function file is in correct directory
351
+ - [ ] Check function naming (no spaces, correct extension)
352
+ - [ ] Verify environment variables are set
353
+ - [ ] Test locally with `netlify dev`
354
+ - [ ] Check for timeout issues (default 10s)
355
+
356
+ ### Deployment Issues
357
+
358
+ - [ ] Verify publish directory is correct
359
+ - [ ] Check that build outputs files to publish directory
360
+ - [ ] Verify no `.gitignore` issues with built files
361
+ - [ ] Check deploy summary for warnings
362
+
363
+ ### Environment Variable Issues
364
+
365
+ - [ ] Variables set in Netlify UI are available
366
+ - [ ] Check variable scopes (build vs. functions)
367
+ - [ ] Verify variable names match exactly (case-sensitive)
368
+ - [ ] Redeploy after adding new variables
369
+
370
+ ## Log Drains (Advanced)
371
+
372
+ Send logs to external services:
373
+
374
+ ```bash
375
+ # Configure log drain to external service
376
+ netlify logs:drain add --type http --destination https://logs.example.com/ingest
377
+
378
+ # List configured drains
379
+ netlify logs:drain list
380
+ ```
381
+
382
+ ## Performance Debugging
383
+
384
+ ### Function Cold Starts
385
+
386
+ ```typescript
387
+ // Measure cold start impact
388
+ let isWarm = false;
389
+
390
+ export default async (request: Request) => {
391
+ if (!isWarm) {
392
+ console.log("Cold start detected");
393
+ isWarm = true;
394
+ }
395
+
396
+ // ... function logic
397
+ };
398
+ ```
399
+
400
+ ### Response Time Monitoring
401
+
402
+ ```typescript
403
+ export default async (request: Request, context: Context) => {
404
+ const startTime = performance.now();
405
+
406
+ const response = await handleRequest(request);
407
+
408
+ const duration = performance.now() - startTime;
409
+ console.log(`Request processed in ${duration.toFixed(2)}ms`);
410
+
411
+ return new Response(response.body, {
412
+ ...response,
413
+ headers: {
414
+ ...response.headers,
415
+ "X-Response-Time": `${duration.toFixed(2)}ms`,
416
+ },
417
+ });
418
+ };
419
+ ```
@@ -0,0 +1,243 @@
1
+ ---
2
+ name: netlify-forms
3
+ description: Handle Netlify Forms including HTML form setup, spam filtering with honeypot fields, AJAX submissions, and form notifications. Use when implementing contact forms, signup forms, or any form submission handling on Netlify-hosted sites.
4
+ license: Apache-2.0
5
+ metadata:
6
+ author: netlify
7
+ version: "1.0"
8
+ ---
9
+
10
+ # Netlify Forms
11
+
12
+ Netlify Forms automatically handles form submissions without requiring server-side code. Forms are detected at build time and submissions are stored in the Netlify dashboard.
13
+
14
+ ## When to Use
15
+
16
+ - Adding contact forms to static sites
17
+ - Capturing user signups or feedback
18
+ - Form submissions without a backend
19
+ - Spam filtering without external services
20
+
21
+ ## Basic HTML Form
22
+
23
+ Add `data-netlify="true"` to any HTML form:
24
+
25
+ ```html
26
+ <form name="contact" method="POST" data-netlify="true">
27
+ <input type="hidden" name="form-name" value="contact" />
28
+ <p>
29
+ <label>Name: <input type="text" name="name" required /></label>
30
+ </p>
31
+ <p>
32
+ <label>Email: <input type="email" name="email" required /></label>
33
+ </p>
34
+ <p>
35
+ <label>Message: <textarea name="message" required></textarea></label>
36
+ </p>
37
+ <p>
38
+ <button type="submit">Send</button>
39
+ </p>
40
+ </form>
41
+ ```
42
+
43
+ **Critical**: The hidden `form-name` input MUST match the form's `name` attribute.
44
+
45
+ ## Spam Filtering with Honeypot
46
+
47
+ Add a honeypot field that bots will fill but humans won't see:
48
+
49
+ ```html
50
+ <form name="contact" method="POST" data-netlify="true" netlify-honeypot="bot-field">
51
+ <input type="hidden" name="form-name" value="contact" />
52
+
53
+ <!-- Honeypot field - hidden from humans -->
54
+ <p class="hidden" style="display:none;">
55
+ <label>Don't fill this out: <input name="bot-field" /></label>
56
+ </p>
57
+
58
+ <p>
59
+ <label>Name: <input type="text" name="name" required /></label>
60
+ </p>
61
+ <p>
62
+ <label>Email: <input type="email" name="email" required /></label>
63
+ </p>
64
+ <p>
65
+ <button type="submit">Send</button>
66
+ </p>
67
+ </form>
68
+ ```
69
+
70
+ ## AJAX/JavaScript Submission
71
+
72
+ For SPAs or enhanced UX, submit forms via JavaScript:
73
+
74
+ ```typescript
75
+ async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
76
+ event.preventDefault();
77
+
78
+ const form = event.currentTarget;
79
+ const formData = new FormData(form);
80
+
81
+ try {
82
+ const response = await fetch('/', {
83
+ method: 'POST',
84
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
85
+ body: new URLSearchParams(formData as any).toString(),
86
+ });
87
+
88
+ if (response.ok) {
89
+ // Success - show thank you message or redirect
90
+ console.log('Form submitted successfully');
91
+ } else {
92
+ throw new Error('Form submission failed');
93
+ }
94
+ } catch (error) {
95
+ console.error('Error:', error);
96
+ }
97
+ }
98
+ ```
99
+
100
+ **Important**: Even with AJAX submission, you need the form HTML present in your built output for Netlify to detect it.
101
+
102
+ ## React Component Example
103
+
104
+ ```tsx
105
+ export function ContactForm() {
106
+ const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
107
+
108
+ async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
109
+ e.preventDefault();
110
+ setStatus('submitting');
111
+
112
+ const form = e.currentTarget;
113
+ const formData = new FormData(form);
114
+
115
+ try {
116
+ const response = await fetch('/', {
117
+ method: 'POST',
118
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
119
+ body: new URLSearchParams(formData as any).toString(),
120
+ });
121
+
122
+ if (response.ok) {
123
+ setStatus('success');
124
+ form.reset();
125
+ } else {
126
+ setStatus('error');
127
+ }
128
+ } catch {
129
+ setStatus('error');
130
+ }
131
+ }
132
+
133
+ if (status === 'success') {
134
+ return <p>Thank you for your message!</p>;
135
+ }
136
+
137
+ return (
138
+ <form
139
+ name="contact"
140
+ method="POST"
141
+ data-netlify="true"
142
+ netlify-honeypot="bot-field"
143
+ onSubmit={handleSubmit}
144
+ >
145
+ <input type="hidden" name="form-name" value="contact" />
146
+ <p style={{ display: 'none' }}>
147
+ <label>Don't fill this out: <input name="bot-field" /></label>
148
+ </p>
149
+
150
+ <label>
151
+ Name:
152
+ <input type="text" name="name" required />
153
+ </label>
154
+
155
+ <label>
156
+ Email:
157
+ <input type="email" name="email" required />
158
+ </label>
159
+
160
+ <label>
161
+ Message:
162
+ <textarea name="message" required />
163
+ </label>
164
+
165
+ <button type="submit" disabled={status === 'submitting'}>
166
+ {status === 'submitting' ? 'Sending...' : 'Send'}
167
+ </button>
168
+
169
+ {status === 'error' && <p>Something went wrong. Please try again.</p>}
170
+ </form>
171
+ );
172
+ }
173
+ ```
174
+
175
+ ## SPA/Framework Considerations
176
+
177
+ For React, Vue, or other SPAs where forms are rendered client-side:
178
+
179
+ 1. **Option A**: Include a hidden static HTML form in your `index.html` or a static file:
180
+
181
+ ```html
182
+ <!-- In public/index.html or a static HTML file -->
183
+ <form name="contact" netlify netlify-honeypot="bot-field" hidden>
184
+ <input type="text" name="name" />
185
+ <input type="email" name="email" />
186
+ <textarea name="message"></textarea>
187
+ </form>
188
+ ```
189
+
190
+ 2. **Option B**: Use a prerendered/SSR page that includes the form markup at build time.
191
+
192
+ ## File Uploads
193
+
194
+ Forms can accept file uploads:
195
+
196
+ ```html
197
+ <form name="upload" method="POST" data-netlify="true" enctype="multipart/form-data">
198
+ <input type="hidden" name="form-name" value="upload" />
199
+ <input type="file" name="attachment" />
200
+ <button type="submit">Upload</button>
201
+ </form>
202
+ ```
203
+
204
+ **Limits**:
205
+ - Max 10MB per file
206
+ - Max 10MB total per submission
207
+
208
+ ## Custom Success Page
209
+
210
+ Redirect to a thank-you page after submission:
211
+
212
+ ```html
213
+ <form name="contact" method="POST" data-netlify="true" action="/thank-you">
214
+ <!-- form fields -->
215
+ </form>
216
+ ```
217
+
218
+ ## Form Notifications
219
+
220
+ Configure email notifications in Netlify UI:
221
+ 1. Go to Site settings → Forms → Form notifications
222
+ 2. Add email notification for form submissions
223
+ 3. Optionally integrate with Slack, webhooks, or Zapier
224
+
225
+ ## Common Issues
226
+
227
+ ### Form not detected
228
+ - Ensure `data-netlify="true"` is present in static HTML at build time
229
+ - Check that `name` attribute matches the hidden `form-name` value
230
+ - For SPAs, include a hidden static form or use SSR
231
+
232
+ ### Submissions not appearing
233
+ - Check the Forms tab in Netlify dashboard
234
+ - Verify the form name matches exactly
235
+ - Check spam folder in Forms dashboard
236
+
237
+ ### 404 on submission
238
+ - Ensure you're posting to `/` or the page URL where the form exists
239
+ - Include `Content-Type: application/x-www-form-urlencoded` header for AJAX
240
+
241
+ ## Environment Variables
242
+
243
+ No environment variables required - Netlify Forms work automatically on Netlify-hosted sites.