Bạn biết tôi qua Upwork? Nếu bạn biết tôi qua Upwork và muốn sử dụng dịch vụ, vui lòng liên hệ qua Upwork. Tin nhắn từ khách Upwork gửi ngoài Upwork sẽ không được trả lời.
Ghi chú bản địa hóa🌏 Bản địa hóa

Bản địa hóa ứng dụng Flutter sang tiếng Việt: ARB, số nhiều và VND

Thêm tiếng Việt vào Flutter: cấu hình gen-l10n, tệp app_vi.arb, quy tắc số nhiều CLDR, định dạng VND không có số thập phân và ngày theo chuẩn dd/MM/yyyy.

Dao Huy (Lucas)7 phút đọc8 mục
Bản địa hóa ứng dụng Flutter sang tiếng Việt: ARB, số nhiều và VND

💡 Flutter hỗ trợ tiếng Việt chỉ trong vài giờ: thêm flutter_localizations và intl: any vào pubspec.yaml, tạo lib/l10n/app_vi.arb, khai báo Locale('vi') và chạy flutter gen-l10n. Tiếng Việt không biến hóa danh từ theo số lượng, nên một nhánh other{...} thường đủ cho hầu hết chuỗi. Định dạng VND với decimalDigits: 0, ngày tháng theo chuẩn dd/MM/yyyy.

Ý chính

  • Thêm flutter_localizations và intl: any vào pubspec.yaml; bật generate: true và tạo tệp l10n.yaml ở thư mục gốc.
  • Tạo lib/l10n/app_vi.arb với các khóa ICU giống template tiếng Anh - chỉ thay đổi giá trị chuỗi.
  • Tiếng Việt có hai loại số nhiều CLDR (one cho n=0 hoặc n=1; other cho n≥2) nhưng danh từ không biến hóa: =0{...} và other{...} thường là đủ.
  • Tiền tệ VND: dùng NumberFormat.currency(locale: 'vi_VN', symbol: '₫', decimalDigits: 0) - không có số thập phân, dấu chấm phân cách hàng nghìn.
  • Ngày tháng theo thứ tự ngày-tháng-năm: DateFormat('dd/MM/yyyy', 'vi_VN'). Kiểm tra trên thiết bị trước khi nộp lên App Store.

Làm thế nào để thêm tiếng Việt vào pipeline gen-l10n của Flutter?

Giải pháp i18n chính thức của Flutter dùng tệp ARB (Application Resource Bundle) được xử lý bởi công cụ gen-l10n. Cài đặt gồm ba bước: cập nhật phụ thuộc, tạo tệp cấu hình, và khai báo locale trong MaterialApp.

Trong pubspec.yaml, thêm flutter_localizations từ Flutter SDK và intl: any, bật generate: true dưới khóa flutter:. Tiếp theo tạo l10n.yaml ở thư mục gốc dự án:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

Trong MaterialApp, truyền AppLocalizations.delegate và ...GlobalMaterialLocalizations.delegates vào localizationsDelegates. Thêm Locale('vi') vào supportedLocales. Chạy flutter gen-l10n hoặc flutter pub get để tạo class Dart đã đánh kiểu.

Tệp app_vi.arb trông như thế nào?

Tệp ARB là JSON với các chuỗi thông báo ICU làm giá trị. Các khóa trong bản tiếng Việt hoàn toàn giống template tiếng Anh - chỉ thay nội dung chuỗi. Dưới đây là ví dụ tối giản:

{
  "appTitle": "Ứng dụng của tôi",
  "greeting": "Xin chào, {name}!",
  "@greeting": {
    "placeholders": {
      "name": { "type": "String" }
    }
  },
  "itemCount": "{count, plural, =0{Không có mục nào} other{{count} mục}}"
}

Metadata @key mô tả từ template tiếng Anh là tùy chọn trong ARB bản dịch. Chỉ thêm @key khi bạn cần định nghĩa placeholder mới hoặc ghi chú riêng cho locale.

