← Studio Log
D. 기술 신뢰 (Uy tín)다국어국제화로케일앱 개발베트남 시장

Thiết kế locale đa ngôn ngữ: Việt, Hàn, Anh trong một app

Thiết kế locale đa ngôn ngữ: Việt, Hàn, Anh trong một app
viết bởi Yeowubie

Vì sao chỉ thêm file dịch là chưa đủ

Nếu hiểu đa ngôn ngữ chỉ là thay chuỗi văn bản, vấn đề sẽ tích tụ ngay sau khi phát hành. Câu chữ hiển thị chỉ là một trong nhiều giá trị mà locale quyết định. Định dạng ngày, dấu phân cách số, thứ tự tên, thứ tự nhập địa chỉ, quy tắc sắp xếp và giờ gửi thông báo đều rẽ nhánh theo. File dịch chỉ là phần dễ thấy nhất.

Phần lớn sự cố thực tế nằm ngoài câu chữ. Người dùng Việt Nam viết ngày theo thứ tự ngày, tháng, năm. Người dùng Hàn Quốc viết năm trước rồi mới đến tháng và ngày. Người dùng nói tiếng Anh lại đọc cùng một ngày theo một trật tự khác nữa. Nếu máy chủ dựng sẵn chuỗi ngày theo một trật tự duy nhất rồi gửi xuống, phía client không còn chỗ để can thiệp. Ngược lại, khi máy chủ gửi mốc thời gian tuyệt đối và để client lo phần hiển thị, việc thêm locale mới không buộc phải sửa code máy chủ. Phân biệt được ranh giới này sẽ quyết định cho bản thiết kế đầu tiên.

Sắp xếp là chỗ hay bị bỏ quên. Khi nói sắp xếp danh sách tên theo thứ tự bảng chữ cái, thứ tự đó khác nhau giữa các ngôn ngữ. Tiếng Việt có quy tắc riêng cho chữ mang dấu thanh và dấu phụ, còn tiếng Hàn đi theo trật tự phụ âm của bảng chữ cái. Nếu phó mặc cho quy tắc so sánh mặc định của cơ sở dữ liệu, người dùng sẽ thấy một danh sách trông như xáo trộn ngẫu nhiên. Lúc dữ liệu còn ít thì không ai để ý, đến khi dữ liệu dày lên thì phản hồi mới đến.

Tìm kiếm còn khó hơn một bậc. Người dùng Việt Nam rất hay gõ không dấu. Nếu so khớp nguyên văn có dấu, người dùng sẽ không tìm ra mục vốn chắc chắn tồn tại. Vì vậy nên tạo thêm một chỉ mục phụ đã bỏ dấu ngay khi lưu dữ liệu. Trong tiếng Hàn lại có người mong tìm được bằng cách gõ phụ âm đầu. Những kỳ vọng này khác nhau theo ngôn ngữ và không hề được thể hiện trong file dịch.

Yeowubie Interaction làm việc đồng thời ở Hàn Quốc và Việt Nam, vừa xây sản phẩm của chính mình vừa phát triển sản phẩm cho khách hàng. Với cách làm đó, đa ngôn ngữ gần như là điều kiện mặc định chứ không phải tùy chọn. onSpots, dịch vụ quản lý chấm công, được xây dựng như một dịch vụ đa ngôn ngữ không giới hạn ở một quốc gia. Langtori, công cụ kết nối giữa người học tiếng Hàn và người dạy, hỗ trợ locale tiếng Hàn, tiếng Việt và tiếng Anh, trong đó trọng tâm là tiếng Việt. Ở cả hai sản phẩm, phần việc nằm ngoài file dịch tốn thời gian hơn chính file dịch.

Nói gọn lại, quốc tế hóa là việc của mô hình dữ liệu chứ không phải việc của chuỗi ký tự. Trước tiên phải quyết định giá trị nào được lưu ở dạng gốc và giá trị nào được dựng ra tại thời điểm hiển thị. Đảo ngược thứ tự này thì mỗi lần thêm một ngôn ngữ, đội phát triển lại phải mở lại nhiều chỗ trong code.

