HomeGuidesReferenceLearn

Expo Localization iconExpo Localization

GitHub

npm


expo-localization allows you to Localize your app, customizing the experience for specific regions, languages, or cultures. It also provides access to the locale data on the native device. Using the popular library i18n-js with expo-localization will enable you to create a very accessible experience for users.

Platform Compatibility

Android DeviceAndroid EmulatoriOS DeviceiOS SimulatorWeb

Installation

Terminal
npx expo install expo-localization

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

Usage

Let's make our app support English and Japanese. To achieve this install the i18n package i18n-js:

Terminal
expo install i18n-js

Then, configure the languages for your app.

import * as Localization from 'expo-localization';
import { I18n } from 'i18n-js';

// Set the key-value pairs for the different languages you want to support.
const i18n = new I18n({
  en: { welcome: 'Hello' },
  ja: { welcome: 'こんにちは' },
});

// Set the locale once at the beginning of your app.
i18n.locale = Localization.locale;

API Design Tips

  • You may want to refrain from localizing text for certain things, like names. In this case you can define them once in your default language and reuse them with i18n.enableFallback = true;.
  • When a user changes the device's language, your app will reset. This means you can set the language once, and don't need to update any of your React components to account for the language changes.
  • On iOS, you can add "CFBundleAllowMixedLocalizations": true to your ios.infoPlist property in your app.json so that your app supports the retrieval of localized strings from frameworks.
    • This will allow you to translate app metadata, including the homescreen display name! Read here for details.

Full Demo

Localization
import { View, StyleSheet, Text } from 'react-native';
import * as Localization from 'expo-localization';
import { I18n } from 'i18n-js';

// Set the key-value pairs for the different languages you want to support.
const translations = {
  en: { welcome: 'Hello', name: 'Charlie' },
  ja: { welcome: 'こんにちは' },
};
const i18n = new I18n(translations);

// Set the locale once at the beginning of your app.
i18n.locale = Localization.locale;

// When a value is missing from a language it'll fallback to another language with the key present.
i18n.enableFallback = true;
// To see the fallback mechanism uncomment line below to force app to use Japanese language.
// i18n.locale = 'ja';

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>
        {i18n.t('welcome')} {i18n.t('name')}
      </Text>
      <Text>Current locale: {i18n.locale}</Text>
      <Text>Device locale: {Localization.locale}</Text>
    </View>
  );
}

%%placeholder-start%%const styles = StyleSheet.create({ ... }); %%placeholder-end%%const styles = StyleSheet.create({
  container: {
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    flex: 1,
  },
  text: {
    fontSize: 20,
    marginBottom: 16,
  },
});

API

import * as Localization from 'expo-localization';

Behavior

This API is mostly synchronous and driven by constants. On iOS the constants will always be correct, on Android you should check if the locale has updated using AppState and Localization.getLocalizationAsync(). Initially the constants will be correct on both platforms, but on Android a user can change the language and return, more on this later.

Constants

Localization.currency

Type: null | string


Three-character ISO 4217 currency code. Returns null on web.

Example

'USD', 'EUR', 'CNY', null

Localization.decimalSeparator

Type: string


Decimal separator used for formatting numbers.

Example

',', '.'

Localization.digitGroupingSeparator

Type: string


Digit grouping separator used when formatting numbers larger than 1000.

Example

'.', '', ','

Localization.isMetric

Type: boolean


Boolean value that indicates whether the system uses the metric system. On Android and web, this is inferred from the current region.

Localization.isRTL

Type: boolean


Returns if the system's language is written from Right-to-Left. This can be used to build features like bidirectional icons.

Returns false in Server Side Rendering (SSR) environments.

Localization.isoCurrencyCodes

Type: string[]


A list of all the supported language ISO codes.

Localization.locale

Type: string


An IETF BCP 47 language tag, consisting of a two-character language code and optional script, region and variant codes.

Example

'en', 'en-US', 'zh-Hans', 'zh-Hans-CN', 'en-emodeng'

Localization.locales

Type: string[]


List of all the native languages provided by the user settings. These are returned in the order the user defines in their device settings.

Example

['en', 'en-US', 'zh-Hans', 'zh-Hans-CN', 'en-emodeng']

Localization.region

Type: null | string


The region code for your device that comes from the Region setting under Language & Region on iOS. This value is always available on iOS, but might return null on Android or web.

Example

'US', 'NZ', null

Localization.timezone

Type: string


The current time zone in display format. On Web time zone is calculated with Intl.DateTimeFormat().resolvedOptions().timeZone. For a better estimation you could use the moment-timezone package but it will add significant bloat to your website's bundle size.

Example

'America/Los_Angeles'

Methods

Localization.getLocalizationAsync()

Get the latest native values from the device. Locale can be changed on some Android devices without resetting the app.

On iOS, changing the locale will cause the device to reset meaning the constants will always be correct.

Example

// When the app returns from the background on Android...

const { locale } = await Localization.getLocalizationAsync();

Returns

  • Promise<Localization>

Types

Localization

NameTypeDescription
currencystring | null

Three-character ISO 4217 currency code. Returns null on web.

Example

'USD', 'EUR', 'CNY', null

decimalSeparatorstring

Decimal separator used for formatting numbers.

Example

',', '.'

digitGroupingSeparatorstring

Digit grouping separator used when formatting numbers larger than 1000.

Example

'.', '', ','

isMetricboolean

Boolean value that indicates whether the system uses the metric system. On Android and web, this is inferred from the current region.

isRTLboolean

Returns if the system's language is written from Right-to-Left. This can be used to build features like bidirectional icons.

Returns false in Server Side Rendering (SSR) environments.

isoCurrencyCodesstring[]

A list of all the supported language ISO codes.

localestring

An IETF BCP 47 language tag, consisting of a two-character language code and optional script, region and variant codes.

Example

'en', 'en-US', 'zh-Hans', 'zh-Hans-CN', 'en-emodeng'

localesstring[]

List of all the native languages provided by the user settings. These are returned in the order the user defines in their device settings.

Example

['en', 'en-US', 'zh-Hans', 'zh-Hans-CN', 'en-emodeng']

regionstring | null

The region code for your device that comes from the Region setting under Language & Region on iOS. This value is always available on iOS, but might return null on Android or web.

Example

'US', 'NZ', null

timezonestring

The current time zone in display format. On Web time zone is calculated with Intl.DateTimeFormat().resolvedOptions().timeZone. For a better estimation you could use the moment-timezone package but it will add significant bloat to your website's bundle size.

Example

'America/Los_Angeles'