Kết xuất Tĩnh và Động với i18n trong Next.js
Vấn đề với next-intl
Chuyện gì xảy ra? Khi bạn sử dụng useTranslations, getTranslations, hoặc bất kỳ helper nào của next-intl bên trong một Server Component trên một ứng dụng có định tuyến i18n (/en/…, /fr/…), Next.js sẽ đánh dấu toàn bộ route đó là động. ([Next Intl][1])
Tại sao? next-intl tra cứu locale hiện tại từ một header chỉ dành cho request (x-next-intl-locale) thông qua headers(). Vì headers() là một API động, bất kỳ component nào sử dụng nó sẽ mất đi khả năng tối ưu tĩnh. ([Next Intl][1], [Next.js][2])
Giải pháp chính thức (boilerplate)
- Xuất generateStaticParams với tất cả các locale được hỗ trợ.
- Gọi setRequestLocale(locale) trong mọi layout/trang trước khi bạn gọi useTranslations. ([Next Intl][1]) Điều này loại bỏ sự phụ thuộc vào header, nhưng bạn sẽ có thêm mã để duy trì và một API không ổn định trong môi trường production.
Cách intlayer tránh được vấn đề này
Lựa chọn thiết kế
- Chỉ dùng tham số route – Locale lấy từ đoạn URL [locale] mà Next.js đã truyền sẵn cho mỗi trang.
- Gói biên dịch thời gian biên dịch – Các bản dịch được nhập dưới dạng các module ES thông thường, vì vậy chúng được tree-shaken và nhúng vào thời gian biên dịch.
- Không dùng API động – useT() đọc từ React context, không phải từ headers() hay cookies().
- Không cần cấu hình thêm – Khi các trang của bạn nằm dưới app/[locale]/, Next.js tự động prerender một file HTML cho mỗi locale.