-
Welcome, {user.name}!
-``` - -## Server Components - -### Fundamentals - -- Server Components render React server-side and never run on the client -- Use Server Components as the default choice, especially for data fetching -- No use of hooks, browser APIs, or event handlers in Server Components -- No use of `useState`, `useEffect`, or any other React hooks -- Server Components can render Client Components but not vice versa - -### Data Fetching - -- Fetch data directly using async/await in Server Components -- Use Suspense boundaries around data-fetching components -- Apply security checks before fetching sensitive data -- Never pass sensitive data (API keys, tokens) to Client Components -- Use React's `cache()` function for caching data requests - -### Error Handling - -- Implement error boundaries at appropriate levels -- Use the Next.js `error.tsx` file for route-level error handling -- Create fallback UI for when data fetching fails -- Log server errors appropriately without exposing details to clients - -### Streaming and Suspense - -- Use React Suspense for progressive loading experiences if specified -- Implement streaming rendering for large or complex pages -- Structure components to enable meaningful loading states -- Prioritize above-the-fold content when using streaming - -## Client Components - -### Fundamentals - -- Add the `'use client'` directive at the top of files for Client Components -- Keep Client Components focused on interactivity and browser APIs -- Use hooks appropriately following the Rules of Hooks -- Implement controlled components for form elements -- Handle all browser events in Client Components - -### Data Fetching - -- Use React Query (TanStack Query) for data fetching in Client Components -- Create custom hooks for data fetching logic (e.g., `useUserData`) -- Always handle loading, success, and error states - -### Form Handling - -- Use libraries like React Hook Form for complex forms -- Implement proper validation with libraries like Zod -- Create reusable form components -- Handle form submissions with loading and error states -- Use controlled components for form inputs - -### Error Handling - -- Implement error boundaries to catch and handle component errors if using client components -- Always handle network request errors -- Provide user-friendly error messages -- Log errors appropriately -- Implement retry mechanisms where applicable - -```typescript -'use client'; - -import { ErrorBoundary } from 'react-error-boundary'; - -function ErrorFallback({ error, resetErrorBoundary }) { - return ( -Something went wrong:
-{error.message}
-
- Thank you for joining us.
', - }); -} - -async function sendComplexEmail() { - // Send with email template - const { html, subject } = await renderAccountDeleteEmail({ - userDisplayName: user.name, - productName: 'My SaaS App', - }); - - await mailer.sendEmail({ - to: user.email, - from: 'noreply@yourdomain.com', - subject, - html, - }); -} -``` - -## Email Templates - -Email templates are located in `@kit/email-templates` and return `{ html, subject }`: - -```typescript -import { - renderAccountDeleteEmail, - renderWelcomeEmail, - renderPasswordResetEmail -} from '@kit/email-templates'; - -// Render template -const { html, subject } = await renderWelcomeEmail({ - userDisplayName: 'John Doe', - loginUrl: 'https://app.com/login' -}); - -// Send rendered email -const mailer = await getMailer(); - -await mailer.sendEmail({ - to: user.email, - from: 'welcome@yourdomain.com', - subject, - html, -}); -``` \ No newline at end of file +@AGENTS.md diff --git a/packages/next/AGENTS.md b/packages/next/AGENTS.md index 0dfa7307c..75c4e74ec 100644 --- a/packages/next/AGENTS.md +++ b/packages/next/AGENTS.md @@ -1,478 +1,58 @@ -# Next.js Utilities Instructions +# Next.js Utilities -This file contains instructions for working with Next.js utilities including server actions and route handlers. +## Quick Reference + +| Function | Import | Purpose | +|----------|--------|---------| +| `enhanceAction` | `@kit/next/actions` | Server actions with auth + validation | +| `enhanceRouteHandler` | `@kit/next/routes` | API routes with auth + validation | ## Guidelines -- Don't use Server Actions for data-fetching, use for mutations only -- Best Practice: Keep actions light, move business logic to ad-hoc services -- Authorization logic must be defined in RLS and DB, not Server Actions or application code (unless using the admin client, use sparinlgy!) -- Do not expose sensitive data -- Log async operations -- Validate body with Zod -- Use 'use server' at the top of the file. No need for 'server only'; +- Server Actions for mutations only, not data-fetching +- Keep actions light - move business logic to services +- Authorization via RLS, not application code +- Use `'use server'` at top of file +- Always validate with Zod schema -## Server Actions Implementation +## Skills -Always use `enhanceAction` from `@packages/next/src/actions/index.ts`. +For detailed implementation patterns: +- `/server-action-builder` - Complete server action workflow -Define a schema: - -```tsx -import { z } from 'zod'; - -// Define your schema in its own file -export const CreateNoteSchema = z.object({ - title: z.string().min(1, 'Title is required'), - content: z.string().min(1, 'Content is required'), - accountId: z.string().uuid('Invalid account ID'), -}); -``` - -Then we define a service for crossing the network boundary: - -```tsx -import { CreateNoteSchema } from '../schemas/notes.schemas.ts'; -import * as z from 'zod'; - -export function createNotesService() { - return new NotesService(); -} - -class NotesService { - createNote(data: z.inferSecondary text
-Secondary text
-Secondary text
-Secondary text
-