Imported from ntnhan94/ai-ready-project-template (
frontend/AGENTS.md). Install upstream withnpx skills add ntnhan94/ai-ready-project-template --skill frontend. Copyright stays with the author.
Frontend — Next.js 16 Application
Stack
- Next.js 16.2 with App Router (no Pages Router)
- React 19 with Server Components as default
- TypeScript 6.0 in strict mode
- Tailwind CSS 4.2 (CSS-first config via
@themedirectives, notailwind.config.js) - shadcn/ui for base UI components (copied into
src/components/ui/) - Auth.js v5 (
next-auth@5) for authentication - Stripe.js +
@stripe/react-stripe-jsfor payment UI
Directory Structure
frontend/
├── src/
│ ├── app/ # App Router: pages, layouts, API routes
│ │ ├── (auth)/ # Auth pages (login, register) — public layout
│ │ ├── (dashboard)/ # Authenticated pages — dashboard layout
│ │ │ ├── invoices/ # Invoice CRUD pages
│ │ │ ├── customers/ # Customer management pages
│ │ │ ├── payments/ # Payment history pages
│ │ │ ├── reports/ # Financial reports pages
│ │ │ └── settings/ # Tenant & user settings
│ │ ├── api/ # API route handlers (webhooks, auth)
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Landing page
│ ├── components/ # React components
│ │ ├── ui/ # shadcn/ui base components
│ │ ├── invoices/ # Invoice-specific components
│ │ ├── customers/ # Customer-specific components
│ │ ├── dashboard/ # Dashboard widgets
│ │ └── layout/ # Shell, sidebar, header
│ ├── lib/ # Utilities, API client, auth config
│ ├── hooks/ # Custom React hooks
│ ├── stores/ # Client-side state (Zustand)
│ └── types/ # Shared TypeScript types
├── public/ # Static assets
├── package.json
├── tsconfig.json
└── .env.example
Conventions
File Naming
- Pages/Layouts:
page.tsx,layout.tsx,loading.tsx,error.tsx(Next.js conventions) - Components: PascalCase file names matching the component name (
InvoiceTable.tsx) - Utilities/hooks: camelCase (
useInvoices.ts,formatCurrency.ts) - Types: PascalCase with
.types.tssuffix for module-specific types
Component Patterns
- Server Components (default): Used for data fetching, layouts, pages. No
"use client"directive. - Client Components: Only when needed for interactivity (forms, modals, dropdowns). Always add
"use client"at the top. - Named exports only — no default exports except for Next.js pages/layouts (which require them).
- Props interfaces: Define inline for simple components, in
.types.tsfor shared/complex types.
Imports
- Use absolute imports via
@/prefix (maps tosrc/) - Group imports: React/Next → third-party →
@/lib→@/components→@/hooks→@/types→ relative
Data Fetching
- Server Components: Use
asynccomponent functions with directfetch()or server actions - Client Components: Use custom hooks wrapping
fetchwith SWR-like patterns from@/hooks/ - API base URL:
process.env.NEXT_PUBLIC_API_URL(points to FastAPI backend) - Auth token: Injected via Auth.js session — never manually manage tokens in components
Styling
- Tailwind CSS 4.2 utility classes only — no CSS modules, no styled-components
- Theme customization via
@themedirective insrc/app/globals.css - Use
cn()utility from@/lib/utilsto merge conditional class names - Responsive design: mobile-first (
sm:,md:,lg:breakpoints)
Error Handling
- Use Next.js
error.tsxboundaries for page-level errors - Use toast notifications (via shadcn/ui
Sonner) for action feedback - API errors are typed as
ApiError— see@/types/api.types.ts
Anti-Patterns (Do NOT)
- Do NOT use
useEffectfor data fetching — use Server Components or SWR hooks - Do NOT store auth tokens in localStorage — Auth.js manages sessions via cookies
- Do NOT use inline styles — use Tailwind classes
- Do NOT create wrapper components that only pass props through
- Do NOT use
anytype — define proper types or useunknownwith type guards