Đặt câu hỏi và nhận tóm tắt tài liệu bằng cách tham chiếu trang này và nhà cung cấp AI bạn chọn
Lịch sử phiên bản
- "Phiên bản ban đầu"v9.5.1026/9/2026
Nội dung của trang này đã được dịch bằng AI.
Xem phiên bản mới nhất của nội dung gốc bằng tiếng AnhNếu bạn có ý tưởng để cải thiện tài liệu này, vui lòng đóng góp bằng cách gửi pull request trên GitHub.
Liên kết GitHub tới tài liệuSao chép Markdown của tài liệu vào bộ nhớ tạm
Cách quốc tế hóa ứng dụng Next.js của bạn bằng Lingui vào năm 2026
Mục lục
Lingui là gì?
Lingui là một thư viện i18n được xây dựng xung quanh macro và trích xuất tin nhắn (message extraction). Bạn viết văn bản nguồn trực tiếp trong các component ( t`Hello` , <Trans>Hello</Trans>), lệnh lingui extract sẽ thu thập mọi thông điệp vào các catalog (mặc định là các tệp PO), và một trình tải (loader) sẽ biên dịch chúng thành mã JavaScript nhỏ gọn. Các thông điệp sử dụng cú pháp ICU MessageFormat, và Lingui hỗ trợ đầy đủ React Server Components trong App Router.
Hướng dẫn này sẽ thiết lập Lingui trong một dự án Next.js 16 App Router, bao gồm:
- Macro được biên dịch bởi SWC, giúp Turbopack duy trì tốc độ tối đa.
- Server và Client Components dùng chung API
TransvàuseLingui. - Định tuyến ngôn ngữ thông qua
proxy.ts:/aboutcho ngôn ngữ mặc định,/fr/aboutcho các ngôn ngữ khác, cùng khả năng tự động phát hiện ngôn ngữ trong lần truy cập đầu tiên. - Render tĩnh (Static rendering) cho mọi ngôn ngữ với
generateStaticParams. - SEO đa ngôn ngữ hoàn chỉnh:
generateMetadatađã dịch, URL chuẩn canonical,hreflangvớix-default, Open Graph locales, JSON-LD,sitemap.ts,robots.tsvà trang 404 được bản địa hóa.
Bạn đang tìm kiếm một thư viện khác? Hãy xem hướng dẫn next-intl, hướng dẫn next-i18next, hoặc hướng dẫn Next.js + Intlayer.
Đang sử dụng TanStack Start? Xem hướng dẫn TanStack Start + Lingui. Cần so sánh các thư viện? Đọc bài viết Lingui vs Intlayer và next-i18next vs next-intl vs Intlayer.
Dữ liệu benchmark nói gì về Lingui trên Next.js
Báo cáo i18n benchmark chạy cùng một ứng dụng Next.js gồm 10 trang, 10 ngôn ngữ với mọi thư viện phổ biến và đo lường dung lượng thực tế mà trình duyệt tải xuống.
Tải JSON động
Tải chậm các bản dịch trong thời gian chạy
JSON có phạm vi (phân không gian tên)
Không gian tên dịch trên mỗi trang
Điểm chuẩn hiệu suất I18n
Số liệu này là gì?
Tổng kích thước nén gzip của gói thư viện quốc tế hóa. Nó chỉ bao gồm logic của nhà cung cấp và truy xuất nội dung sau khi tree-shaking và thu nhỏ (minification).
Tại sao nó quan trọng?
Kích thước thư viện nhỏ hơn giúp giảm tải trọng JavaScript ban đầu, tốc độ tải nhanh hơn.
Xem dưới dạng
Các số liệu chính cho @lingui/core@6.6.0 trên Next.js 16, được đo vào ngày 2026-09-26 (gzip):
Mở bảng trong một cửa sổ bật lên để xem toàn bộ nội dung dữ liệu một cách rõ ràng
| Cấu hình | Kích thước thư viện | JS mỗi trang | Rò rỉ ngôn ngữ khác | Rò rỉ trang khác |
|---|---|---|---|---|
| Không có i18n (ứng dụng gốc) | - | 141.0 KB | 0% | 0% |
| Lingui, một catalog cho mỗi locale | 72.1 KB | 145.4 KB | 2.8% | 89.9% |
@intlayer/lingui (tương thích) | 10.7 KB | 221.6 KB | 50% | 90% |
next-intlayer (Intlayer gốc) | 4.9 KB | 141.5 KB | 0% | 0% |
Những điểm quan trọng cần lưu ý:
- Một catalog đơn lẻ cho mỗi ngôn ngữ vẫn làm rò rỉ thông điệp của các trang khác vào client provider. Hãy giữ càng nhiều văn bản càng tốt trong Server Components, vì chúng chỉ gửi HTML đã render chứ không gửi catalog.
- Runtime của Lingui nặng ~72 KB gzip. Adapter tương thích
@intlayer/linguicắt giảm runtime xuống ~11 KB, nhưng trong benchmark này cấu hình tương thích Next.js vẫn tải toàn bộ catalog vào trang. API gốcnext-intlayerlà giải pháp duy nhất giữ nguyên kích thước của ứng dụng cơ sở ban đầu.
Xem dữ liệu đầy đủ: Báo cáo benchmark Next.js, và kho lưu trữ benchmark.
So sánh tính năng trên Next.js
Bảng so sánh Lingui với next-intl và Intlayer về các tính năng mà một dự án Next.js App Router thường cần:
Mở bảng trong một cửa sổ bật lên để xem toàn bộ nội dung dữ liệu một cách rõ ràng
| Tính năng | next-intlayer (Intlayer) | Lingui | next-intl |
|---|---|---|---|
| Bản dịch đặt gần components | ✅ Nội dung đặt cùng vị trí với từng component | ⚠️ Văn bản nguồn trong component, catalog tập trung | ❌ JSON tập trung |
| Tích hợp TypeScript | ✅ Kiểu dữ liệu nghiêm ngặt được tạo tự động | ⚠️ Macros có type, catalog thông điệp thì không | ✅ Tốt, thông qua mở rộng AppConfig |
| Phát hiện bản dịch thiếu | ✅ Lỗi TypeScript và cảnh báo khi build | ⚠️ Dự phòng thời gian chạy về văn bản nguồn | ⚠️ Dự phòng thời gian chạy |
| Nội dung phong phú (JSX, Markdown) | ✅ Hỗ trợ trực tiếp | ✅ JSX bên trong <Trans>, không có Markdown | ⚠️ Thẻ qua t.rich, không có Markdown |
| Dịch thuật bằng AI | ✅ Tự dùng nhà cung cấp và API key, có ngữ cảnh app | ❌ Không | ❌ Không |
| Trình chỉnh sửa trực quan / CMS | ✅ Trình chỉnh sửa trực quan cục bộ + CMS tùy chọn | ❌ Thông qua nền tảng bên ngoài | ❌ Thông qua nền tảng bên ngoài |
| Định tuyến bản địa hóa | ✅ Tích hợp sẵn | ❌ Tự viết proxy.ts | ✅ Tích hợp phân đoạn [locale] |
| Xử lý số nhiều (Pluralization) | ✅ Dựa trên liệt kê (Enumeration) | ✅ ICU, macro <Plural> | ✅ ICU |
| Định dạng nội dung | ✅ .ts, .tsx, .js, .json, .md, .yaml | ✅ PO, JSON, CSV | ✅ .json, .js, .ts |
| ICU MessageFormat | ✅ Thông qua format: "icu" | ✅ Hỗ trợ gốc | ✅ Hỗ trợ gốc |
| Hỗ trợ SEO (hreflang, sitemap) | ✅ Tiện ích cho Metadata, sitemap và robots.txt | ❌ Thủ công | ✅ Tốt |
| Server Components | ✅ Truy cập trực tiếp trong mọi Server Component | ⚠️ Cần setI18n trong mọi layout và page | ⚠️ Cần await getTranslations() mỗi component |
| Tree-shaking theo component | ✅ Tại thời điểm build (Babel / SWC) | ⚠️ Một catalog mỗi ngôn ngữ, trích xuất theo trang đang thử nghiệm | ⚠️ Thủ công, với pick() cho mỗi route |
| Kích thước runtime (gzip, benchmark) | 4.9 KB | 72.1 KB | 14.7 KB |
| Bản dịch thiếu trong CI | ✅ npx intlayer test | ✅ lingui compile --strict | ⚠️ Không tích hợp sẵn |
| Hệ sinh thái / cộng đồng | ⚠️ Nhỏ hơn, đang phát triển nhanh | ✅ Trưởng thành | ✅ Lớn |
Kích thước runtime được lấy từ Next.js benchmark. Để thảo luận chi tiết hơn, hãy đọc Lingui vs Intlayer.
Các hướng dẫn Next.js khác: next-intl, next-i18next và Intlayer.
Các thực hành bạn nên tuân theo
- Thiết lập
langvàdirtrên<html>trong layout[locale]. - Ưu tiên Server Components cho văn bản: chúng render HTML trên máy chủ và không cần gửi catalog về client.
- Gọi
initLingui(locale)trong mọi layout và page. Layout không render lại khi điều hướng, vì vậy một page không thể phụ thuộc vào việc layout đã thiết lập ngôn ngữ hay chưa. - Duy trì một URL duy nhất cho mỗi ngôn ngữ và pre-render mọi ngôn ngữ với
generateStaticParams. - Dịch metadata của bạn trong
generateMetadata, bao gồmcanonical,hreflangvàx-default. - Tạo sitemap và robots.txt đa ngôn ngữ với quy ước
sitemap.tsvàrobots.ts. - Sử dụng các liên kết thực cho bộ chuyển đổi ngôn ngữ, để các bot tìm kiếm có thể khám phá mọi ngôn ngữ.
- Chạy
lingui extracttrong CI để đảm bảo không có thông điệp mới nào được triển khai mà chưa được dịch.
Xem hướng dẫn của chúng tôi về quốc tế hóa và SEO, hướng dẫn hreflang và so sánh SEO đa ngôn ngữ trên Next.js.
Hướng dẫn từng bước thiết lập Lingui trong ứng dụng Next.js
Dưới đây là cấu trúc dự án mà chúng ta sẽ tạo:
Sao chép mã vào clipboard
Cài đặt các gói phụ thuộc
bashSao chép mãSao chép mã vào clipboard
- @lingui/core / @lingui/react: runtime,
I18nProvider,setI18ncho Server Components, và các macro (@lingui/core/macro,@lingui/react/macro). - @lingui/swc-plugin: biên dịch các macro bên trong luồng xử lý SWC của Next.js.
- @lingui/loader: biên dịch các catalog
.pokhi import, giúp bạn không cần chạylingui compile. - @lingui/cli: lệnh
lingui extractđể thu thập các thông điệp vào catalog.
@lingui/swc-pluginlà một WebAssembly plugin gắn liền với phiên bản SWC của Next.js. Nếu build thất bại sau khi nâng cấp Next.js, hãy cập nhật plugin lên phiên bản tương thích được liệt kê trong README của plugin.- @lingui/core / @lingui/react: runtime,
Tập trung cấu hình ngôn ngữ của bạn
Một tệp duy nhất định nghĩa các ngôn ngữ và hàm tiện ích URL. Hệ thống định tuyến, metadata, sitemap và Lingui đều đọc từ tệp này.
src/i18n/config.tsSao chép mãSao chép mã vào clipboard
Cấu hình Lingui và Next.js
lingui.config.tsSao chép mãSao chép mã vào clipboard
Plugin SWC biên dịch các macro, và loader biên dịch các tệp
.po, cho cả Turbopack (mặc định trong Next.js 16) và webpack:next.config.tsSao chép mãSao chép mã vào clipboard
Thêm các script trích xuất vào
package.json:package.jsonSao chép mãSao chép mã vào clipboard
Tải Catalogs và tạo các Instance cho Server
Server Components không có React context, vì vậy Lingui cung cấp hàm
setI18nđể đăng ký instance cho lần render hiện tại. Module này tải mỗi catalog một lần duy nhất cho mỗi tiến trình server và tạo một instanceI18ncho mỗi ngôn ngữ. Tệp này làserver-only: catalog của các ngôn ngữ khác sẽ không bao giờ bị đưa vào bundle phía client.src/i18n/appRouterI18n.tsSao chép mãSao chép mã vào clipboard
src/i18n/initLingui.tsSao chép mãSao chép mã vào clipboard
Để TypeScript chấp nhận việc import tệp
.po, hãy khai báo module một lần:src/i18n/po.d.tsSao chép mãSao chép mã vào clipboard
Tạo Client Provider
Client Components đọc bản dịch từ một React context. Provider nhận catalog của ngôn ngữ đang hoạt động từ server layout và khởi tạo instance riêng một lần.
src/components/LinguiClientProvider.tsxSao chép mãSao chép mã vào clipboard
Định nghĩa các Route ngôn ngữ động
Phân đoạn
[locale]chứa root layout.generateStaticParamssẽ pre-render mọi ngôn ngữ tại thời điểm build, vàdynamicParams = falsesẽ trả về trang 404 cho bất kỳ tiền tố nào khác.src/app/[locale]/layout.tsxSao chép mãSao chép mã vào clipboard
Client provider nhận toàn bộ catalog của ngôn ngữ đang hoạt động. Đây chính là yếu tố mà benchmark đo lường là "rò rỉ trang khác". Việc giữ văn bản trong Server Components sẽ giới hạn những gì client thực sự cần. Đối với các ứng dụng lớn, trình trích xuất theo từng trang đang thử nghiệm của Lingui (
experimental.extractortronglingui.config.ts) sẽ chia nhỏ catalog theo từng điểm vào (entry point).Sử dụng bản dịch trong Server Components
Server Components sử dụng các macro tương tự như Client Components.
initLinguicũng phải được chạy trong từng page, vì layout không render lại khi điều hướng giữa các trang bên trong nó.src/app/[locale]/about/page.tsxSao chép mãSao chép mã vào clipboard
Sử dụng bản dịch trong Client Components
Client Components sử dụng các import tương tự. Các macro sẽ đọc instance từ
LinguiClientProvider.src/components/Counter.tsxSao chép mãSao chép mã vào clipboard
Trích xuất và dịch thông điệp của bạn
Chạy lệnh trích xuất. Lingui sẽ ghi mọi thông điệp tìm thấy trong thư mục
srcvào từng catalog ngôn ngữ:bashSao chép mãSao chép mã vào clipboard
Sau đó dịch giá trị
msgstrcho từng mục:src/locales/fr/messages.poSao chép mãSao chép mã vào clipboard
src/locales/es/messages.poSao chép mãSao chép mã vào clipboard
Các placeholder
<0>giữ nguyên vị trí của các phần tử JSX trong thẻ<Trans>, giúp người dịch có thể di chuyển vị trí của chúng mà không làm ảnh hưởng đến cấu trúc mã.Thiết lập Proxy cho định tuyến ngôn ngữ
Tùy chọnNext.js 16 đã đổi tên
middleware.tsthànhproxy.ts. Proxy sẽ triển khai chiến lược tiền tố "khi cần thiết" (as-needed):/fr/aboutđược phục vụ bình thường;/en/aboutchuyển hướng đến/about, giúp ngôn ngữ mặc định chỉ có một URL duy nhất;/aboutđược viết lại nội bộ thành/en/about, mà không thay đổi URL hiển thị trên thanh địa chỉ;- Lần truy cập đầu tiên vào
/sẽ chuyển hướng đến ngôn ngữ ưu tiên (ưu tiên cookie trước, sau đó đếnAccept-Language).
src/i18n/negotiateLocale.tsSao chép mãSao chép mã vào clipboard
src/proxy.tsSao chép mãSao chép mã vào clipboard
Thay đổi ngôn ngữ nội dung của bạn
Tùy chọnusePathnametrả về URL hiển thị trên trình duyệt (/abouthoặc/fr/about). Loại bỏ tiền tố ngôn ngữ, sau đó xây dựng liên kết cho từng ngôn ngữ. Bộ chuyển đổi render các liên kết thực sự để trình thu thập dữ liệu có thể tiếp cận mọi phiên bản ngôn ngữ, và cookie sẽ ghi nhớ lựa chọn rõ ràng của người dùng.src/components/LocaleSwitcher.tsxSao chép mãSao chép mã vào clipboard
Xây dựng Component Localized Link
Tùy chọnsrc/components/LocalizedLink.tsxSao chép mãSao chép mã vào clipboard
Component này cũng hoạt động từ Server Components, vì nó được render bên trong
LinguiClientProvider:tsxSao chép mãSao chép mã vào clipboard
Quốc tế hóa Metadata của bạn
Tùy chọnMỗi phiên bản ngôn ngữ có thể xếp hạng độc lập, miễn là mỗi trang cung cấp đầy đủ:
titlevàdescriptionđã được dịch;- URL canonical trỏ về chính nó;
- Các liên kết thay thế
hreflangcho mỗi ngôn ngữ, cộng vớix-default; - Open Graph
locale,alternateLocalevàurl; - JSON-LD kèm
inLanguage.
Hàm
generateMetadatachạy bên ngoài React tree, do đó nó sử dụng trực tiếp instance phía server cùng macromsg:src/i18n/metadata.tsSao chép mãSao chép mã vào clipboard
src/app/[locale]/about/page.tsxSao chép mãSao chép mã vào clipboard
JSON-LD được render bởi chính trang đó. Các tệp trang chỉ được phép export các trường của Next.js, vì vậy hãy giữ component trong tệp riêng của nó:
src/components/WebPageJsonLd.tsxSao chép mãSao chép mã vào clipboard
src/app/[locale]/about/page.tsxSao chép mãSao chép mã vào clipboard
Quốc tế hóa Sitemap của bạn
Tùy chọnQuy ước
sitemap.tshỗ trợalternates.languages, được Next.js render dưới dạng các liên kết thay thếxhtml:link. Liệt kê mọi URL cho từng ngôn ngữ:src/app/sitemap.tsSao chép mãSao chép mã vào clipboard
Quốc tế hóa robots.txt của bạn
Tùy chọnCác đường dẫn riêng tư tồn tại trong mọi ngôn ngữ, vì vậy
disallowphải bao gồm tất cả các đường dẫn đã được bản địa hóa:src/app/robots.tsSao chép mãSao chép mã vào clipboard
Xử lý các trang 404 được bản địa hóa
Tùy chọnnot-found.tsxrender bên trong layout[locale], do đó nó có quyền truy cập vào client provider. Catch-all route sẽ chuyển các đường dẫn không xác định trong một ngôn ngữ về trang này. Next.js sẽ tự động thêmnoindexvào các phản hồi 404.src/app/[locale]/not-found.tsxSao chép mãSao chép mã vào clipboard
src/app/[locale]/[...rest]/page.tsxSao chép mãSao chép mã vào clipboard
Truy cập Locale trong Server Actions
Tùy chọnServer Actions không nhận tham số route. Cách tiếp cận đáng tin cậy nhất là gửi ngôn ngữ kèm theo form, từ chính trang biết ngôn ngữ đó:
src/app/[locale]/contact/page.tsxSao chép mãSao chép mã vào clipboard
src/app/actions/sendContactMessage.tsSao chép mãSao chép mã vào clipboard
Giữ nguyên Macro, cắt giảm Runtime với Intlayer
Tùy chọnAdapter tương thích
@intlayer/linguigiữ nguyên mã nguồn của bạn: các macro vẫn biên dịch như trước, và các lời gọii18n._(),useLingui()cùng<Trans>được phục vụ bởi từ điển Intlayer. Trong benchmark Next.js, runtime giảm từ ~72.1 KB xuống ~10.7 KB gzip.Trên Next.js, adapter được tích hợp bằng cách alias
@lingui/corevà@lingui/reactsang@intlayer/linguitrongnext.config.ts(cho cả webpack và Turbopack), đồng thời bọc cấu hình bằngwithIntlayertừnext-intlayer/server. Hãy giữ lại@lingui/swc-pluginđể các macro vẫn được biên dịch trước. Cấu hình chi tiết có trong hướng dẫn tương thích Lingui.Như bảng benchmark đã chỉ ra, adapter giúp giảm kích thước runtime nhưng chưa thể giảm phần catalog được gửi tới từng trang trên Next.js. Nó phù hợp nhất khi được sử dụng làm cầu nối di chuyển: sau khi ứng dụng hoạt động ổn định, hãy chuyển dần từng component sang API gốc
useIntlayer, chỉ gửi đúng nội dung mà component đó cần hiển thị. Xem hướng dẫn Next.js + Intlayer, Lingui vs @intlayer/lingui và tất cả các adapter tương thích.Tự động hóa bản dịch bằng Intlayer
Tùy chọnLingui hỗ trợ trích xuất thông điệp, nhưng việc dịch thủ công hàng chục catalog là công đoạn tiêu tốn nhiều thời gian nhất. Intlayer là giải pháp miễn phí và mã nguồn mở, cung cấp các công cụ hoạt động song song cùng Lingui:
- Dịch bằng AI với API key và nhà cung cấp của chính bạn. Xem tự động điền (auto fill) và CLI.
- Giữ các tệp PO làm nguồn chân lý duy nhất với plugin sync PO.
- Kiểm tra bản dịch bị thiếu trong CI. Xem kiểm thử bản dịch.
- Kiểm tra website đã triển khai để phát hiện thiếu
hreflang, sai canonical và rò rỉ ngôn ngữ với lệnh scan.
Các câu hỏi thường gặp
Có. @lingui/react hỗ trợ React Server Components. Server Components đăng ký instance thông qua setI18n từ @lingui/react/server, Client Components đọc instance từ I18nProvider, và cả hai đều sử dụng chung các macro Trans và useLingui.
Server Components không có context, do đó instance được đăng ký cho mỗi lần render. Các layout được giữ lại khi điều hướng và không render lại, vì vậy một page không thể phụ thuộc vào việc layout đã thiết lập ngôn ngữ hay chưa. Việc gọi initLingui(locale) ở đầu mỗi layout và page giúp chúng hoạt động độc lập và chính xác.
Hãy sử dụng @lingui/swc-plugin. Nó duy trì luồng biên dịch SWC và Turbopack. Việc thêm cấu hình Babel sẽ vô hiệu hóa SWC trong Next.js và làm chậm quá trình build. Ràng buộc duy nhất là giữ cho phiên bản plugin tương thích với phiên bản SWC của bản phát hành Next.js mà bạn đang sử dụng.
Lấy server instance bằng getI18nInstance(locale) và dịch các mô tả được khai báo bằng macro msg: i18n._(msg`About us`). Trả về alternates.canonical, alternates.languages với x-default, và openGraph.locale. Bước 13 cung cấp một helper có thể tái sử dụng.
Báo cáo benchmark đo được runtime khoảng ~72 KB gzip. Với một catalog cho mỗi ngôn ngữ, kích thước trang khoảng ~145 KB so với 141 KB khi không có i18n, nhưng mỗi trang vẫn nhận các thông điệp của các trang khác thông qua client provider.
Lingui phù hợp với các nhóm thích viết văn bản nguồn trực tiếp trong component và làm việc với các tệp PO cùng biên dịch viên. next-intl phù hợp với các nhóm thích catalog dạng JSON và API t("key") tích hợp chặt chẽ với Next.js. next-i18next mang lại hệ sinh thái plugin phong phú của i18next. Xem next-i18next vs next-intl vs Intlayer và Next.js benchmark.
Bình luận
Chưa có bình luận nào. Hãy là người đầu tiên chia sẻ suy nghĩ của bạn.
