Trong App Router, một component không có directive gì ở đầu file là loại nào?
A.Server Component — đây là mặc định trong App Router
B.Component lai, chạy cả hai phía tùy theo hook được dùng bên trong
C.Client Component — mọi component React đều chạy ở trình duyệt trừ khi đánh dấu 'use server'
D.Next.js tự phân tích code và quyết định, không có mặc định
Đáp án: A
Server Component — mặc định của App Router. Nó chạy trên server, không gửi JavaScript của mình xuống client, truy cập trực tiếp được database và biến môi trường bí mật. Thêm 'use client' khi cần state, effect hoặc sự kiện trình duyệt.
Trong App Router, file nào định nghĩa giao diện của một route?
A.page.tsx — chỉ thư mục nào có file này mới trở thành một route truy cập được; các file khác trong thư mục không tự tạo route
B.route.tsx — dùng cho cả giao diện lẫn API
C.index.tsx, giống quy ước của Pages Router
D.Bất kỳ file .tsx nào trong thư mục app/ đều tự thành một route
Đáp án: A
page.tsx. Trong App Router chỉ các tên file quy ước mới có ý nghĩa: page (giao diện route), layout (khung bao quanh), loading, error, not-found, route (API). File thường đặt chung thư mục sẽ không tạo route — nên component đặt cạnh trang được.
Trong App Router, cách lấy dữ liệu cho một trang tĩnh phía server là gì?
A.Phải tạo một Route Handler rồi gọi fetch tới chính nó
B.Khai báo component là async rồi await ngay trong thân nó
C.Dùng useEffect để gọi API sau khi component mount
D.Vẫn export getServerSideProps như trước, App Router giữ nguyên API này
Đáp án: B
Cho component async và await trực tiếp. Server Component chạy trên server nên gọi thẳng database hay API nội bộ được. getServerSideProps và getStaticProps chỉ thuộc Pages Router, không dùng trong App Router.
Trong App Router, tạo một API endpoint bằng cách nào?
A.Khai báo trong next.config.js phần api
B.Đặt file trong pages/api/ như Pages Router — App Router không hỗ trợ API
C.Export hàm handler mặc định từ page.tsx
D.Tạo file route.ts trong thư mục tương ứng và export hàm theo tên HTTP method: GET, POST, PUT, DELETE...
Đáp án: D
File route.ts với các hàm export tên đúng HTTP method. app/api/users/route.ts phục vụ /api/users. Hàm nhận và trả về Web Request/Response chuẩn, không phải object riêng của Next.js như pages/api.
Dùng next/image thay cho thẻ <img> mang lại lợi ích chính nào?
A.Tự đổi định dạng, tạo nhiều kích thước, lazy load, giữ chỗ đúng tỉ lệ
B.Tự tải ảnh lên CDN khi build
C.Nén ảnh trong repository để giảm dung lượng khi clone
D.Cho phép dùng ảnh mà không cần biết kích thước, khác với <img>
Đáp án: A
next/image phục vụ ảnh đã tối ưu: định dạng hiện đại theo trình duyệt, kích thước phù hợp thiết bị, lazy load mặc định, và bắt buộc khai báo kích thước để giữ chỗ trước — trực tiếp cải thiện LCP và CLS trong Core Web Vitals.
Component nào sau đây BẮT BUỘC phải có 'use client'?
A.Component async gọi database rồi render danh sách
B.Component chỉ nhận prop và render JSX tĩnh
C.Component đọc biến môi trường bí mật để dựng URL nội bộ
D.Component dùng useState để mở/đóng một dropdown và có onClick trên nút
Đáp án: D
Cần 'use client' khi component dùng state/effect, trình xử lý sự kiện, hoặc API trình duyệt (window, localStorage). Không cần khi chỉ lấy dữ liệu và render — và tuyệt đối không đưa đoạn đọc bí mật xuống client.
Thư mục (marketing) và _components trong app/ khác nhau thế nào?
A.(marketing) chỉ dùng cho trang marketing theo quy ước của Next.js
B._components tạo route bắt đầu bằng dấu gạch dưới trong URL
C.Cả hai đều bị loại khỏi URL, chỉ khác quy ước đặt tên
D.(marketing) là route group — tên trong ngoặc KHÔNG xuất hiện trong URL nhưng bên trong vẫn tạo route
Đáp án: D
Ngoặc đơn (tên) nhóm các route lại để dùng chung layout mà không thêm đoạn nào vào URL. Gạch dưới _tên loại thư mục khỏi routing hoàn toàn — dùng để đặt component, helper cạnh nơi sử dụng mà không sợ thành route.
error.tsx trong App Router có yêu cầu bắt buộc nào?
A.Chỉ được đặt ở thư mục gốc app/, không đặt được ở route con
B.Phải là Client Component và nhận prop reset
C.Phải là Server Component để đọc được thông tin lỗi từ server
D.Phải export một hàm tên handleError
Đáp án: B
error.tsx bắt buộc 'use client' vì error boundary là cơ chế phía client. Nó nhận error và reset. Điểm hay quên: nó không bắt được lỗi phát sinh trong layout.tsx CÙNG CẤP — muốn bắt thì phải đặt error.tsx ở cấp cha.
Biến môi trường nào đọc được từ code chạy trong trình duyệt?
A.Chỉ những biến có tiền tố NEXT_PUBLIC_
B.Không biến nào — client phải gọi API để lấy cấu hình
C.Mọi biến trong .env.local đều đọc được ở cả hai phía
D.Chỉ biến khai báo trong next.config.js
Đáp án: A
Chỉ biến bắt đầu bằng NEXT_PUBLIC_. Next.js thay giá trị của chúng thẳng vào bundle lúc build. Biến không có tiền tố chỉ đọc được ở Server Component, Route Handler, Server Action — vì thế DATABASE_URL không bao giờ rơi xuống trình duyệt.
Dùng next/font thay vì nhúng thẻ <link> tới Google Fonts mang lại lợi ích gì?
A.Cho phép dùng font trả phí miễn phí
B.Font được nén mạnh hơn nên tải nhanh hơn
C.Font tải về và phục vụ từ domain của bạn ngay lúc build
D.Font chỉ tải khi người dùng cuộn tới phần dùng nó
Đáp án: C
next/font tải font lúc build và phục vụ từ domain của bạn — bỏ được một lần kết nối tới máy chủ bên thứ ba. Quan trọng hơn, nó tự tính và chèn fallback có kích thước khớp, nên khi font thật hiện lên chữ không nhảy — cải thiện trực tiếp chỉ số CLS.
A.next/router — vẫn là đường dẫn chung cho cả hai router
B.next/link — cùng module với component điều hướng
C.next/navigation — bản từ next/router chỉ dành cho Pages Router
D.react-router-dom — Next.js dùng lại thư viện này
Đáp án: C
Từ module điều hướng của App Router. Bản trong module cũ chỉ dành cho hệ định tuyến trước và gây lỗi lúc chạy nếu import nhầm — thông báo lỗi lại không nói rõ nguyên nhân nên rất dễ mất thời gian.
Chế độ phát triển biên dịch theo yêu cầu và cập nhật ngay khi sửa mã, nhưng chậm và chưa tối ưu. Chế độ chạy thật phục vụ bản đã dựng sẵn: mã được nén, trang tĩnh đã dựng, và hiệu năng phản ánh đúng production.
Thư mục public/ trong dự án Next.js dùng để làm gì?
A.Chứa kết quả sau khi chạy lệnh dựng
B.Chứa mã nguồn dùng chung giữa client và server
C.Phục vụ file tĩnh theo đường dẫn gốc
D.Chứa các trang công khai không cần đăng nhập
Đáp án: C
Nó phục vụ file tĩnh theo đường dẫn từ gốc: một file đặt ở đó truy cập được ngay qua đường dẫn tương ứng. File không qua bước xử lý nào của trình dựng nên không được tối ưu hay đánh dấu phiên bản.
Nó phải nhận và render prop children. Nội dung của các route con được truyền vào qua prop này, nên quên render nó khiến mọi trang bên dưới hiển thị trống mà không có lỗi nào.
Dùng <Link href="/about"> thay thẻ <a href="/about"> được lợi gì?
A.Tự động thêm thuộc tính bảo mật cho liên kết
B.Kiểm tra đường dẫn có tồn tại trước khi chuyển
C.Chỉ hoạt động với các trang tĩnh
D.Điều hướng phía client, không tải lại trang
Đáp án: D
Nó điều hướng phía client: chỉ phần thay đổi được lấy về và render thay vì tải lại cả trang. Trạng thái ứng dụng được giữ, chuyển trang nhanh hơn nhiều, và Next.js còn tải trước nội dung khi liên kết vào tầm nhìn.
File not-found.tsx trong App Router có tác dụng gì?
A.Chuyển hướng người dùng về trang chủ
B.Chặn truy cập vào route chưa được khai báo
C.Hiển thị giao diện khi route không có
D.Ghi lại các đường dẫn bị lỗi để phân tích
Đáp án: C
Nó hiển thị giao diện khi route không tồn tại — cả khi đường dẫn không khớp route nào, và khi mã chủ động gọi hàm báo không tìm thấy, ví dụ khi truy vấn không thấy bản ghi tương ứng.
A.Không, vì kết nối database không giữ được giữa các lần render
B.Được, vì mã chỉ chạy ở phía server
C.Không, phải luôn gọi qua một API endpoint
D.Được, nhưng phải bọc trong khối kiểm tra môi trường
Đáp án: B
Được, và đó là một trong những lợi ích chính. Mã của loại component này không bao giờ được gửi xuống trình duyệt, nên thông tin kết nối và câu truy vấn không bị lộ, và không cần thêm một lớp API ở giữa.
Import ảnh từ mã nguồn khác đặt ảnh trong public/ thế nào?
A.Ảnh import biết sẵn kích thước, tên có mã băm
B.Ảnh import chỉ dùng được ở Server Component
C.Ảnh import được nén mạnh hơn khi dựng
D.Ảnh trong thư mục công khai tải nhanh hơn
Đáp án: A
Ảnh import được trình dựng xử lý: nó biết sẵn chiều rộng và chiều cao nên tránh được hiện tượng bố cục nhảy, và tên file có mã băm nên lưu đệm được vĩnh viễn. Ảnh trong thư mục công khai thì phải tự khai báo kích thước.
Nó khai báo cấu hình build và hành vi framework: chuyển hướng, viết lại đường dẫn, tên miền ảnh được phép, chế độ xuất bản, tiêu đề HTTP. File được đọc lúc dựng và lúc khởi động, không đọc lại theo từng yêu cầu.
Một dự án có cả thư mục app/ và pages/. Điều gì xảy ra?
A.Thư mục cũ bị bỏ qua hoàn toàn
B.Chỉ thư mục xuất hiện trước theo bảng chữ cái được dùng
C.Cả hai cùng chạy, app/ ưu tiên khi trùng
D.Quá trình dựng thất bại vì xung đột cấu hình
Đáp án: C
Cả hai cùng chạy, và khi trùng đường dẫn thì thư mục mới được ưu tiên. Đây là thiết kế có chủ ý để chuyển đổi dần từng route, thay vì phải viết lại toàn bộ ứng dụng trong một lần.
File có 'use client' import một component khác. Component được import đó chạy ở đâu?
tsx
// app/dashboard/panel.tsx'use client'import { Chart } from'./chart'// chart.tsx không có directiveexportfunctionPanel() {
const [open, setOpen] = useState(false)
return<Chart />
}
A.Next.js báo lỗi build vì trộn hai loại component
B.Ở server lần render đầu, sau đó chuyển sang client
C.Ở server, vì bản thân chart.tsx không có 'use client'
D.Ở client — 'use client' đánh dấu ranh giới cho cả cây dưới nó
Đáp án: D
'use client' là ranh giới chứ không phải nhãn cho một file. Mọi thứ được import xuống dưới ranh giới đó đều thành Client Component. Muốn giữ một phần ở server bên trong cây client thì truyền nó xuống qua prop children chứ không import.
Người dùng điều hướng giữa /posts/1 và /posts/2, cả hai cùng nằm dưới app/posts/layout.tsx. Layout có bị render lại không?
A.Không — layout giữ nguyên state và không render lại
B.Có — mỗi lần đổi URL thì toàn bộ cây từ root layout xuống đều render lại
C.Có, trừ khi bọc layout trong React.memo
D.Không, và cả children cũng không đổi vì cùng một layout
Đáp án: A
Không. Layout giữ nguyên qua các lần điều hướng trong phạm vi của nó — state, scroll position, input đang gõ đều còn. Chỉ children được thay bằng nội dung route mới. Đây là lý do sidebar hay audio player đặt trong layout không bị reset.
C.Kiểm tra tính hợp lệ của tham số và trả 404 khi giá trị không nằm trong danh sách
D.Liệt kê trước giá trị tham số động để dựng sẵn trang lúc build
Đáp án: D
Nó cho Next.js biết trước cần dựng sẵn những trang nào lúc build. Với /posts/[slug], trả về danh sách slug thì mỗi slug được render thành HTML tĩnh — phục vụ nhanh từ CDN, tốt cho SEO. Đây là bản thay thế getStaticPaths của Pages Router.
Trang dùng cookies() hoặc headers() thì được render theo kiểu nào?
A.Dynamic — hai hàm này phụ thuộc vào request cụ thể
B.Tùy next.config.js, mặc định vẫn là static
C.Static, nhưng phần dùng cookie được điền vào phía client sau khi tải
D.Vẫn static, vì Next.js chụp lại cookie tại thời điểm build
Đáp án: A
Dynamic. cookies(), headers(), searchParams và connection() đều phụ thuộc vào request nên không thể dựng sẵn HTML — dùng bất kỳ cái nào là cả route chuyển sang render theo request. Muốn giữ phần còn lại tĩnh thì cô lập phần động vào một component bọc <Suspense>.
A.Next.js tạo sẵn một endpoint nội bộ cho hàm này; client gửi request tới đó, hàm chạy trên server và revalidatePath làm mới cache của /posts
B.Hàm được bundle xuống client và chạy trong trình duyệt như một handler thường
C.Hàm chỉ chạy lúc build, không xử lý được submit lúc chạy
D.Cần tạo thêm một Route Handler thì form mới gửi được dữ liệu đi
Đáp án: A
Next.js sinh một endpoint riêng cho hàm đó. Client gửi request tới endpoint, hàm chạy trên server với đầy đủ quyền truy cập database, rồi revalidatePath xóa cache để trang hiển thị dữ liệu mới. Code hàm không đi xuống trình duyệt.
Câu 6·Server & Client Components· chọn nhiều đáp án
Những phát biểu nào sau đây đúng về Server Component? (chọn nhiều đáp án)
A.Server Component dùng được useState và useEffect miễn là component đó async
B.Prop truyền từ Server Component sang Client Component phải serialize được — truyền một function thường sẽ lỗi
C.Server Component đọc được biến môi trường bí mật và gọi thẳng database mà không lộ ra client
D.Code và thư viện chỉ dùng trong Server Component không đi vào bundle của client
Đáp án: B, C, D
Server Component không gửi code xuống client, truy cập được bí mật và database, nhưng không có hook và không xử lý sự kiện. Dữ liệu truyền qua ranh giới sang Client Component phải serialize được — function không qua được, trừ Server Action.
Đặt file loading.tsx trong một thư mục route có tác dụng gì?
A.Next.js tự bọc page.tsx của thư mục đó trong <Suspense> với fallback là component này
B.Nó chỉ hoạt động khi được import và render thủ công trong page.tsx
C.Nó hiển thị trong lúc trình duyệt tải file JavaScript của trang, không liên quan tới dữ liệu
D.Nó thay thế page.tsx khi việc lấy dữ liệu thất bại
Đáp án: A
loading.tsx là fallback của một <Suspense> mà Next.js tự đặt quanh route. Trang được stream: vỏ tĩnh cùng giao diện chờ hiện ngay, nội dung thật thay vào khi dữ liệu server xong. Người dùng thấy phản hồi tức thì thay vì màn hình trắng.
Middleware trong Next.js chạy ở thời điểm nào và hợp với việc gì?
A.Chạy sau khi trang render xong, dùng để sửa HTML trước khi gửi đi
B.Chạy lúc build, dùng để sinh danh sách route
C.Chạy trước khi request tới route, hợp cho việc nhẹ và nhanh: chuyển hướng, viết lại đường dẫn, đặt header, kiểm tra sơ bộ cookie phiên đăng nhập
D.Chỉ chạy cho các route trong app/api, không áp dụng cho trang
Đáp án: C
Middleware chạy trước khi request được xử lý bởi route. Hợp cho việc nhẹ: redirect, rewrite, set header, kiểm tra nhanh cookie. Vì nằm trên đường đi của mọi request nên tránh truy vấn database hay logic nặng ở đây.
Trang chi tiết sản phẩm cần title và Open Graph riêng theo từng sản phẩm. Làm thế nào trong App Router?
A.Dùng useEffect để gán document.title sau khi trang mount
B.Export hàm generateMetadata từ page.tsx
C.Khai báo tĩnh trong next.config.js cho từng đường dẫn
D.Vẫn dùng component <Head> của next/head như Pages Router
Đáp án: B
Export generateMetadata từ page.tsx. Nó nhận params, await được dữ liệu, và trả về object metadata. Next.js render thẻ meta ngay trong HTML server nên crawler và bộ xem trước link đọc được. Metadata tĩnh thì export hằng metadata.
Thư viện biểu đồ nặng 300KB chỉ dùng ở một tab ít người mở. Cách nào giảm bundle ban đầu?
A.next/dynamic để tách thư viện ra chunk riêng và chỉ tải khi component đó thực sự render
B.Thêm thư viện vào next.config.js phần transpilePackages
C.Bọc component trong <Suspense> là đủ để tách code
D.Đặt thư viện vào devDependencies để không đóng gói vào production
Đáp án: A
next/dynamic: const Chart = dynamic(() => import('./chart')). Thư viện được tách thành chunk riêng, chỉ tải khi component render. Thêm { ssr: false } khi thư viện đụng window, và loading để có giao diện chờ.
Bọc một async Server Component trong <Suspense> cho hiệu quả gì?
A.Phần còn lại hiển thị ngay, phần này stream tới sau
B.Dữ liệu được cache lại nên lần sau không phải fetch nữa
C.Lỗi trong component được bắt lại thay vì làm hỏng cả trang
D.Component được chuyển sang chạy phía client
Đáp án: A
Phần còn lại của trang được gửi về và hiển thị ngay, còn phần bên trong ranh giới được stream tới sau khi dữ liệu sẵn sàng. Không có nó, toàn trang phải chờ truy vấn chậm nhất mới gửi được byte đầu tiên.
Truyền một function làm prop từ Server Component sang Client Component thì sao?
A.Function chạy được nhưng mất closure của nó
B.Component tự động chuyển sang chạy phía server
C.Lỗi — prop phải serializable, trừ Server Action
D.Function được gửi dưới dạng chuỗi rồi eval lại ở client
Đáp án: C
Lỗi lúc chạy. Props vượt ranh giới phải serialize được vì chúng đi qua mạng dưới dạng dữ liệu. Ngoại lệ duy nhất là hành động máy chủ — chúng được biến thành một tham chiếu mà client gọi ngược lại được.
A.Context hoạt động bình thường ở cả hai loại component
B.Provider phải đặt trong từng page thay vì trong layout
C.Provider phải là Client Component, và Server Component không đọc được context
D.Context chỉ dùng được cho dữ liệu nguyên thuỷ
Đáp án: C
Nhà cung cấp bắt buộc là thành phần client, và thành phần máy chủ không đọc được ngữ cảnh. Cách đúng là tạo một tệp riêng có directive 'use client' cho nhà cung cấp, rồi đặt nó ở layout gốc bọc quanh nội dung con.
A.Gây lỗi build khi một module chỉ dành cho server bị import vào client
B.Chuyển các lời gọi API sang chạy ở server để tránh CORS
C.Nén các module server để giảm dung lượng bản build
D.Đánh dấu component chạy phía server thay cho directive
Đáp án: A
Nhập gói này vào một module khiến việc import module đó từ mã phía client gây lỗi lúc build. Đây là một rào chắn: không có nó, một lần import nhầm có thể đưa khoá bí mật vào bản gửi tới trình duyệt.
B.Template được mount lại mỗi lần điều hướng; layout thì không
C.Template chạy phía client còn layout chạy phía server
D.Template chỉ áp dụng cho route động còn layout cho route tĩnh
Đáp án: B
Layout giữ nguyên khi điều hướng giữa các trang bên trong nó, còn template bị dựng lại mỗi lần. Nhờ đó chạy lại được hiệu ứng vào trang, hoặc đặt lại trạng thái ở mỗi lần chuyển route.
B.Dạng hai ngoặc chỉ dùng được trong route handler
C.Dạng hai ngoặc chỉ khớp tối đa hai segment
D.Dạng một ngoặc khớp query string còn dạng hai khớp path
Đáp án: A
Dạng một cặp ngoặc yêu cầu ít nhất một đoạn đường dẫn. Dạng hai cặp ngoặc khớp cả trường hợp không có đoạn nào — tức là chính đường dẫn gốc của thư mục đó cũng khớp.
Gọi notFound() trong một Server Component gây ra gì?
A.Chuyển hướng người dùng về trang chủ
B.Ném một exception mà bạn phải tự bắt lại
C.Dừng render, trả status 404 và hiện not-found.tsx
D.Trả về trang trống với status 200
Đáp án: C
Nó dừng việc render, hiển thị tệp không tìm thấy gần nhất trong cây route, và trả về mã trạng thái 404. Trả đúng mã trạng thái quan trọng với SEO vì công cụ tìm kiếm sẽ không lập chỉ mục trang đó.
A.Nó bắt cả lỗi trong root layout nên phải tự render thẻ html và body
B.Nó chỉ hoạt động trong môi trường phát triển
C.Nó bắt lỗi ở cả phía server lẫn phía client, còn file kia chỉ bắt client
D.Nó không cần directive 'use client' còn file kia thì cần
Đáp án: A
Nó bắt cả lỗi xảy ra trong layout gốc — nơi tệp lỗi thông thường không với tới. Vì layout gốc chưa render được nên tệp này phải tự render các thẻ khung của tài liệu HTML.
Trong Next.js 15, params và searchParams của page có gì thay đổi?
A.Chúng bị gộp lại thành một object duy nhất
B.Chúng chỉ còn đọc được trong Client Component
C.Chúng trở thành Promise nên phải await trước khi đọc
D.Chúng bị bỏ, thay bằng một hook mới
Đáp án: C
Chúng trở thành promise nên phải chờ trước khi đọc. Thay đổi này mở đường cho việc render phần tĩnh của trang trước khi biết giá trị của chúng — nền tảng của cơ chế dựng sẵn một phần.
Dùng useSearchParams() khiến build báo lỗi về Suspense. Vì sao?
A.Hook này chỉ dùng được trong Server Component
B.Hook này đọc dữ liệu bất đồng bộ nên cần ranh giới chờ
C.Hook này xung đột với việc dùng directive 'use client'
D.Nó làm component phụ thuộc request nên cần Suspense
Đáp án: D
Vì nó làm thành phần phụ thuộc vào request cụ thể. Bọc trong một ranh giới chờ cho phép Next dựng tĩnh phần còn lại của trang và chỉ để phần này chờ tới lúc chạy — không có ranh giới thì cả trang bị đẩy sang render động.
A.Tự prefetch khi link vào viewport ở production, tắt được bằng prop
B.Không prefetch; nó chỉ là thẻ neo có xử lý điều hướng
C.Prefetch mọi link trên trang ngay khi trang tải xong
D.Chỉ prefetch khi người dùng rê chuột lên link
Đáp án: A
Nó tự tải trước khi liên kết lọt vào vùng nhìn thấy, và chỉ hoạt động ở môi trường sản xuất. Nhờ đó chuyển trang gần như tức thì — đổi lại tốn thêm request cho các liên kết người dùng không bấm tới.
generateMetadata khác export metadata tĩnh ở điểm nào?
A.Nó ghi đè metadata của layout còn cách kia thì gộp vào
B.Là hàm async nhận params nên tạo metadata theo dữ liệu
C.Nó chỉ đặt được thẻ tiêu đề còn cách kia đặt được mọi thẻ
D.Nó chạy phía client còn cách kia chạy phía server
Đáp án: B
Nó là một hàm bất đồng bộ nhận tham số route, nên tạo được siêu dữ liệu theo dữ liệu thật — tiêu đề theo tên sản phẩm, mô tả theo nội dung bài viết. Cách khai tĩnh chỉ hợp khi giá trị cố định.
File sitemap.ts trong thư mục app/ hoạt động thế nào?
A.Nó là file XML tĩnh được copy thẳng vào thư mục public
B.Nó tự động liệt kê mọi route mà không cần viết gì
C.Nó chỉ khai báo cấu hình, sitemap do công cụ ngoài sinh ra
D.Export hàm trả mảng URL, Next sinh ra XML tương ứng
Đáp án: D
Xuất một hàm trả về mảng các mục gồm đường dẫn, thời điểm sửa cuối, tần suất thay đổi và độ ưu tiên. Framework sinh ra tệp XML tương ứng. Hàm này chạy được truy vấn nên danh sách luôn khớp dữ liệu thật.
B.Khai báo đường dẫn tới một file ảnh tĩnh đã có sẵn
C.Nén và tối ưu các ảnh trong thư mục public
D.Sinh ảnh chia sẻ động từ JSX ngay lúc chạy
Đáp án: D
Sinh ảnh chia sẻ mạng xã hội động từ JSX ngay lúc chạy. Nhờ đó mỗi bài viết có ảnh riêng mang tiêu đề và tác giả của nó, thay vì phải thiết kế tay từng ảnh hoặc dùng chung một ảnh cho mọi trang.
useActionState (trước là useFormState) dùng để làm gì?
A.Lưu dữ liệu form vào bộ nhớ cục bộ của trình duyệt
B.Giữ giá trị trả về của Server Action để hiển thị lỗi validate
C.Theo dõi trạng thái đang gửi của form
D.Đồng bộ giá trị các input với state của component
Đáp án: B
Giữ giá trị trả về của hành động máy chủ để hiển thị lại — điển hình là danh sách lỗi xác thực theo từng trường. Nó trả về trạng thái hiện tại, một hàm bọc để gắn vào biểu mẫu, và một cờ báo đang chạy.
Trong một thành phần con nằm bên trong thẻ biểu mẫu — thường là chính nút gửi. Đặt ở thành phần khai báo biểu mẫu thì nó luôn trả về trạng thái rỗng, vì hook đọc ngữ cảnh do chính thẻ đó cung cấp.
Sau khi Server Action ghi dữ liệu, làm sao để UI hiển thị dữ liệu mới?
A.Gọi revalidatePath hoặc revalidateTag ngay trong action
B.Tải lại toàn bộ trang bằng API của trình duyệt
C.Gọi router.push tới chính trang hiện tại
D.Không cần làm gì; Next tự phát hiện dữ liệu đã đổi
Đáp án: A
Gọi hàm làm mới theo đường dẫn hoặc theo thẻ ngay trong hành động, sau khi ghi thành công. Không có bước đó thì cache vẫn giữ dữ liệu cũ và giao diện không đổi dù việc ghi đã thành công.
Hai truy vấn độc lập trong cùng một Server Component nên gọi thế nào?
A.await từng cái theo thứ tự cho dễ đọc
B.Chuyển cả hai sang Client Component để chạy song song
C.Gộp thành một truy vấn duy nhất bằng cách nối bảng
D.Khởi tạo cả hai rồi await Promise.all để chúng chạy song song
Đáp án: D
Khởi tạo cả hai promise trước rồi chờ chúng cùng lúc. Chờ tuần tự từng cái làm tổng thời gian bằng tổng hai truy vấn, thay vì bằng truy vấn chậm hơn — đây là mẫu thác nước request kinh điển.
Next.js 15 đổi hành vi cache mặc định của fetch thế nào?
A.Cache chuyển từ phía server sang phía client
B.Không đổi gì, chỉ đổi cách khai báo trong cấu hình
C.Mặc định không cache nữa; muốn cache phải khai báo
D.Mặc định cache vĩnh viễn thay vì cache theo thời gian
Đáp án: C
Từ mặc định lưu đệm chuyển sang mặc định không lưu đệm. Muốn lưu thì khai tường minh tuỳ chọn tương ứng hoặc đặt khoảng làm mới. Đây là thay đổi gây bất ngờ nhất khi nâng cấp lên bản 15.
A.Theo nhãn gắn ở nơi fetch, nên chạm mọi trang dùng dữ liệu đó
B.Nó xoá cache ngay lập tức còn cách kia chờ tới lần truy cập sau
C.Nó chỉ dùng được trong route handler, không dùng trong action
D.Nó áp cho cache phía client còn cách kia cho cache phía server
Đáp án: A
Nó làm mới theo nhãn gắn ở nơi lấy dữ liệu, nên một lời gọi chạm tới mọi trang dùng dữ liệu đó. Làm mới theo đường dẫn thì phải biết trước danh sách trang, vốn khó khi cùng dữ liệu xuất hiện ở nhiều nơi.
React cache() giải quyết vấn đề gì trong Server Component?
A.Lưu kết quả vào bộ nhớ của trình duyệt
B.Lưu kết quả giữa các request để lần sau không phải truy vấn lại
C.Khử trùng lặp lời gọi giống nhau trong cùng một lần render
D.Chạy các lời gọi song song thay vì tuần tự
Đáp án: C
Khử trùng lặp các lời gọi giống nhau trong cùng một lần render. Nhờ đó layout, trang và hàm sinh siêu dữ liệu cùng gọi một truy vấn mà cơ sở dữ liệu chỉ bị hỏi đúng một lần.
Chạy route trên Edge runtime thay vì Node runtime đánh đổi gì?
A.Bỏ được bước build vì mã chạy trực tiếp từ nguồn
B.Cho phép truy cập cơ sở dữ liệu mà không cần kết nối mạng
C.Khởi động nhanh và gần người dùng, đổi lại không có API Node đầy đủ
D.Chạy nhanh hơn với mọi loại tác vụ nhờ được tối ưu sâu hơn
Đáp án: C
Khởi động gần như tức thì và chạy gần người dùng về mặt địa lý, đổi lại không có đầy đủ API của Node. Nhiều thư viện phổ biến dùng module lõi của Node nên chúng không chạy được ở đó.
A.Giới hạn middleware chỉ chạy cho các đường dẫn khớp mẫu
B.Khai báo các route mà middleware được phép chuyển hướng tới
C.Ánh xạ các đường dẫn cũ sang đường dẫn mới
D.Chọn môi trường thực thi cho từng nhóm đường dẫn
Đáp án: A
Giới hạn middleware chỉ chạy cho các đường dẫn khớp mẫu. Không có nó, middleware chạy cho mọi request kể cả tài nguyên tĩnh và ảnh — vừa tốn kém vừa có thể gây lỗi khó hiểu.
Dùng next/image với ảnh từ domain ngoài báo lỗi. Cách sửa?
A.Khai domain đó vào images.remotePatterns trong config
B.Tải ảnh về thư mục public rồi tham chiếu cục bộ
C.Thay bằng thẻ ảnh thông thường vì component chỉ hỗ trợ ảnh nội bộ
D.Bật một cờ tắt kiểm tra nguồn ảnh trong cấu hình
Đáp án: A
Khai tên miền đó vào danh sách mẫu nguồn từ xa trong tệp cấu hình. Đây là danh sách cho phép có chủ đích: nó ngăn người khác lợi dụng máy chủ tối ưu ảnh của bạn để xử lý ảnh của họ.
Nó cho trình duyệt biết ảnh sẽ hiển thị rộng bao nhiêu ở mỗi kích thước màn hình, để chọn đúng biến thể độ phân giải. Thiếu nó, trình duyệt giả định ảnh rộng bằng cả viewport và tải bản lớn hơn nhiều so với cần.
Nhúng script bên thứ ba bằng next/script với strategy="afterInteractive" nghĩa là gì?
A.Script chạy trước khi React nhận quyền điều khiển trang
B.Script được nhúng thẳng vào HTML thay vì tải qua mạng
C.Script chỉ tải khi người dùng tương tác với trang
D.Script tải sau khi trang đã tương tác được
Đáp án: D
Script được tải sau khi trang đã tương tác được. Đây là mặc định và hợp cho hầu hết script bên thứ ba — phân tích, quảng cáo, hỗ trợ trực tuyến — vì chúng không cần chạy trước khi nội dung hiện ra.
Bundle client lớn bất thường. Bước chẩn đoán đầu tiên?
A.Nâng cấp mọi dependency lên phiên bản mới nhất
B.Chuyển toàn bộ component sang Server Component
C.Chạy bundle analyzer xem module nào chiếm chỗ
D.Bật nén gzip trên máy chủ để giảm dung lượng truyền
Đáp án: C
Chạy công cụ phân tích gói để xem module nào chiếm dung lượng. Đoán mò thường sai vì thủ phạm hay là một phụ thuộc gián tiếp — một thư viện ngày tháng đầy đủ ngôn ngữ, hay một bộ biểu tượng được nhập cả bộ.
dynamic(() => import(...), { ssr: false }) dùng khi nào?
A.Khi muốn component render nhanh hơn ở phía server
B.Khi component cần lấy dữ liệu từ một API bên ngoài
C.Khi component được dùng ở nhiều trang khác nhau
D.Khi component chỉ chạy được ở trình duyệt, ví dụ dùng window
Đáp án: D
Khi thành phần chỉ chạy được ở trình duyệt — dùng đối tượng cửa sổ, đo kích thước phần tử, hoặc một thư viện phụ thuộc API của trình duyệt. Render nó ở máy chủ sẽ lỗi vì các API đó không tồn tại.
output: "standalone" trong next.config dùng để làm gì?
A.Cho phép chạy ứng dụng mà không cần cài Node.js
B.Sinh một thư mục chứa đủ file để chạy, cho ảnh Docker nhỏ hơn nhiều
C.Xuất trang thành HTML tĩnh để host trên CDN
D.Gộp toàn bộ ứng dụng thành một file JavaScript duy nhất
Đáp án: B
Sinh một thư mục chứa đúng những tệp cần để chạy — mã đã build cùng các phụ thuộc thật sự được dùng. Nhờ đó ảnh Docker nhỏ hơn nhiều so với việc sao chép cả thư mục phụ thuộc hàng trăm megabyte.
A.Mọi thứ cần server lúc chạy: Server Action, ISR, middleware, route handler động
B.Chỉ giới hạn việc tối ưu ảnh, các tính năng khác vẫn hoạt động
C.Chỉ giới hạn các route động có tham số
D.Không giới hạn gì; nó chỉ đổi cách đóng gói kết quả build
Đáp án: A
Mọi tính năng cần một máy chủ lúc chạy: hành động máy chủ, làm mới tĩnh theo thời gian, middleware, endpoint động, và tối ưu ảnh mặc định. Kết quả chỉ là các tệp tĩnh nên không có tiến trình nào xử lý request.
Biến môi trường trong Next.js được đọc ở thời điểm nào?
A.Chúng được đọc lại ở mỗi request nên đổi có hiệu lực ngay
B.Tất cả đều bị nhúng lúc build nên phải build lại khi đổi
C.Tất cả đều được đọc lúc chạy nên đổi biến chỉ cần restart
D.Biến có tiền tố công khai bị nhúng lúc build; biến còn lại đọc lúc chạy
Đáp án: D
Biến có tiền tố công khai bị nhúng thành hằng số trong bản build cho trình duyệt, nên đổi chúng đòi hỏi build lại. Biến còn lại chỉ dùng phía máy chủ và đọc được lúc chạy, nên khởi động lại là đủ.
Làm route đa ngôn ngữ trong App Router theo cách nào?
A.Khai báo danh sách ngôn ngữ trong i18n của next.config
B.Tạo một thư mục app riêng cho mỗi ngôn ngữ
C.Segment động [locale] cộng middleware phát hiện và chuyển hướng
D.Dùng query string để chọn ngôn ngữ
Đáp án: C
Một đoạn động cho mã ngôn ngữ ở đầu cây route, cộng một middleware phát hiện ngôn ngữ từ đường dẫn hoặc header rồi chuyển hướng. Cơ chế dựng sẵn của hệ định tuyến cũ không còn ở App Router.
C.Cho phép chạy code chưa được build trong môi trường production
D.Xem trước nội dung chưa xuất bản bằng cách bỏ qua cache tĩnh
Đáp án: D
Xem trước nội dung chưa xuất bản. Nó đặt một cookie khiến các trang vốn được dựng tĩnh chuyển sang render động cho riêng phiên đó — nên người biên tập thấy bản nháp còn người dùng khác vẫn thấy bản đã xuất bản.
C.Không có vấn đề gì; chúng test như component thường
D.Component async luôn ném lỗi khi chạy ngoài môi trường Next
Đáp án: A
Các thư viện render phía client chưa hỗ trợ đầy đủ thành phần bất đồng bộ. Hướng khuyến nghị là tách logic ra hàm thuần để kiểm thử đơn vị, và dùng kiểm thử đầu cuối cho phần render.
C.Thay trình quản lý gói để cài dependency nhanh hơn
D.Thay webpack; build nhanh hơn nhờ Rust và cache tăng dần
Đáp án: D
Thay bundler cũ. Nó được viết bằng Rust và dùng cache tăng dần ở mức hàm, nên thời gian cập nhật khi sửa mã trong lúc phát triển giảm rõ rệt — đáng kể nhất trên các dự án lớn.
Khi nào nên viết Route Handler thay vì Server Action?
A.Khi cần trả về HTML thay vì JSON
B.Khi cần ghi dữ liệu vào cơ sở dữ liệu
C.Khi cần validate dữ liệu đầu vào trước khi xử lý
D.Khi cần API công khai cho client ngoài hoặc nhận webhook
Đáp án: D
Khi cần một API công khai và ổn định: cho ứng dụng di động, cho đối tác, hoặc để nhận webhook. Hành động máy chủ có định danh sinh tự động và đổi theo mỗi lần build nên không làm hợp đồng API được.
export const revalidate = 3600 trong một page có tác dụng gì?
A.Dựng lại trang tối đa mỗi giờ
B.Xoá cache của trang sau mỗi giờ
C.Đặt thời hạn lưu đệm ở trình duyệt là một giờ
D.Buộc trang render lại ở mỗi yêu cầu sau một giờ
Đáp án: A
Trang được dựng lại nhiều nhất mỗi giờ một lần. Yêu cầu tới sau khi hết hạn vẫn nhận bản cũ ngay lập tức, còn việc dựng lại chạy ở nền — nên không người dùng nào phải chờ.
Gắn nhãn cho dữ liệu để sau này làm mới có chọn lọc bằng cách nào?
A.Đặt tên nhãn trùng với tên route cần làm mới
B.Khai báo danh sách nhãn trong file cấu hình
C.Truyền next: { tags: [...] } khi fetch
D.Gọi một hàm đăng ký nhãn ở đầu mỗi page
Đáp án: C
Truyền danh sách nhãn kèm theo lời gọi lấy dữ liệu. Sau này gọi hàm làm mới theo nhãn sẽ vô hiệu hoá mọi mục có nhãn đó, ở bất kỳ route nào — chính xác hơn nhiều so với làm mới theo đường dẫn.
Gọi redirect("/login") bên trong Server Component hoạt động thế nào?
A.Trả về một component rỗng rồi chuyển hướng sau
B.Ném một lỗi đặc biệt, dừng render ngay
C.Đặt tiêu đề HTTP rồi tiếp tục render bình thường
D.Chỉ có tác dụng khi gọi ở cấp cao nhất của component
Đáp án: B
Nó ném một lỗi đặc biệt mà framework bắt được, nên quá trình render dừng ngay tại đó và mã phía sau không chạy. Hệ quả quan trọng: đặt nó trong khối bắt lỗi sẽ nuốt mất lỗi đó và chuyển hướng không xảy ra.
Dữ liệu lấy thẳng từ database bằng ORM, muốn lưu đệm như fetch thì dùng gì?
A.Đặt cấu hình thời hạn ở cấp route là đủ
B.ORM tự lưu đệm nên không cần làm gì
C.Lưu kết quả vào một biến ở cấp module
D.Bọc hàm truy vấn bằng API cache
Đáp án: D
Bọc hàm truy vấn bằng API cache của Next.js. Cơ chế lưu đệm tự động chỉ gắn vào lời gọi qua mạng, nên truy vấn trực tiếp phải được bọc mới nhận được nhãn và thời hạn để làm mới có chọn lọc.
Gọi cookies().set() trong một Server Component báo lỗi. Vì sao?
A.Phải khai báo cookie trong file cấu hình trước
B.Cookie chỉ ghi được từ mã chạy ở trình duyệt
C.Chỉ ghi cookie được ở Server Action hoặc Route Handler
D.Hàm này chỉ hoạt động ở môi trường Edge
Đáp án: C
Vì cookie chỉ ghi được trong Server Action hoặc Route Handler. Quá trình render có thể đã bắt đầu gửi phản hồi theo luồng, nên tiêu đề HTTP không còn sửa được nữa. Đọc cookie trong component thì vẫn bình thường.
Prop priority của next/image nên dùng cho ảnh nào?
A.Ảnh lớn hiện ngay ở màn hình đầu
B.Mọi ảnh trong trang để tải nhanh hơn
C.Ảnh có dung lượng lớn nhất trong trang
D.Các ảnh nằm ở cuối trang
Đáp án: A
Chỉ cho ảnh lớn hiện ngay trong màn hình đầu tiên — thường là ảnh chính của phần đầu trang. Ảnh đó quyết định thời điểm trang được coi là hiển thị xong nội dung chính, nên tải sớm cải thiện chỉ số trải nghiệm.
Vì sao không nên kiểm tra phiên đăng nhập bằng truy vấn database trong middleware?
A.Middleware chạy trước mọi yêu cầu, độ trễ cộng dồn
B.Middleware không chuyển hướng người dùng được
C.Middleware không đọc được cookie của yêu cầu
D.Middleware chỉ chạy ở môi trường phát triển
Đáp án: A
Vì nó chạy trước mọi yêu cầu khớp bộ lọc, nên độ trễ của truy vấn cộng vào tất cả. Ngoài ra môi trường chạy của nó hạn chế nên kết nối database thường không dùng được như ở mã server thông thường.
Nó là gốc để ghép các đường dẫn tương đối thành URL đầy đủ. Ảnh chia sẻ mạng xã hội và thẻ canonical bắt buộc dùng URL tuyệt đối, nên thiếu nó thì các thẻ sinh ra bị sai và mạng xã hội không hiển thị được ảnh xem trước.
redirects và rewrites trong next.config khác nhau thế nào?
A.Một cần khai báo mã trạng thái, một thì không
B.Một đổi URL trên thanh địa chỉ, một không
C.Một dùng cho route nội bộ, một cho địa chỉ ngoài
D.Một chạy lúc dựng, một chạy lúc nhận yêu cầu
Đáp án: B
Chuyển hướng bảo trình duyệt đi tới địa chỉ khác, nên URL trên thanh địa chỉ đổi. Viết lại chỉ đổi đích xử lý ở phía server, người dùng vẫn thấy URL ban đầu và không có lượt đi về nào thêm.