Cấu trúc Dự án (Project Structure)
Agenda
Thời gian đọc ước tính: ~20 phút
Learning Outcomes
- Hiểu được triết lý định tuyến dựa trên hệ thống tệp (File-system routing) của Next.js.
- Phân biệt được các tệp quy ước đặc biệt (Special Routing Files) như
page.tsx,layout.tsx,loading.tsx, v.v. - Giải thích được cơ chế Colocation (Đặt cùng vị trí) giúp tổ chức code gọn gàng, an toàn.
- Áp dụng được các mẫu thiết kế cấu trúc thư mục nâng cao: Route Groups, Private Folders, và Intercepting Routes.
Glossary & Vocabulary
1. Technical Terms (Thuật ngữ kỹ thuật):
| Term | Vietnamese Meaning & Quick Explain |
|---|---|
| File-system Routing | Định tuyến dựa trên hệ thống tệp. URL của ứng dụng được quyết định bởi tên và vị trí của thư mục trong mã nguồn. |
| Colocation | Đặt cùng vị trí. Cho phép đặt các file không liên quan đến routing (ví dụ: components, utils) cùng thư mục với các file routing mà không làm lộ URL ra public. |
| Route Segments | Phân đoạn đường dẫn. Mỗi thư mục đóng vai trò như một phần của URL (ví dụ: /shop/clothing gồm 2 phân đoạn shop và clothing). |
| Private Folders | Thư mục riêng tư (bắt đầu bằng dấu _). Các thư mục này và toàn bộ nội dung bên trong sẽ bị loại khỏi hệ thống routing. |
| Route Groups | Nhóm định tuyến (bọc trong ngoặc đơn, ví dụ (shop)). Giúp tổ chức thư mục mã nguồn mà không ảnh hưởng đến cấu trúc URL thực tế. |
2. Vocabulary Support (Từ vựng học thuật/B1+):
| Word | Meaning in Context (Nghĩa trong ngữ cảnh) |
|---|---|
| Unopinionated (adj) | Không áp đặt khuôn mẫu cố định. Framework cho phép developer tự do cấu trúc thư mục theo ý muốn. |
| Colocate (v) | Đặt cùng vị trí. Hành động gom nhóm các thành phần liên quan (logic, UI, CSS) lại gần nhau. |
| Hierarchy (n) | Hệ thống phân cấp. Cách các component lồng vào nhau theo chiều dọc từ ngoài vào trong. |
| Intersect (v) | Giao nhau, chặn ngang (trong ngữ cảnh Intercepting Routes). |
| Parameterize (v) | Tham số hóa. Biến một đoạn URL cố định thành một biến có thể nhận nhiều giá trị (dynamic). |
1. WHY — Tại sao cấu trúc của Next.js App Router lại đặc biệt?
Vấn đề phát sinh với React thuần và Pages Router cũ:
- Routing phức tạp ở React thuần: Bạn phải bảo trì một file cấu hình định tuyến khổng lồ (thường là
App.jsvớireact-router), quản lý thủ công từng đường dẫn URL đến từng component. Khi dự án lớn lên, việc theo dõi URL nào gọi đến component nào trở thành cực hình. - Hạn chế của Pages Router (Next.js cũ): Bất kỳ file nào đặt trong thư mục
pages/đều tự động trở thành một URL công khai (public route). Điều này khiến developer không thể đặt các file component dùng chung, file utils hay file test nằm cạnh trang (page) tương ứng. Họ phải tạo các thư mục song song ở ngoài, dẫn đến việc phải import các thành phần với đường dẫn tương đối dài dòng (../../../components/Button).
Cách Next.js App Router giải quyết vấn đề:
Next.js giới thiệu mô hình Routing dựa trên thư mục (Folder-based Routing) kết hợp với cơ chế Colocation.
- Thư mục quyết định đường dẫn (URL).
- Tệp đặc biệt (
page.tsx,route.ts) quyết định nội dung sẽ hiển thị. Nhờ vậy, định tuyến trở nên rõ ràng và bạn có thể gom nhóm mọi thứ liên quan đến một chức năng vào cùng một vị trí mà không sợ lộ URL trái phép.
2. WHAT — Giải phẫu hệ thống cấu trúc tệp
Định nghĩa File-system routing trong App Router: Là cơ chế trong đó các thư mục lồng nhau (nested folders) xác định cấu trúc của URL, và các tệp quy ước (convention files) đóng vai trò dựng hình Giao diện Người dùng (UI) hoặc xử lý Logic API cho URL đó.
2.1. Definition Anatomy (Giải phẫu định nghĩa)
- nested folders (các thư mục lồng nhau): Nếu bạn có thư mục
app/blog/tech, URL tương ứng sẽ là/blog/tech. - convention files (các tệp quy ước): Các tệp có tên cố định mang chức năng đặc thù mà Next.js hiểu sẵn (như
layout.js,page.js,loading.js). Tên khác sẽ bị Next.js "lờ đi" trong việc định tuyến. - dựng hình Giao diện (UI) hoặc xử lý Logic API:
page.tsxtrả về HTML/UI, cònroute.tstrả về dữ liệu (JSON, Text) như một API đích thực.
2.2. Phân cấp thư mục cấp cao nhất (Top-level folders)