Tách riêng ngôn ngữ, khu vực, tiền tệ và ngày tháng

Gói locale thành một giá trị duy nhất thì sớm muộn cũng phải tách ra. Ngôn ngữ, khu vực, tiền tệ, múi giờ và định dạng ngày thay đổi độc lập với nhau. Một người Hàn Quốc sống tại Việt Nam muốn xem giao diện tiếng Hàn nhưng dùng giờ Việt Nam và đồng Việt Nam. Cấu trúc không diễn tả được tổ hợp đó sẽ buộc người dùng chịu thiệt ở một phía.

Nếu hồ sơ người dùng chỉ có đúng một trường ngôn ngữ, tổ hợp trên bị chặn ngay từ đầu. Tối thiểu nên lưu ngôn ngữ hiển thị và khu vực thành hai trường, còn múi giờ là một trường riêng. Tiền tệ thường phải bám theo đồng tiền của giao dịch chứ không theo sở thích người dùng, nên hợp lý hơn khi gắn nó vào miền thanh toán. Chia sẵn như vậy thì sau này thêm quy tắc theo khu vực cũng không phải động vào các trường cũ.

Hiển thị số tiền cần lưu ý riêng. Đồng Việt Nam trên thực tế không dùng phần thập phân và có số chữ số lớn. Won Hàn Quốc cũng không có phần thập phân. Trong khi đó đô la Mỹ dùng hai chữ số thập phân. Nếu ghi cứng số chữ số thập phân vào code, cứ thêm một loại tiền tệ là thêm một nhánh điều kiện. Cách bền hơn là lưu số tiền dưới dạng số nguyên theo đơn vị nhỏ nhất, luôn đi kèm mã tiền tệ, và đọc số chữ số hiển thị từ metadata của tiền tệ đó. Dấu phân cách hàng nghìn cũng khác nhau theo khu vực. Có nơi vai trò của dấu chấm và dấu phẩy đảo ngược, nên tự ghép chuỗi số một cách thủ công là tự gây khó khăn cho bản thân mình.

Với thời gian, hãy tách bạch giữa lưu trữ và hiển thị. Lưu vào cơ sở dữ liệu ở dạng mốc tuyệt đối có thông tin múi giờ, rồi chuyển sang múi giờ của người dùng khi hiển thị. Hàn Quốc và Việt Nam lệch nhau hai tiếng, nên ở những tính năng lấy thời điểm làm căn cứ phán định như chấm công hay hạn nộp, độ lệch này lập tức biến thành tranh cãi. Lấy múi giờ nào để cắt một ngày cũng là quyết định chính sách. Nếu không ghi rõ là nửa đêm theo giờ người dùng hay nửa đêm theo múi giờ vận hành của dịch vụ dẫn đến việc mỗi người triển khai sẽ hiểu một kiểu khác nhau.

Cách chèn giá trị vào câu cũng nên thống nhất trước. Cắt câu thành nhiều phần rồi nối lại sẽ không khớp được nếu thực hiện ở những ngôn ngữ có trật tự từ khác. Tiếng Hàn đặt vị ngữ ở cuối câu, còn tiếng Việt đặt từ bổ nghĩa sau danh từ. Vì vậy đơn vị dịch phải là cả câu có chứa chỗ giữ chỗ. Hầu hết thư viện quốc tế hóa phổ biến đều hỗ trợ cách này, nhưng cú pháp chi tiết khác nhau giữa các thư viện, nên trước khi đưa vào dự án hãy đọc tài liệu thực tế và chốt một quy ước chung cho đội.

Xử lý số nhiều cũng khác nhau theo ngôn ngữ. Tiếng Anh phân biệt số ít và số nhiều, còn tiếng Hàn và tiếng Việt không bắt buộc phân biệt đó về mặt ngữ pháp. Ghi cứng nhánh rẽ hai chiều theo chuẩn tiếng Anh sẽ sinh ra những câu gượng gạo ở ngôn ngữ khác. An toàn hơn là khai báo quy tắc số nhiều ngay trong tài nguyên dịch theo từng ngôn ngữ, còn code chỉ truyền xuống con số.

