Lỗi đó là cơ chế bảo vệ: nếu cho phép tối ưu ảnh từ mọi domain, ai cũng có thể ép server của bạn xử lý ảnh của họ.
Phải khai báo domain được phép:
// next.config.js
module.exports = {
images: {
remotePatterns: [
{ protocol: 'https', hostname: 'cdn.example.com', pathname: '/uploads/**' },
],
},
}Khai báo càng hẹp càng tốt (pathname, port). Tránh hostname: '**'.
fill và sizes: khi không biết trước kích thước ảnh (ảnh do người dùng tải lên, ảnh phủ kín card), dùng fill để ảnh trải theo phần tử cha — cha phải có position: relative và chiều cao xác định.
<div className="relative h-64 w-full">
<Image src={url} alt="" fill sizes="(max-width: 768px) 100vw, 33vw" style={{ objectFit: 'cover' }} />
</div>sizes cho trình duyệt biết ảnh sẽ chiếm bao nhiêu bề rộng ở mỗi breakpoint, để nó chọn đúng bản trong srcset. Thiếu sizes khi dùng fill là lỗi hay gặp nhất: trình duyệt mặc định coi ảnh rộng 100vw và tải bản lớn nhất, tức là mất luôn phần lợi ích mà next/image mang lại.
Về chi phí: mỗi tổ hợp (ảnh gốc, bề rộng, định dạng) là một lần transform có tính phí trên nền tảng hosting. Giảm bằng cách khai báo deviceSizes/imageSizes gọn lại, hoặc dùng unoptimized cho ảnh CDN đã tối ưu sẵn.