Next.js Development
Best practices and project-specific patterns for developing with Next.js.
This document outlines the key patterns and best practices we follow for Next.js development. Adhering to these conventions is crucial for maintaining a secure, performant, and maintainable codebase.
Server Actions
Server Actions are a cornerstone of our application for handling mutations (creating, updating, or deleting data).
Security and Validation
- Treat as Public Endpoints: Always assume Server Actions can be called by anyone. Implement rigorous server-side validation with Zod.
- Authentication: Use our custom
requireUser()orrequireSuperAdmin()helpers from@repo/auth/authat the beginning of every action to ensure the user is authenticated and has the necessary permissions. - Error Handling: Never throw errors directly from a Server Action. Wrap all logic in a
try...catchblock and return a consistent{ success: boolean, message: string }object.
Client-Side Usage
- Loading States: Use the
useTransitionhook to manage pending states in your UI. This provides a better user experience than usinguseState. - Notifications: Use
toastfromsonnerto display success or error messages to the user based on the result of the Server Action.
Data Fetching
- Use Server Components: For fetching data (reading), use React Server Components. This is the idiomatic Next.js approach and allows for efficient data fetching on the server.
- Reserve Server Actions for Mutations: Do not use Server Actions for fetching data. They are designed for mutations that change the state of the application.
- Route Handlers for APIs: If you need a dedicated API endpoint (e.g., for a third-party service to call), use a Route Handler.
Form Handling
We use a combination of React Hook Form and Zod for building robust and type-safe forms.
- Schema Definition: Define a Zod schema for your form data.
- Type Inference: Use
z.input<typeof yourSchema>to infer the type for your form inputs. - Submission: Use the
startTransitionfunction fromuseTransitionto handle form submissions asynchronously.
Project-Specific Rules
- Authentication Imports: Never import directly from
@clerk/nextjs. Always use our abstracted packages:@repo/auth/authfor server-side code and@repo/auth/auth-clientfor client-side code. - UI Components: All shared UI components are located in
@repo/design-system/components/ui. - Animation: Use
motion/reactfor animations, notframer-motion.