Áp lực mà tiếng Việt và tiếng Hàn đặt lên bố cục

Cùng một nội dung nhưng độ dài câu khác nhau theo ngôn ngữ. Tiếng Việt cao hơn về mặt chiều dọc vì có dấu thanh, tiếng Hàn nén lại ngắn gọn, còn tiếng Anh nằm đâu đó ở giữa. Khác biệt này lộ ra ngay tại những chỗ có bề rộng cố định như nút bấm, tab và tiêu đề thẻ. Bố cục phải được kiểm tra theo ngôn ngữ dài nhất.

Dấu thanh và dấu phụ trong tiếng Việt nằm cả phía trên lẫn phía dưới chữ. Nếu đặt khoảng cách dòng quá hẹp, dấu phía trên sẽ bị cắt hoặc dính vào dòng trước. Khoảng cách trông ổn ở giao diện tiếng Hàn và tiếng Anh nhưng vỡ riêng ở tiếng Việt thường là vì lý do này. Khi chọn phông chữ cũng phải kiểm tra xem bộ chữ có phủ đủ các ký tự mở rộng của tiếng Việt hay không. Nếu thiếu, trình duyệt hoặc hệ điều hành sẽ thay bằng phông khác, và ngay khoảnh khắc đó hình dạng chữ trong cùng một câu bị pha trộn.

Tiếng Hàn có một vấn đề ngắt dòng riêng. Ở hành vi mặc định của web, tiếng Hàn bị cắt ngay giữa từ và phần còn lại rơi xuống dòng dưới. Một từ hai âm tiết bị xẻ làm đôi qua hai dòng khiến người đọc thấy gợn ngay lập tức. Nhìn thì tưởng chuyện thẩm mỹ, thực chất là chuyện dễ đọc và độ tin cậy. Cần khai báo trong phần định kiểu để việc ngắt dòng diễn ra theo đơn vị từ, và ở những chỗ mà cách ngắt dòng quyết định ý nghĩa như tiêu đề lớn thì nên chủ động chia dòng thay vì phó mặc cho trình duyệt tự xuống dòng. Nếu lập trình viên không biết điều này thì sẽ không ai nhắc, bởi với người kiểm duyệt không biết tiếng Hàn, màn hình trông vẫn bình thường.

Chênh lệch độ dài câu nên được hấp thụ bằng thiết kế. Ép dịch ngắn lại cho vừa một dòng nút bấm sẽ làm nghĩa bị mờ đi. Thay vào đó, cho phép nút giãn ra hai dòng, hoặc đặt chiều cao tối thiểu rồi để nội dung tự đẩy chiều cao. Màn hình dạng bảng đặc biệt dễ vỡ. Bảng có bề rộng cột cố định chỉ vừa với một ngôn ngữ, các ngôn ngữ còn lại hoặc bị cắt hoặc thừa chỗ. Cách chuyển bảng thành danh sách thẻ trên màn hình hẹp cũng phát huy tác dụng tốt trong bối cảnh đa ngôn ngữ.

Cách kiểm tra cũng nên được quy định. Mỗi khi dựng xong một màn hình, hãy xem giao diện đã render thật ở cả ba ngôn ngữ, trên cả máy tính lẫn điện thoại. Việc kiểm tra kiểu dữ liệu chạy qua không có nghĩa là bố cục đã được xác nhận. Một cách khác là thử chèn chuỗi dài nhất có thể. Nếu bản dịch chưa có, hãy dùng chuỗi giả được kéo dài để thử bề rộng trước.

Cắt chữ bằng dấu ba chấm chỉ nên là phương án cuối. Câu bị cắt là thông tin đã mất, và người dùng không biết phần mất đi là gì. Với những giá trị quan trọng như tên người, địa chỉ hay tên cửa hàng, việc bị cắt gây rắc rối thật sự. Phân định ngay từ khâu thiết kế màn hình rằng giá trị nào được phép cắt và giá trị nào bắt buộc hiển thị đủ sẽ giúp đội tránh tranh luận giữa lúc đang code.

