|
| 1 | +--- |
| 2 | +description: Next.js with TypeScript and Shadcn UI best practices |
| 3 | +applyTo: **/*.tsx, **/*.ts, src/**/*.ts, src/**/*.tsx |
| 4 | +--- |
| 5 | + |
| 6 | +# Next.js Best Practices |
| 7 | + |
| 8 | +## Git Repository Manager |
| 9 | + |
| 10 | +- Use conventional commit |
| 11 | +- Use rebase for merge branch |
| 12 | + |
| 13 | +## Manager Package |
| 14 | + |
| 15 | +- Use pnpm instead of npm |
| 16 | +- Use shadcn instead of shadcn-ui as it is the old name of the library. |
| 17 | + |
| 18 | +## Workflow |
| 19 | + |
| 20 | +- When create a new api route, remember create swagger api document |
| 21 | +- When create new UI component, priority to use shadcn@latest before create new component |
| 22 | +- When create new page, priority to use i18n with two languages: English and Vietnamese |
| 23 | + |
| 24 | +## Development Environment |
| 25 | + |
| 26 | +- Node.js version 22 |
| 27 | +- PNPM version >= 9 |
| 28 | +- Use Turbopack in development (`next dev --turbopack`) |
| 29 | +- Use Biome for linting and formatting |
| 30 | +- Commits are checked with Biome via lint-staged |
| 31 | +- Files are automatically formatted before commits |
| 32 | +- Prisma schema location: ./configs/prisma/schema.prisma |
| 33 | +- Remember **DONT** write in 'main' branch, write code in 'dev' branch or create new branch if need |
| 34 | + |
| 35 | +## Code Style & Formatting |
| 36 | + |
| 37 | +- Follow Biome's default code style |
| 38 | +- Use consistent formatting across all files |
| 39 | +- Run Biome checks before committing: |
| 40 | + - `pnpm lint:check` to check with biome |
| 41 | + - `pnpm lint:fix` to fix linting issues |
| 42 | + - `pnpm lint:unsafe` for unsafe fixes |
| 43 | +- Fix any Biome warnings or errors before committing |
| 44 | + |
| 45 | +## Project Structure |
| 46 | + |
| 47 | +- Use the App Router directory structure |
| 48 | +- Place components in `app` directory for route-specific components |
| 49 | +- Place shared components in `components` directory |
| 50 | +- Place utilities and helpers in `utils` directory, the `lib` directory is reserved for third-party libraries |
| 51 | +- Use lowercase with dashes for directories (e.g., `components/auth-wizard`) |
| 52 | +- Place configuration files in `configs` directory |
| 53 | + |
| 54 | +## Components |
| 55 | + |
| 56 | +- Use Server Components by default |
| 57 | +- Mark client components explicitly with 'use client' |
| 58 | +- Client components must use [name].client.tsx naming format |
| 59 | +- Components should be less than 300 lines |
| 60 | +- Break down large components into smaller, focused ones |
| 61 | +- Use subcomponents for complex UIs |
| 62 | +- Group related components in feature folders |
| 63 | +- Wrap client components in Suspense with fallback |
| 64 | +- Use dynamic loading for non-critical components |
| 65 | +- Implement proper error boundaries |
| 66 | + |
| 67 | +## Data Fetching |
| 68 | + |
| 69 | +- Use Server Components for data fetching when possible, it should be place in dynamic.tsx file |
| 70 | +- Implement proper error handling for data fetching |
| 71 | +- Use appropriate caching strategies |
| 72 | +- Handle loading and error states appropriately |
| 73 | + |
| 74 | +## Forms and Validation |
| 75 | + |
| 76 | +- Use Zod for form validation |
| 77 | +- Implement proper server-side validation |
| 78 | +- Handle form errors appropriately |
| 79 | +- Show loading states during form submission |
| 80 | + |
| 81 | +## Error Handling |
| 82 | + |
| 83 | +- Use `useHandleError` hook for client-side error handling |
| 84 | + - Always wrap async operations with handleErrorClient |
| 85 | + - Provide success callbacks when needed |
| 86 | + - Control toast notifications with withSuccessNotify parameter |
| 87 | +- Use `handleErrorServer` utilities for server-side error handling |
| 88 | + - Use handleErrorServerNoAuth for public routes |
| 89 | + - Use handleErrorServerWithAuth for protected routes |
| 90 | + - Always return ResponseType with proper error or success structure |
| 91 | +- Use toast notifications for user feedback |
| 92 | +- Implement proper error boundaries in components |
| 93 | + |
| 94 | +## Internationalization (i18n) |
| 95 | + |
| 96 | +- Use next-intl for translations |
| 97 | +- Place translation files in configs/messages/ |
| 98 | +- Support multiple locales (en, vi) |
| 99 | +- Use dynamic route groups for localization ([locale]) |
| 100 | +- Use useTranslations hook for client-side translations |
| 101 | +- Place all text in translation files, no hardcoded strings |
| 102 | + |
| 103 | +## Authentication (Supabase) |
| 104 | + |
| 105 | +- Use Supabase SSR client for server-side auth |
| 106 | +- Implement proper session handling in middleware |
| 107 | +- Use auth callback routes for authentication flow |
| 108 | +- Protected routes should use handleErrorServerWithAuth |
| 109 | + |
| 110 | +## State Management |
| 111 | + |
| 112 | +- Minimize client-side state |
| 113 | +- Use React Context sparingly |
| 114 | +- Prefer server state when possible |
| 115 | +- Implement proper loading states |
| 116 | +- Use proper TypeScript types for all state |
0 commit comments