Tổng quan: 3 nhóm chính trong dự án Next.js
Mọi dự án Next.js đều được tổ chức thành 3 nhóm rõ ràng, mỗi nhóm có vai trò riêng:Pages
Components
Services
Cấu trúc thư mục tổng thể
components/ui/. Khi cần thêm trang mới → vào app/. Khi cần sửa cách đọc dữ liệu → vào features/tasks/services/.
1. Pages — Các trang giao diện
Pages là gì?
Pages là các trang mà người dùng truy cập qua URL. Trong Next.js, mỗi filepage.tsx trong thư mục app/ tạo ra một URL tương ứng.
Cấu trúc thư mục trình bày các trang (pages)
Giải thích các khái niệm trong Pages
Tên thư mục = URL
Tên thư mục = URL
[id] — Trang động (Dynamic Route)
[id] — Trang động (Dynamic Route)
[id] tạo trang dùng cho nhiều URL khác nhau. Thay vì tạo riêng 1 trang cho mỗi task, bạn tạo 1 trang duy nhất hiển thị nội dung theo ID.page.tsx nhưng hiển thị nội dung khác nhau dựa trên id trong URL.(auth) — Nhóm route (Route Group)
(auth) — Nhóm route (Route Group)
(auth) tạo nhóm logic nhưng không ảnh hưởng URL.layout.tsx — Khung chung cho nhiều trang
layout.tsx — Khung chung cho nhiều trang
/tasks sang /crm, layout gốc (header, sidebar, theme) giữ nguyên — chỉ phần nội dung chính thay đổi.api/ — Backend nhẹ trong cùng dự án
api/ — Backend nhẹ trong cùng dự án
api/ cho phép tạo API endpoint ngay trong dự án Next.js. Code này chạy trên server (Vercel), không lộ ra trình duyệt — phù hợp cho logic cần giữ bí mật.Mỗi Page chứa gì?
Một filepage.tsx thường chứa 3 phần:
2. Components — Khối xây dựng giao diện
Components là gì?
Components là mảnh ghép giao diện có thể tái sử dụng. Tạo một lần, ghép vào nhiều trang khác nhau, và khi sửa thì chỉ cần sửa ở một chỗ.Cấu trúc thư mục Components
Dự án chia components thành 2 nơi với vai trò khác nhau:components/ui/→ Viên gạch cơ bản, không biết nghiệp vụ (Button chỉ là nút bấm)features/tasks/components/→ Khối nghiệp vụ, hiểu dữ liệu task (TasksTable biết cách hiển thị danh sách tasks)
2 loại Components
UI Components (components/ui/) — Viên gạch cơ bản
UI Components (components/ui/) — Viên gạch cơ bản
Button chỉ biết nó là nút bấm, không biết bấm để làm gì. Tính năng do component cha quyết định.Ngoài ra, theme-provider.tsx quản lý chuyển đổi dark/light theme cho toàn ứng dụng.Feature Components (features/tasks/components/) — Khối nghiệp vụ
Feature Components (features/tasks/components/) — Khối nghiệp vụ
Components lồng nhau — Xây từ nhỏ đến lớn
Components được ghép lồng vào nhau từ đơn giản đến phức tạp, tạo thành giao diện hoàn chỉnh: Đọc từ trên xuống:- Page (
app/tasks/page.tsx) sử dụng Layout gốc (layout.tsx) - Page ghép Feature components (
TasksToolbar,TasksTable,TaskFormDialog) - Mỗi Feature component bên trong sử dụng các UI components (
Button,Table,Badge,Dialog)
3. Services — Kết nối dữ liệu
Services là gì?
Services là code giao tiếp với Firebase (hoặc bất kỳ nguồn dữ liệu nào). Chúng chứa các hàm đọc/ghi dữ liệu mà Hooks và Components gọi đến khi cần.Cấu trúc thư mục Services
Trong dự án này, services nằm bên trong thư mục feature, không phải ở cấp gốc:services/ ở gốc, dự án này đặt services cạnh components và hooks của cùng tính năng. Cách này giúp mỗi feature (tasks, crm, hrm) hoạt động như một module độc lập.Mỗi Service chứa gì?
Mỗi file service chứa một hàm thực hiện một thao tác cụ thể. Ví dụ cho tính năng Tasks:Chi tiết từng nhóm
lib/firebase.ts — Khởi tạo kết nối
lib/firebase.ts — Khởi tạo kết nối
.env.local) và tạo kết nối đến Firebase.lib/firebase.ts để sử dụng.features/tasks/services/ — CRUD tasks
features/tasks/services/ — CRUD tasks
app/api/notifications/route.ts — API Route
app/api/notifications/route.ts — API Route
route.ts trong thư mục api/ tạo API endpoint chạy trên server (Vercel). Code này không lộ ra trình duyệt — phù hợp cho logic cần giữ bí mật.Tại sao tách riêng Services?
4. Hooks — Logic tái sử dụng
Hooks là đoạn logic mà nhiều components cùng cần, được gói gọn vào hàm riêng để tái sử dụng. Trong dự án này, hooks nằm trong thư mục feature:useTasks làm gì? Nó gọi service get-tasks.ts bên trong, rồi bổ sung quản lý loading state, error handling. Khi trang Tasks cần dữ liệu, chỉ cần gọi useTasks() — có ngay danh sách tasks kèm trạng thái loading.
features/crm/hooks/use-customers.ts cho tính năng CRM.Cách các nhóm phối hợp với nhau
Đây là phần quan trọng: Pages, Components, Hooks và Services không hoạt động độc lập — chúng phối hợp theo luồng rõ ràng.Luồng hiển thị trang danh sách tasks
Luồng tạo task mới
Quy tắc phối hợp
Ví dụ thực tế: Trang danh sách tasks
Gộp tất cả lại, đây là cách trang danh sách tasks được “lắp ráp”:Mô tả cho Claude Code
Khi bạn hiểu cấu trúc Pages / Components / Services, việc mô tả yêu cầu cho Claude Code trở nên chính xác hơn: Thêm trang mới:Câu hỏi thường gặp
Khi nào thì tạo component mới, khi nào viết thẳng trong page?
Khi nào thì tạo component mới, khi nào viết thẳng trong page?
- Code đó sẽ dùng lại ở 2 nơi trở lên
- Khối giao diện phức tạp (nhiều hơn 30-40 dòng)
- Muốn tách isolate logic (form, bảng, bộ lọc)
- Code đơn giản, chỉ dùng 1 lần
- Chỉ là vài dòng ghép components có sẵn
Tại sao tách services ra khỏi components?
Tại sao tách services ra khỏi components?
getTasks(). Nếu code nằm trong component, phải copy-paste.Lý do 2 — Dễ thay đổi: Nếu sau này chuyển từ Firebase sang Supabase, bạn chỉ sửa file service — không cần sửa bất kỳ component nào.Lý do 3 — Dễ test: Service có thể được test độc lập, không cần render giao diện.Thư mục hooks/ khác gì services/?
Thư mục hooks/ khác gì services/?
useTasks() bên trong gọi service get-tasks.ts, rồi bổ sung quản lý loading state, error handling.Claude Code có tự tổ chức thư mục đúng không?
Claude Code có tự tổ chức thư mục đúng không?
Tóm tắt
Điểm mấu chốt: Dự án Next.js được tổ chức theo nguyên tắc feature-based — mỗi tính năng (tasks, crm) gom components, hooks và services vào cùng một thư mục. UI components dùng chung nằm trongcomponents/ui/, cấu hình chung nằm tronglib/. Hiểu cấu trúc này giúp bạn mô tả yêu cầu cho Claude Code chính xác hơn — biết cần thêm component ở đâu, sửa service nào, tạo page mới ra sao.
Thực hành tạo dự án
Phần này hướng dẫn bạn tạo một dự án quản lý công việc từ đầu — từ khởi tạo dự án Next.js đến kết nối Firebase. Mỗi bước kèm prompt mẫu để bạn gửi cho Claude Code.Khởi tạo dự án
Mở dự án trong VS Code
Chạy dự án
http://localhost:3000 để xem kết quả.Tạo trang login
app/login/page.tsx với form đăng nhập sử dụng các UI components từ shadcn/ui.Tạo trang quản lý công việc
Chuẩn hóa components theo feature
page.tsx ra thành các component riêng theo cấu trúc feature-based đã giới thiệu ở phần trước.Kết nối Firebase
- Truy cập Firebase Console
- Tạo project mới, đặt tên:
claude-code-tasks-management - Tạo Firestore Database
- Vào Project Settings → General → Your apps → Web và thêm web app
- Copy các thông số config
"..." bằng giá trị thật từ Firebase Console. Claude Code sẽ tạo lib/firebase.ts để khởi tạo kết nối và các service files trong features/tasks/services/ để thay thế mock data bằng dữ liệu thật từ Firestore.