Chọn ngôn ngữ mặc định và quy tắc fallback

Không chốt ngôn ngữ mặc định và quy tắc fallback thì màn hình sẽ trống hoặc lộ ra tên khóa dịch. Có ba việc cần quyết. Hiển thị gì cho người truy cập lần đầu, lùi về ngôn ngữ nào khi thiếu bản dịch, và tôn trọng lựa chọn của người dùng trong bao lâu. Cả ba đều là chính sách chứ không phải code.

Với màn hình đầu tiên, nên tham khảo thiết lập của trình duyệt hoặc thiết bị nhưng không nên theo y nguyên. Thiết bị bán tại Việt Nam thường được đặt sang tiếng Anh, và người dùng Hàn Quốc cũng có người dùng hệ điều hành bản tiếng Anh. Hãy đặt thiết lập thiết bị, khu vực truy cập và thị trường trọng tâm của dịch vụ cạnh nhau rồi xác định thứ tự ưu tiên. Langtori hỗ trợ ba ngôn ngữ nhưng đặt trọng tâm ở tiếng Việt, nên trong vùng khó phán đoán thì nghiêng về tiếng Việt. Quyết định như vậy khác nhau theo từng sản phẩm, và phải ghi rõ căn cứ vào tài liệu để về sau không tranh luận lại từ đầu.

Khi người dùng tự đổi ngôn ngữ, đó là tín hiệu mạnh nhất. Ở các lần truy cập sau, hãy ưu tiên lựa chọn của người dùng bất kể thiết bị đang đặt gì. Người dùng đã đăng nhập thì lưu vào tài khoản, người chưa đăng nhập thì lưu ở bộ nhớ trình duyệt. Lỗi hay gặp ở đây là ngay lúc đăng nhập, giá trị lưu trong tài khoản ghi đè lựa chọn hiện tại và giao diện đổi ngôn ngữ đột ngột. Hãy quyết trước bên nào thắng và xử lý ở một chỗ duy nhất.

Fallback nên được dựng theo bậc. Thiếu biến thể theo khu vực thì lùi về ngôn ngữ cha, thiếu cả ngôn ngữ cha thì lùi về một ngôn ngữ chuẩn đã chỉ định. Ngôn ngữ chuẩn phải là ngôn ngữ được quản lý để tuyệt đối không thiếu bản dịch. Nếu coi ba ngôn ngữ ngang nhau hoàn toàn, kết cục là không ngôn ngữ nào đầy đủ. Khi ngay cả ngôn ngữ chuẩn cũng thiếu khóa thì chuỗi khóa sẽ hiện ra màn hình, nên tốt hơn là đặt một bước kiểm tra khóa thiếu ở khâu build và cho build thất bại.

Fallback không chỉ áp dụng cho văn bản. Banner có chữ nằm trong ảnh, văn bản điều khoản khác nhau theo ngôn ngữ, kênh hỗ trợ khách hàng theo ngôn ngữ đều đi theo cùng quy tắc. Nếu màn hình tiếng Việt dẫn sang bản điều khoản tiếng Hàn, người dùng mất niềm tin ngay tại thời điểm đó. Với tài liệu cần hiệu lực pháp lý, còn phải ghi rõ bản ngôn ngữ nào là bản gốc dùng làm căn cứ. Phần này cần kiểm tra riêng theo tính chất từng dịch vụ.

Cấu trúc đường dẫn cũng nên chốt sớm. Đưa ngôn ngữ vào đường dẫn, tách theo tên miền phụ, hay giữ cùng một địa chỉ và phán đoán bằng header sẽ dẫn tới trải nghiệm chia sẻ và khả năng hiển thị trên công cụ tìm kiếm khác nhau. Nếu cùng một địa chỉ hiện ngôn ngữ khác nhau tùy người truy cập, công cụ tìm kiếm khó xác định nên lập chỉ mục ngôn ngữ nào, và người nhận được link chia sẻ sẽ thấy một ngôn ngữ khác. Cấp cho mỗi ngôn ngữ một địa chỉ riêng và khai báo liên kết trỏ qua lại giữa chúng là cấu trúc dễ vận hành hơn.

