💡 React Native adds Vietnamese in an afternoon: install
expo-localization, readgetLocales()[0].languageCodeto detectvi, wire upi18n-jsorreact-i18nextfor translations, format VND withIntl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND', maximumFractionDigits: 0 }), and display dates asdd/MM/yyyy. Vietnamese nouns never inflect for number, so a single translation key covers all counts.
Key takeaways
- Install
expo-localizationand callgetLocales()[0].languageCodeto getvion Vietnamese devices. Store the locale in state and pass it to your i18n library. - Vietnamese nouns do not change form with quantity. One translation key handles both "1 item" and "5 items" - no plural branch needed in most cases.
- VND has no sub-units: use
maximumFractionDigits: 0withIntl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND' }). The period (.) separates thousands in Vietnamese format. - Vietnamese date order is day-month-year. October 11 is 11/10, not 10/11. Use
Intl.DateTimeFormatwith thevi-VNlocale or hardcodedd/MM/yyyy. - Budget 20-30% extra horizontal space in Flexbox: Vietnamese diacritics make strings wider than English. Avoid fixed-width containers for buttons and tabs.
How do you detect and set Vietnamese in a React Native app?
Expo's expo-localization package is the recommended way to read the device locale. Install it with npx expo install expo-localization, then call getLocales() at startup:
import { getLocales } from 'expo-localization';
const deviceLang = getLocales()[0]?.languageCode ?? 'en'; // 'vi' on Vietnamese devices
const deviceTag = getLocales()[0]?.languageTag ?? 'en-US'; // 'vi-VN'
getLocales() returns the user's ordered preference list. The first entry is the primary locale. For Vietnamese, languageCode is vi and languageTag is vi-VN. Pass deviceLang to your translation library as the initial language. Store it in React state or a context so the UI re-renders when the user changes device language.
For non-Expo bare React Native projects, the community package react-native-localize provides the same getLocales() API. The returned shape is identical.
Which translation library works best for Vietnamese?
Expo's docs list four choices: i18n-js, react-i18next, Lingui, and Intlayer. Vietnamese works well with all of them. The practical tradeoffs are:
- i18n-js: lightweight (~10 kB), simple JSON translation files, easy to understand for non-engineers who maintain strings. Best for small-to-medium apps where translators edit JSON directly.
- react-i18next: the most widely used solution in the ecosystem. Supports ICU MessageFormat, namespaces, lazy loading, and backend plugins for fetching translations over-the-air. Best for apps with many screens or a CAT-tool workflow (Trados, Crowdin, Lokalise).
- Lingui: excellent TypeScript ergonomics and compile-time extraction. Good choice if your team values type safety and wants the i18n framework to stay out of the way at runtime.
All three export translation files as JSON. A Vietnamese translator can work in any of them without touching code. For teams connecting a TMS (Crowdin, Lokalise, Phrase), react-i18next has the broadest integration support.
How do plural rules work for Vietnamese in i18n libraries?
The Unicode CLDR plural rules define two plural categories for Vietnamese: one (n = 0 or 1) and other (all other values). However, Vietnamese nouns do not change form with quantity. "1 sản phẩm" and "5 sản phẩm" use the same word. In practice, the other translation covers all cases, and you only need an explicit entry for the empty state:
// i18n-js translation file: vi.json
{
"cart": {
"items_zero": "Giỏ hàng trống",
"items_one": "{{count}} sản phẩm",
"items_other":"{{count}} sản phẩm"
}
}
Notice items_one and items_other are identical - this is intentional. Vietnamese classifiers (loại từ) such as cái, con, chiếc do vary by noun category, but that is a fixed attribute of each noun, not a grammatical rule that changes with count. Machine translation frequently selects the wrong classifier for a noun class. That is a quick catch for a native Vietnamese reviewer that automated tools miss.
VND currency and date formatting in React Native
JavaScript's Intl.NumberFormat is available on both iOS and Android via JSC/Hermes. For VND, set maximumFractionDigits: 0 - the dong has no sub-units. Vietnamese formatting uses a period (.) as the thousands separator and a comma (,) as the decimal separator, the reverse of US English:
const vndFmt = new Intl.NumberFormat('vi-VN', {
style: 'currency',
currency: 'VND',
maximumFractionDigits: 0,
});
vndFmt.format(1250000); // "1.250.000 ₫"
Omitting maximumFractionDigits: 0 will produce an incorrect "1.250.000,00 ₫" on some runtime versions. Always set it explicitly.
Vietnamese date order is little-endian: day, month, year. October 11, 2026 is "11/10/2026". Displaying "10/11" confuses Vietnamese users who read it as November 10. Use Intl.DateTimeFormat with the vi-VN locale and explicit options, or use a formatting library such as date-fns with the vi locale imported:
// Intl.DateTimeFormat
new Intl.DateTimeFormat('vi-VN').format(new Date(2026, 9, 11));
// "11/10/2026"
// date-fns
import { format } from 'date-fns';
import { vi } from 'date-fns/locale';
format(new Date(2026, 9, 11), 'P', { locale: vi }); // "11/10/2026"
Why does Vietnamese text need more space on screen?
Vietnamese combines a base letter with up to two stacked diacritics per character. The word "ộ" (o + circumflex + dot below) is visually wider and taller than a plain Latin letter. Vietnamese strings run 20-30% longer than their English equivalents on average. "Settings" (8 characters) becomes "Cài đặt" (7 characters but visually wider), and "Notifications" (13 characters) becomes "Thông báo" (9 characters but taller due to stacked tone marks).
Build Flexbox layouts with flexible widths. Use flex: 1 rather than a fixed width for buttons and tabs. Test with Vietnamese active before shipping - a bottom tab bar that fits in English may clip labels in Vietnamese. DataReportal's 2025 Vietnam report counts 127 million mobile connections across 101 million people, meaning most Vietnamese users access your app on a phone. Small-screen clipping is immediately visible.
Font rendering: React Native uses the system font by default (San Francisco on iOS, Roboto on Android). Both handle Vietnamese diacritics well. If you use a custom font, test all 134 Vietnamese precomposed diacritic combinations. Missing glyphs render as boxes.
What you can do in-house vs when a native Vietnamese reviewer pays off
Your development team can handle the entire technical pipeline - expo-localization, the i18n library, Intl formatting - in a day. The resulting strings will be syntactically valid. Where non-native Vietnamese localization typically falls short:
- Register mismatch: B2B fintech and enterprise software use Sino-Vietnamese (Hán Việt) vocabulary. Consumer apps use everyday Vietnamese. Mixing the two registers in the same UI feels inconsistent to native speakers and signals that the app was not made for them.
- Classifier errors: Vietnamese classifiers pair with specific noun categories.
congoes with animals,cáiwith inanimate objects,chiếcwith vehicles or paired items. Machine translation picks the wrong one often enough that native users notice immediately. - UI edge cases: Error messages, empty states, permission prompts, and confirmation dialogs need natural Vietnamese. Awkward phrasing at these moments erodes user trust at the worst point in the flow.
A single review pass by a native Vietnamese localization specialist after a machine-translation first pass catches most of these issues for a fraction of the cost of full translation from scratch. For fintech, healthcare, or legal apps, build a Vietnamese terminology glossary before the first translation pass to keep register consistent across all screens.
FAQ
Does expo-localization work in bare React Native projects without Expo?
Yes, with a caveat. expo-localization is an Expo module and requires the Expo Modules API to be installed in your project. For bare React Native without any Expo dependency, use react-native-localize instead - it provides the same getLocales() API and works without the Expo toolchain.
How do I test Vietnamese locale in the iOS simulator?
In Xcode, go to the scheme editor (Cmd+Shift+,), select the Run scheme, open the Options tab, and set Application Language to Vietnamese. The simulator will restart with Vietnamese locale active. On Android, go to Settings - General management - Language - Add language - Vietnamese and move it to the top of the list. Alternatively, wrap your component in a test with the locale forced in state to avoid restarting the device.
Should I store translations in the app bundle or fetch them remotely?
Bundle translations for the core UI - settings, navigation, error messages - so the app works offline. Use remote fetching (via react-i18next's i18next-http-backend or Expo Updates) for content that changes frequently, such as marketing copy or feature announcements. Vietnamese strings in the core bundle add under 20 KB to your app size for a typical app.
Can I use Google Translate or DeepL to generate the Vietnamese translations?
For a first draft, yes. Modern neural MT handles Vietnamese at a fluency level that is usable for basic navigation text. The practical limit is register and classifier accuracy: B2B software vocabulary and noun classifiers are where MT output most often needs correction by a Vietnamese speaker. A human review pass on MT output costs significantly less than translating from scratch.
What is the difference between languageCode "vi" and languageTag "vi-VN"?
languageCode is the ISO 639-1 two-letter language identifier. vi means Vietnamese regardless of region. languageTag is the BCP 47 tag combining language and region: vi-VN means Vietnamese as used in Vietnam. For Intl.NumberFormat and Intl.DateTimeFormat, pass vi-VN to get Vietnamese formatting conventions (period thousands separator, day-first dates). Pass vi to your translation library unless you need regional variants.
Official Sources
- Expo Localization Guide - expo-localization package, getLocales() API, recommended translation libraries. Verified Nov 2026.
- MDN Intl.NumberFormat reference - currency formatting options, maximumFractionDigits. Verified Nov 2026.
- Unicode CLDR Plural Rules - Vietnamese plural categories (one/other). Verified Nov 2026.
- DataReportal Digital 2025: Vietnam - 127 million mobile connections, 101 million population, 79.8 million internet users. Verified Nov 2026.

Written by Dao Huy (Lucas), Vietnamese translator and localization specialist (English, Chinese and French into Vietnamese). See translation services →