app: Chứa toàn bộ logic ứng dụng và routing của hệ thống App Router mới.pages: Dùng cho hệ thống định tuyến cũ (Pages Router). Bạn không nên dùng song song trừ khi đang migrate hệ thống cũ.public: Chứa các tài sản tĩnh (static assets) như hình ảnh, font chữ. Trình duyệt có thể truy cập trực tiếp bằng đường dẫn gốc/.src(tùy chọn): Thư mục nguồn (chứaapp). Giúp tách biệt mã nguồn khỏi các tệp cấu hình nằm ở gốc thư mục dự án.
2.3. Các tệp cấu hình cấp cao nhất (Top-level files)
Các file này nằm ở thư mục gốc của project (bên cạnh package.json):
next.config.js/next.config.ts: File cấu hình lõi của Next.js.instrumentation.ts: File cấu hình OpenTelemetry và các công cụ theo dõi hiệu suất.proxy.ts: Cấu hình Proxy để chuyển tiếp request..env,.env.local,.env.production: File chứa biến môi trường.eslint.config.mjs: Cấu hình ESLint để kiểm tra chất lượng code.
2.4. Tệp Định tuyến Quy ước (Routing Files)
Để hiển thị UI hoặc API cho một URL segment, bạn CẦN sử dụng một trong các tệp quy ước sau:
layout.tsx: Bố cục chia sẻ chung cho thư mục hiện tại và mọi thư mục con.page.tsx: Nội dung giao diện (Page) duy nhất của thư mục đó (Công khai ra internet).loading.tsx: Giao diện hiển thị trong lúc chờ tải dữ liệu (Loading UI).not-found.tsx: Giao diện lỗi 404 tùy chỉnh.error.tsx: Giao diện bắt lỗi (Error Boundary) nếu có crash trong component.global-error.tsx: Giao diện bắt lỗi toàn cục (hiếm dùng).route.ts: API Endpoint (Xử lý các request GET, POST, PUT...). Không thể nằm chung thư mục vớipage.tsx.template.tsx: Giốnglayout.tsxnhưng re-render lại toàn bộ mỗi khi điều hướng.default.tsx: Giao diện dự phòng dùng trong định tuyến song song (Parallel Routes).
2.5. Tệp Metadata (Metadata file conventions)
Next.js tự động nhận diện các tệp tĩnh dưới đây để sinh meta tag chuẩn SEO:
- App icons:
favicon.ico,icon.png/jpg/svg,apple-icon.png(Hoặc dùngicon.tsxđể generate động). - Open Graph:
opengraph-image.jpg,twitter-image.png. - SEO:
sitemap.xml,robots.txt(Hoặc dùng file.tsđể tự động tạo).
3. HOW — Tổ chức kiến trúc dự án thực tế
Next.js hoàn toàn Unopinionated (Không gò ép) trong việc tổ chức thư mục bên trong app/. Dưới đây là các cơ chế quan trọng giúp bạn tối ưu hóa kiến trúc.