Đa ngôn ngữ kéo dài đến khâu vận hành nội dung

Đa ngôn ngữ không kết thúc ở lần phát hành. Thông báo, mô tả sản phẩm, trang trợ giúp và tin đẩy vẫn tiếp tục sinh ra sau khi ra mắt. Nếu không định trước ai lấp đầy ba ngôn ngữ, theo thứ tự nào, và hiển thị gì khi một ngôn ngữ còn trống, thì càng về sau nội dung giữa các ngôn ngữ càng lệch nhau. Quy tắc vận hành quan trọng ngang với code.

Hãy bắt đầu từ mô hình nội dung. Cấu trúc nên là một mục duy nhất với các bản nội dung theo ngôn ngữ gắn bên dưới, để có thể theo dõi trạng thái dịch theo từng mục. Nếu tạo mục riêng cho mỗi ngôn ngữ, sẽ không biết đâu là bản gốc và bản dịch nào đã cũ khi bản gốc được sửa. Gắn thêm trường trạng thái cho từng bản ngôn ngữ để phân biệt bản nháp, chờ duyệt và đã phát hành sẽ ngăn được sự cố bản dịch dở dang lọt ra ngoài.

Về bản thân việc dịch, cách thực tế là để máy dựng bản nháp rồi người biên tập lại. Có điều những chỗ cần người thì đã rõ. Thuật ngữ riêng của sản phẩm, câu chữ mang tính pháp lý và những câu dẫn dắt hành động của người dùng đều cần mắt người. Quản lý một bảng thuật ngữ riêng sẽ ngăn hiện tượng cùng một khái niệm bị dịch thành từ khác nhau ở mỗi màn hình. Bảng thuật ngữ vừa là tài liệu giao cho người dịch, vừa đóng vai trò bản thỏa thuận nội bộ của đội.

Thông báo cần được xử lý tách riêng. Phải đọc thiết lập ngôn ngữ của người dùng tại thời điểm gửi để chọn nội dung, và định dạng thời gian cũng phải khớp múi giờ người dùng. Thông báo đã dựng sẵn và xếp vào hàng đợi mà gửi đi sau khi người dùng đổi ngôn ngữ thì sẽ đi bằng ngôn ngữ cũ. An toàn hơn là chốt ngôn ngữ ngay trước lúc gửi. Giờ gửi cũng phải tính đến khu vực. Chín giờ sáng theo giờ Hàn Quốc là bảy giờ sáng theo giờ Việt Nam.

Khả năng hiển thị trên công cụ tìm kiếm cũng là hạng mục vận hành. Hãy quản lý tiêu đề và phần tóm tắt riêng theo từng ngôn ngữ, và đừng bê nguyên một cách diễn đạt hiệu quả ở ngôn ngữ này sang ngôn ngữ khác. Từ khóa tiếng Việt và từ khóa tiếng Hàn có hình thái khác nhau dù cùng một chủ đề. Hãy viết lại dựa trên cách người dùng ngôn ngữ đó thực sự gõ vào ô tìm kiếm, chứ không dựa trên tiêu đề đã dịch. Việc này thuộc về vận hành nội dung chứ không phải phát triển, và nếu không chỉ định người phụ trách thì sẽ không ai làm.

Cuối cùng là chu kỳ rà soát. Khoảng mỗi quý một lần, đặt màn hình ba ngôn ngữ cạnh nhau và so sánh thì những chỗ lệch sẽ hiện ra. Đó là hướng dẫn cũ chỉ còn sót ở một ngôn ngữ, phần mô tả tính năng mới chỉ thiếu ở một ngôn ngữ, hay kênh liên hệ khác nhau giữa các ngôn ngữ. Ở sản phẩm đa ngôn ngữ, chất lượng được phân định tại những lần rà soát như vậy chứ không phải ở lần dựng đầu tiên. Trước khi quyết định thêm một ngôn ngữ, hãy tính trước chi phí duy trì ngôn ngữ đã thêm.