Trước khi có middleware, để thực hiện được các xử lý như redirect nếu không có quyền truy cập, rewrite 1 đường dẫn ảnh tới 1 server bên ngoài, hay bổ sung thêm cookie vào headers đều phải làm thủ công
Cụ thể là chúng ta đều phải thực hiện những việc trên trong từng page, hoặc phải bổ sung config vào next.config.js
. Bây giờ, với sự bổ sung _middleware.ts
mọi việc sẽ dễ dàng hơn nhiều
Sử dụng
Đầu tiên, để sử dụng _middleware.ts
chúng ta phải cài đặt phiên bản mới nhất của Nextjs. Dù bạn đạn chạy version cũ hơn của Next.js thì vẫn có thể chạy lệnh dưới đây để nâng cấp
$ yarn add next@latest
Sau đó, tạo 1 file có tên là _middleware.ts
trong thư mục /pages
// pages/_middleware.ts
import type { NextFetchEvent, NextRequest } from 'next/server'
export function middleware(req: NextRequest, ev: NextFetchEvent) {
return new Response('Hello, world!')
}
Lưu ý rằng:
Do bạn có thể sử dụng
_middleware.ts
ở bất kì đâu trong/pages
nên hiển nhiên chúng ta cũng có thể sử dụng nó trong/pages/api/
Xong, thủ tục thì chỉ đơn giản như vậy thôi
Thứ tự thực thi
Nếu bạn tạo middleware.ts
bên trong thư mục /pages
như hình dưới, thì nó sẽ được thực thi trước toàn bộ routes. Do đó, /pages/_middleware.ts
sẽ chạy trước, sau đó đến /pages/index.tsx
, /pages/about.tsx
, /pages/teams.tsx
- package.json
- /pages
_middleware.ts # chạy trước toàn bộ routes
index.tsx
about.tsx
teams.tsx
Còn nếu bạn có nhiều cấp thư mục con, thì thứ tự thực thi sẽ là từ ngoài vào trong
- package.json
- /pages
index.tsx
_middleware.ts # chạy thứ 1
- /about
_middleware.ts # chạy thứ 2
about.tsx
- /teams
_middleware.ts # chạy thứ 3 => do nó nằm trong /about/teams
teams.tsx
Giải thích nội dung bên trong middleware.ts
Nhìn đoạn code bên dưới, có 1 số Class chúng ta cần quan tâm: NextRequest
, NextFetchEvent
, Response
, NextResponse
. Tuy nhiên, đã khá quen thuộc, nên bài viết này chỉ giải thích về các Class còn lạiNextRequest
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
export function middleware(req: NextRequest, ev: NextFetchEvent) {
return new Response("Hello, world!");
}
Vậy, ta có thể làm gì với những Class này ?
Đầu tiên, về Response
- nó là chuẩn Web API Response
Chúng ta sử dụng Response
để trả về kết quả, như ví dụ trên thì kết quả hiển thị trên trình duyệt sẽ là

Các bạn có thể đọc thêm tài liệu về Web API Response tại MDN, dưới đây là 1 số cách sử dụng cơ bản
1/ Redirecting
export function middleware(req: NextRequest, ev: NextFetchEvent) {
return Response.redirect("https://google.com");
}
2/ Trả về json object, thêm cookie vào header
export function middleware(req: NextRequest, ev: NextFetchEvent) {
const headers = new Headers();
headers.append("Content-Type", "application/json");
// bổ sung `name` và httpOnly
headers.set("Set-Cookie", "name=12; HttpOnly");
return new Response(JSON.stringify({ name: "John", age: 32 }), {
status: 200,
statusText: "OK",
headers: headers,
});
}

Class thứ 2 là NextResponse
Thực ra, NextResponse
chỉ là 1 Class mở rộng của Response
, nó cung cấp 1 số phương thức tiện dụng sau
cookie(name, value, options)
clearCookie(name)
redirect(url)
rewrite(url)
next()
Các phương thức trên tương đối dễ hiểu do đó me sẽ chỉ giải thích 2 phương thức là rewrite(url)
và next()
1/ rewrite(url)
Phương thức này được sử dụng chủ yếu để chuyển hướng 1 địa chỉ url tới 1 địa chỉ url khác. Tuy nhiên, khác với redirect, rewrite
không làm thay đổi địa chỉ url trên thanh địa chỉ của trình duyệt. Chỉ có 1 điểm giống nhau giữa redirect
và rewrite
đó là kết quả hiển thị
// redirect
http://blog/unknown-post
=> redirect(/404)
http://blog/404
// rewrite
http://blog/unknown-post
=> rewrite(/404)
http://blog/unknown-post
2/ next()
Phương thức này thì đơn giản hơn, nó nói cho server biết rằng, cứ tiếp tục xử lý request, không có vấn đề gì cả
export function middleware(req: NextRequest, ev: NextFetchEvent) {
return NextResponse.next();
}
Kết quả là

Còn nếu sử dụng Response
export function middleware(req: NextRequest, ev: NextFetchEvent) {
return return new Response('Hello, world!');
}
Thì kết quả là

Cuối cùng, class thứ 3 NextFetchEvent
Updating ....