Lưu tệp ARB dưới dạng UTF-8 không BOM. Dấu tiếng Việt phải là Unicode thật sự, không phải các chuỗi escape. Nếu pipeline CI chạy trên Windows và chạm vào các tệp này, hãy kiểm tra mã hóa trước khi đẩy lên.

Quy tắc số nhiều trong tiếng Việt hoạt động ra sao?

Theo quy tắc số nhiều Unicode CLDR, tiếng Việt có hai loại cơ bản: one (khi n = 0 hoặc n = 1) và other (n ≥ 2). Khác với tiếng Anh, danh từ tiếng Việt không thay đổi hình thức khi số lượng thay đổi. "1 cuốn sách" và "5 cuốn sách" dùng cùng từ "sách".

Vì vậy, hầu hết chuỗi UI chỉ cần một nhánh other{...} cùng với =0{...} cho trạng thái trống:

"cartItems": "{count, plural, =0{Giỏ hàng trống} other{{count} sản phẩm}}"

Bạn không cần nhánh one{...} riêng như tiếng Anh (“1 item” vs “2 items”). Điều này giảm đáng kể khối lượng dịch so với các ngôn ngữ biến hóa như tiếng Pháp hay tiếng Đức.

Lưu ý danh từ tiếng Việt thường đi kèm loại từ (cái, con, chiếc, cuốn, tờ). Dịch máy thường chọn sai loại từ - "con" dùng cho động vật, "cái" dùng cho đồ vật. Đây là một trong những lỗi mà chỉ có người kiểm tra bản ngữ mới phát hiện được.

Định dạng số, tiền tệ và ngày tháng cho người dùng Việt Nam

VND không có đơn vị nhỏ hơn. Mọi mức giá đều là số nguyên. Hiển thị "1.250.000,00 ₫" là sai và gây nhầm lẫn cho người mua hàng.

Tiếng Việt dùng dấu chấm (.) phân cách hàng nghìn và dấu phẩy (,) phân cách số thập phân - ngược với tiếng Anh. Dùng gói intl của Dart:

final vndFormat = NumberFormat.currency(
  locale: 'vi_VN',
  symbol: '₫',
  decimalDigits: 0,
);
print(vndFormat.format(1250000)); // "1.250.000 ₫"

Về ngày tháng, thứ tự ngày-tháng-năm là chuẩn Việt Nam. Ngày 11/10/2026 nghĩa là 11 tháng 10, không phải 10 tháng 11. Dùng DateFormat('dd/MM/yyyy', 'vi_VN'). Môi trường kinh doanh dùng giờ 24h: DateFormat('HH:mm', 'vi_VN').

Tại sao chuỗi tiếng Việt dài hơn tiếng Anh trên màn hình?

Tiếng Việt dùng dấu chồng - một ký tự như "ộ" (o + mũ + chấm dưới) rộng hơn một chữ Latin thường trong hầu hết font. Chuỗi tiếng Việt thường cần nhiều hơn 20-30% chiều rộng ngang so với tiếng Anh tương đương. "Add to cart" (11 ký tự) thành "Thêm vào giỏ hàng" (18 ký tự kèm dấu).

Thiết kế giao diện với ràng buộc linh hoạt. Dùng Expanded, FittedBox hoặc độ rộng theo tỷ lệ cho nút, chip và nhãn tab thay vì các giá trị pixel cố định. Kiểm tra với locale tiếng Việt trước khi nộp ứng dụng. Báo cáo DataReportal 2025 về Việt Nam ghi nhận 127 triệu kết nối di động trên 101 triệu dân số.

Những gì nhóm kỹ thuật tự làm được và khi nào cần chuyên gia bản ngữ

Toàn bộ pipeline kỹ thuật (ARB, gen-l10n, định dạng số và ngày) nằm trong tầm tay của lập trình viên và chỉ mất vài giờ để thiết lập. Kết quả sẽ hợp lệ về cú pháp và cấu trúc.

