Skip to content

9 điều cơ bản đầu tiên khi đến với Next.js

Next.js không thay thế React — nó là một framework xây dựng trên nền React, bổ sung những thứ mà React “vanilla” không có sẵn: Server-Side Rendering (SSR), file-based routing, tối ưu hình ảnh, và nhiều hơn nữa.
Bạn đã quen với React — tạo component, quản lý state, render UI. Nhưng khi ứng dụng cần SEO tốt hơn, tốc độ tải trang nhanh hơn, hay routing không cần cài thêm thư viện… bạn bắt đầu nghe đến Next.js.
Next.js không thay thế React — nó là một framework xây dựng trên nền React, bổ sung những thứ mà React “vanilla” không có sẵn: Server-Side Rendering (SSR), file-based routing, tối ưu hình ảnh, và nhiều hơn nữa.
Bài viết này tóm tắt 11 khái niệm cốt lõi bạn sẽ gặp ngay trong bất cứ buổi học đầu tiên nào về Next.js.

1. Làm quen với “file-based routing”: tạo route bằng folder

Với React Router, bạn phải khai báo route bằng code.
Next.js làm điều đó theo cách khác: cấu trúc thư mục chính là routing.
/app
├── page.js → example.com/
├── /about
│ └── page.js → example.com/about
└── /blog
├── page.js → example.com/blog
└── /post-1
└── page.js → example.com/blog/post-1
Mỗi thư mục là một segment của URL. Muốn có route mới? Tạo thư mục mới và đặt page.js bên trong.

2. Hai “reserved files” quan trọng nhất: page.jslayout.js

Next.js có một hệ thống reserved filenames — những tên file đặc biệt mà framework nhận ra và xử lý theo cách riêng.
Hai file cơ bản nhất:
page.js — định nghĩa nội dung của một trang, đây là file bắt buộc để một route được render.
layout.js — định nghĩa “khung” bao quanh trang, ví dụ header, footer, sidebar. Layout lồng nhau (nested layout) cũng được hỗ trợ — layout.js trong thư mục con chỉ áp dụng cho trang đó và các trang con của nó.
/app
├── layout.js ← app shell (master layout, bao toàn bộ app)
├── page.js
└── /about
├── layout.js ← nested layout, chỉ áp dụng cho /about
└── page.js
Trong layout.js thường có metadata, thẻ <html><body>, và {children} — placeholder để render các trang con.

3. Các reserved filenames khác cần biết

Next.js còn nhiều tên file đặc biệt khác:
File
Tác dụng
not-found.js
Hiển thị khi route không tồn tại (lỗi 404)
error.js
Fallback khi có lỗi xảy ra
loading.js
Hiển thị trong khi trang đang fetch data
route.js
Tạo API endpoint (trả về JSON, không phải JSX)
icon.png
Tự động dùng làm favicon
There are no rows in this table
Chi tiết đầy đủ tại .

4. Component <Link> — navigate thông minh hơn

Thay vì dùng thẻ <a> thông thường, Next.js cung cấp component <Link>:
import Link from 'next/link';

<Link href="/about">About</Link>
Điểm hay của việc sử dụng Link là khi truy cập trực tiếp vào URL, Next.js sẽ SSR (render phía server).
Khi bạn đang đứng trong ứng dụng và click link, nó chuyển sang CSR — chỉ load phần component của route mới, không reload toàn trang. Tốt nhất của cả hai thế giới.

5. Dynamic Routes — route với tham số động

Để xử lý các URL dạng /blog/post-1, /blog/post-2… bạn có thể dùng dynamic segment bằng cách đặt tên thư mục trong dấu ngoặc vuông:
/app
└── /blog
├── page.js
└── /[slug]
└── page.js → example.com/blog/:slug
Trong component, params được truyền vào như một prop mặc định:
export default function BlogDetail({ params }) {
return <p>{params.slug}</p>;
}

6. Tổ chức file — /components nên đặt ngoài /app

Thư mục /app chỉ nên chứa các routing files. Custom components nên đặt bên ngoài thư mục /app:
/app
├── layout.js
└── page.js

/components ← đặt ở ngoài /app
└── header.js
Lý do: thư mục trong /app mà không có page.js sẽ không tạo ra route — nhưng để tránh nhầm lẫn, tốt hơn là tách biệt hoàn toàn.
Để import cho gọn, dùng path alias @ bằng cách cấu hình jsconfig.json:
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}
Sau đó import như sau: import Header from '@/components/header'.

7. CSS Modules — tránh xung đột class name

Bên cạnh global.css như mọi app, Next.js hỗ trợ sẵn CSS Modules. Mỗi component có file CSS riêng:
/components
├── header.js
└── header.module.css
import classes from '@/components/header.module.css';

<Link className={classes.logo} href="/">Home</Link>
Class name sẽ được tự động scope theo component, tránh hoàn toàn việc “trùng tên class” giữa các component khác nhau.

8. Component <Image> — tối ưu hình ảnh tự động

Đừng dùng thẻ <img> thông thường trong Next.js. Hãy dùng <Image> từ next/image:
import Image from 'next/image';
import logo from '@/assets/logo.png';

<Image src={logo} priority />
Next.js tự động xử lý: lazy loading, tối ưu chất lượng và kích thước, sinh srcset cho responsive…
Thêm prop priority cho những ảnh quan trọng (hiển thị ngay khi load trang, không lazy load).
Lưu ý quan trọng: Chỉ những ảnh được import tĩnh (xử lý lúc build time) mới tận dụng được đầy đủ tính năng này.
Ảnh lấy từ database lúc runtime sẽ không có sẵn metadata width, height — bạn cần truyền thủ công hoặc dùng prop fill.

9. Server Components và Client Components

Đây là khái niệm khác biệt lớn nhất so với React thuần.
Với create-react-app, tất cả component đều là Client Components — chạy trên browser.
Với Next.js, tất cả component mặc định là React Server Components (RSC) — render phía server.
Bằng chứng đơn giản: thử console.log trong một component Next.js — bạn sẽ thấy log xuất hiện ở terminal của dev server, không phải trong DevTools của browser.
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.