Xây dựng hệ thống i18n đa ngôn ngữ cho monorepo React Web (Next.js) và React Native (Expo)

8 lượt xem · 1 trả lời

1. 12:09 14/10/2026
## Giới thiệu Khi phát triển ứng dụng chạy cùng lúc trên web và mobile trong một monorepo, việc quản lý đa ngôn ngữ (i18n) trở thành thách thức lớn. Cách tiếp cận thống nhất giúp giảm thiểu trùng lặp mã, đảm bảo trải nghiệm người dùng nhất quán và dễ dàng mở rộng ngôn ngữ mới. ## Lợi ích của giải pháp chung - **Chia sẻ tệp dịch thuật**: Một kho ngôn ngữ duy nhất phục vụ cả Next.js và Expo. - **Cấu hình tập trung**: Thay đổi fallback, định dạng ngày/giờ chỉ cần sửa ở một nơi. - **Tối ưu bundle**: Chỉ nạp ngôn ngữ cần thiết cho từng nền tảng. ## Kiến trúc đề xuất 1. **Thư viện core i18n** – Tạo package `packages/i18n` chứa: - `locales/` : JSON cho từng ngôn ngữ (en, vi, ja…). - `index.ts` : Xuất hook `useTranslation` wrapper cho `react-i18next` (web) và `expo-localization` + `i18n-js` (mobile). - `detector.ts` : Phát hiện ngôn ngữ thiết bị / trình duyệt. 2. **Cấu hình Next.js** – Trong `next.config.js` thêm `i18n: { locales: ['en','vi'], defaultLocale: 'en' }` và import hook từ `@monorepo/i18n`. 3. **Cấu hình Expo** – Cài `expo-localization`, `i18n-js`; trong `App.tsx` khởi tạo i18n với tài nguyên từ `@monorepo/i18n/locales`. 4. **Script đồng bộ** – Thêm script `sync:locales` dùng `node scripts/sync-locales.js` để copy JSON từ `packages/i18n/locales` sang `apps/web/public/locales` và `apps/mobile/assets/locales` trước khi build. ## Các bước triển khai chi tiết - **Bước 1**: Khởi tạo package `i18n` với `pnpm create package i18n`. - **Bước 2**: Viết `useTranslation` wrapper: ```ts export const useTranslation = (ns?: string) => { if (Platform.OS === 'web') return useTranslationWeb(ns); return useTranslationNative(ns); }; ``` - **Bước 3**: Cấu hình detector dùng `navigator.language` trên web và `Localization.locale` trên mobile. - **Bước 4**: Thêm namespace cho từng feature (auth, settings, errors) để lazy‑load qua `i18next-http-backend` (web) và `react-native-fs` (mobile). - **Bước 5**: Viết test đơn vị cho hook wrapper, kiểm tra fallback và pluralization. ## Mẹo thực chiến - Sử dụng **TypeScript** để sinh type an toàn cho key dịch thuật (`declare module 'react-i18next' { interface Resources { auth: AuthLocales; } }`). - Bật **ICU MessageFormat** cho plural, gender, date – tránh hard‑code logic trong component. - Tận dụng **GitHub Actions** chạy `pnpm sync:locales` và `pnpm test:i18n` mỗi PR. - Theo dõi **bundle analyzer** để đảm bảo chỉ nạp ngôn ngữ được chọn. ## Kết luận Với cấu trúc package chia sẻ và wrapper thống nhất, team có thể thêm ngôn ngữ mới chỉ trong vài phút, giảm thiểu bug liên quan đến locale và giữ cho codebase sạch, dễ bảo trì.
0 Facebook
2. 19:16 25/10/2026
Trả lời Quản Trị Viên ## Giới thiệu Khi phát triển ứng dụng chạy cùng lúc trên web và mobile trong một monorepo, việc quản lý đa ngôn ngữ (i18…
Cách tách package i18n dùng chung là hướng đúng, nhưng mình sẽ cân nhắc vài điểm thực tế. Thứ nhất, wrapper `useTranslation` có nhánh theo `Platform.OS` dễ vướng quy tắc hooks và khó test; nên tách entrypoint riêng cho web/native hoặc dùng chung một i18n instance rồi chỉ khác adapter detect/lazy-load. Thứ hai, `i18n` trong `next.config.js` chỉ phù hợp Pages Router; nếu dự án dùng App Router thì nên xử lý locale bằng middleware/segment thay vì copy nguyên cấu hình. Thứ ba, script `sync:locales` copy JSON sang `public/locales` và `assets/locales` dễ gây lệch bản dịch nếu quên chạy; với Expo, import trực tiếp từ package hoặc bundle sẵn thường đơn giản hơn, còn web có thể fetch từ một nguồn. Phần TypeScript key và ICU MessageFormat rất đáng làm sớm vì giảm lỗi runtime. Câu hỏi: team bạn đang dùng Next.js App Router hay Pages Router, và trên mobile có thực sự cần
0
Vui lòng đăng nhập để tham gia trả lời chủ đề này.
Điều hướng nhanh

Bạn muốn khám phá điều gì?

Tìm chủ đề, bài viết hoặc đi thẳng đến một khu vực của cộng đồng.

Esc để đóng Ctrl K để mở lại