Nơi mà bản dịch không phải bản ngữ thường thiếu sót:

  • Sai văn phong: Phần mềm doanh nghiệp dùng từ Hán Việt, ứng dụng tiêu dùng dùng tiếng Việt thuần. Dịch máy thường trộn lẫn hai loại, tạo cảm giác không nhất quán cho người dùng bản ngữ.
  • Sai loại từ: Loại từ tiếng Việt (cái, con, chiếc, cuốn) phụ thuộc vào loại vật. Dịch máy thường chọn sai và người dùng Việt nhận ra ngay.
  • Các trường hợp biên: Thông báo lỗi, trạng thái trống, hộp xác nhận cần tiếng Việt tự nhiên. Ngôn ngữ lú̀ng cu£ng ở đây ảnh hưởng trực tiếp đến niềm tin.

Một lượt kiểm tra của chuyên gia bản địa hóa tiếng Việt sau bước dịch máy sẽ phát hiện hầu hết các vấn đề này. Với ứng dụng tài chính, y tế hoặc pháp lý, hãy xây dựng bảng thuật ngữ trước khi dịch để đảm bảo nhất quán trong toàn bộ giao diện.

Câu hỏi thường gặp

Flutter có sẵn bản dịch tiếng Việt cho các widget Material không?

Có. Thêm GlobalMaterialLocalizations.delegate và GlobalCupertinoLocalizations.delegate vào localizationsDelegates là bạn có chuỗi tiếng Việt cho date picker, nút quay lại, nút hộp thoại và các widget chuẩn khác. Bạn vẫn cần cung cấp bản dịch cho chuỗi của ứng dụng qua ARB.

Tôi có thể bỏ qua khóa trong app_vi.arb khi chuỗi giống hệt tiếng Anh không?

Có thể. Nếu một chuỗi như tên thương hiệu hoặc thuật ngữ kỹ thuật giống nhau ở cả hai ngôn ngữ, hãy bỏ khóa đó khỏi app_vi.arb và Flutter sẽ dùng giá trị template. Nên ghi chú trong mô tả @key của tiếng Anh rằng đây là chuỗi cố ý không dịch.

Font nào hiển thị tốt nhất cho dấu tiếng Việt trong Flutter?

Noto Sans là lựa chọn đáng tin cậy nhất. Font này hỗ trợ toàn bộ 134 tổ hợp dấu tiếng Việt. Thêm qua gói google_fonts và dùng GoogleFonts.notoSans(). Nếu bó font tùy chỉnh, hãy kiểm tra các tổ hợp dấu: ắ ặ ể ị ộ ụ ướ ự - đây là những ký tự dễ hiển thị sai nhất.

Kiểm tra locale tiếng Việt trên máy ảo mà không cần đổi ngôn ngữ hệ thống?

Bọc MaterialApp trong Localizations.override khi phát triển: Localizations.override(context: context, locale: const Locale('vi'), child: MaterialApp(...)). Điều này ép locale tiếng Việt cho phần cây widget đó mà không thay đổi ngôn ngữ thiết bị. Nhớ xóa wrapper này trước khi phát hành.

Khi nào nên dùng người dịch con người thay vì dịch máy?

Dùng người dịch khi ứng dụng xử lý tiền bạc, dữ liệu y tế, điều khoản pháp lý hoặc nội dung nhạy cảm. Với ứng dụng tiêu dùng thông thường, dịch máy rồi kiểm tra bản ngữ là hướng hiệu quả về chi phí. Tham khảo dịch vụ bản địa hóa website cho các dự án cần chất lượng cao.

Nguồn

Dao Huy (Lucas)
Dao Huy (Lucas)
Tốt nghiệp Trường Đại học Ngoại ngữ, Đại học Đà Nẵng. Ký cam kết chính xác trên mọi bản dịch có xác nhận (USCIS, IRCC).

Bài viết bởi Đào Huy (Lucas), biên dịch viên và chuyên viên bản địa hóa tiếng Việt (Anh, Trung, Pháp sang Việt). See translation services →

Báo giáWhatsApp