AInstein

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() or requireSuperAdmin() helpers from @repo/auth/auth at 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...catch block and return a consistent { success: boolean, message: string } object.

Client-Side Usage

  • Loading States: Use the useTransition hook to manage pending states in your UI. This provides a better user experience than using useState.
  • Notifications: Use toast from sonner to 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 startTransition function from useTransition to handle form submissions asynchronously.

Project-Specific Rules

  • Authentication Imports: Never import directly from @clerk/nextjs. Always use our abstracted packages: @repo/auth/auth for server-side code and @repo/auth/auth-client for client-side code.
  • UI Components: All shared UI components are located in @repo/design-system/components/ui.
  • Animation: Use motion/react for animations, not framer-motion.

On this page