new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Expo & React Native · all subjects

localization

36 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

expo-localization installation

Install the expo-localization library using 'npx expo install expo-localization'.

getLocales returns current locale from device settings

The getLocales method from expo-localization returns the current locale based on the system settings of the device. It returns the locale based on the order in which the user prefers them, and there will always be at least one locale in the list. Access the first locale's language code using getLocales()[0].languageCode.

Per-app language selection via system settings with supportedLocales

Both Android and iOS allow users to choose a preferred language for individual apps via system settings. To support this feature, declare supported locales using the expo-localization config plugin with the supportedLocales property. You can provide an array directly or use supportedLocales.ios and supportedLocales.android for platform-specific values.

expo-localization config plugin supportedLocales example

Example configuration in app.json: ```json { "expo": { "plugins": [ [ "expo-localization", { "supportedLocales": { "ios": ["en", "ja"], "android": ["en", "ja"] } } ] ] } } ```

i18n-js installation for translations

Install the i18n-js library using 'npx expo install i18n-js' to handle multi-language support in your app.

i18n-js basic configuration example

Basic setup: ```tsx import { getLocales } from 'expo-localization'; import { I18n } from 'i18n-js'; const i18n = new I18n({ en: { welcome: 'Hello' }, ja: { welcome: 'こんにちは' }, }); i18n.locale = getLocales()[0].languageCode ?? 'en'; console.log(i18n.t('welcome')); ```

i18n.enableFallback behavior

Setting i18n.enableFallback = true allows the app to fall back to another language when a value is missing in the current language. This enables defining names and other values once in the default language and reusing them across all locales.

Android language change behavior with AppState

On Android, when a user changes the device's language, the app will not reset. Use the AppState API to listen for changes to the app's state and call getLocales() each time the app's state changes to detect language updates.

iOS language change behavior

On iOS, when a user changes the device's language, the app will reset. This means you can set the language once without updating React components to account for language changes.

Complete localization example with i18n-js

Complete working example: ```tsx import { View, StyleSheet, Text } from 'react-native'; import { getLocales } from 'expo-localization'; import { I18n } from 'i18n-js'; const translations = { en: { welcome: 'Hello', name: 'Charlie' }, ja: { welcome: 'こんにちは' }, }; const i18n = new I18n(translations); i18n.locale = getLocales()[0].languageCode ?? 'en'; i18n.enableFallback = true; 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: {getLocales()[0].languageCode}</Text> </View> ); } const styles = StyleSheet.create({ container: { backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', flex: 1, }, text: { fontSize: 20, marginBottom: 16, }, }); ```

Alternative translation libraries: Lingui, fbtee, React i18next, Intlayer

Alternative libraries for translations include Lingui (mature library with React and RSC support), fbtee (powerful internationalization framework), React i18next (stable library based on i18next), and Intlayer (per-component i18n library with extractor and AI tools).

Translating app metadata in app config

To localize app metadata like display name and system dialogs, set ios.infoPlist.CFBundleAllowMixedLocalizations to true in the app config, then provide a locales object with language identifiers as keys and paths to JSON translation files as values.

App metadata localization example

Example in app.json: ```json { "expo": { "ios": { "infoPlist": { "CFBundleAllowMixedLocalizations": true } }, "locales": { "ja": "./languages/japanese.json" } } } ``` Example japanese.json: ```json { "ios": { "CFBundleDisplayName": "こんにちは", "NSContactsUsageDescription": "日本語のこれらの言葉", "NSUserTrackingUsageDescription": "より関連性の高い広告を表示するために、このアプリによるアクティビティの追跡を許可します。", "Localizable.strings": { "HELLO_NOTIFICATION_KEY": "こんにちは世界" } }, "android": { "app_name": "こんにちは", "HELLO_NOTIFICATION_KEY": "こんにちは世界" } } ```

Locale identifiers format for app metadata

Locale identifiers in the locales object should be made up of a 2-letter language code with an optional region code (for example, en-US or en-GB). For iOS use the language name or ISO language designator. For Android, refer to the locale naming guidelines and list of commonly used locales in Android documentation.

iOS Localizable.strings in SDK 55 and later

In SDK 55 and later, there is an iOS-only option to specify a Localizable.strings object in the locale file. Its entries are used to create native localization files and can be used in iOS localized notifications.

RTL support enabled by default in SDK 58 and later

RTL (right-to-left) support is enabled by default in SDK 58 and later. Layout direction follows React Native's I18nManager. The app renders in RTL when the device is set to an RTL language such as Arabic or Hebrew, and in LTR (left-to-right) otherwise. On iOS, the device language must also be one of your app's supported locales declared with the supportedLocales option.

Disabling RTL support with supportsRTL option

To opt out of RTL layout, set the supportsRTL option to false on the expo-localization config plugin: ```json { "expo": { "plugins": [ [ "expo-localization", { "supportsRTL": false } ] ] } } ```

Forcing RTL layout with forcesRTL option

To force RTL layout for testing or for applications localized only for RTL locales, set the forcesRTL option to true on the expo-localization config plugin: ```json { "expo": { "plugins": [ [ "expo-localization", { "forcesRTL": true } ] ] } } ```

Dynamically overriding RTL settings from application code

You can override default RTL detection dynamically from application code using I18nManager.allowRTL() and I18nManager.forceRTL(), then reload the app with Updates.reloadAsync(). This does not work in Expo Go, as Expo Go resets RTL preferences when opening the launcher or individual projects.

Dynamically overriding RTL settings example

Example: ```tsx import { Text, View, StyleSheet, I18nManager, Platform } from 'react-native'; import Constants from 'expo-constants'; import * as Updates from 'expo-updates'; export default function App() { const shouldBeRTL = true; if (shouldBeRTL !== I18nManager.isRTL && Platform.OS !== 'web') { I18nManager.allowRTL(shouldBeRTL); I18nManager.forceRTL(shouldBeRTL); Updates.reloadAsync(); } return ( <View style={styles.container}> <Text style={styles.paragraph}>{I18nManager.isRTL ? ' RTL' : ' LTR'}</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingTop: Constants.statusBarHeight, padding: 8, }, paragraph: { fontSize: 18, fontWeight: 'bold', textAlign: 'left', width: '50%', backgroundColor: 'pink', }, }); ```

RTL start and end properties behavior

On LTR locales, start and end are the same as left and right. On RTL locales, start and end are the same as right and left. Use start and end values in flex properties instead of left and right to automatically adapt to locale direction.

Web RTL support with react-native-web

For web RTL layout support with react-native-web, add a dir property to your root View component: `<View dir={getLocales()[0].textDirection || 'ltr'}>...</View>`. Note that textDirection is not available on Firefox and older browser versions.

Text alignment in RTL locales

React Native's textAlign property does not accept start or end values. Instead, left works as start (aligns left on LTR, right on RTL), and right works as end. The default unset value aligns to actual left on both LTR and RTL. Each Text tag should have textAlign: left or textAlign: right set explicitly for correct alignment. Define this style in a custom reusable Text component.

Custom Text component for mobile RTL support

Example custom Text component for mobile: ```tsx import { Text as RNText, TextProps as RNTextProps } from 'react-native'; const MobileText = (props: RNTextProps) => { return <RNText style={{ textAlign: 'left', ...props.style }} {...props} />; }; export default MobileText; ```

Custom Text component for web with lang property

Example custom Text component for web: ```tsx import { getLocales } from 'expo-localization'; const deviceLanguage = getLocales()[0].languageCode; const WebText = (props: RNTextProps) => { return <RNText lang={deviceLanguage} {...props} />; }; export default WebText; ```

Platform-specific Text component selection

Pick between mobile and web Text components based on the current platform: ```tsx const Text = Platform.OS === 'web' ? WebText : MobileText; export default Text; ```

Using I18nManager.isRTL to select assets based on text direction

If you need to use different icons for LTR/RTL or change styles based on layout direction, use I18nManager.isRTL to get the current layout direction. ```tsx import { I18nManager } from 'react-native'; const isRTL = I18nManager.isRTL; ```

getLocales and getCalendars methods

expo-localization provides synchronous getLocales() and getCalendars() methods. getLocales() returns a list of locales based on user preference order (always at least one locale). getCalendars() returns a list of calendars based on user preference order (always at least one calendar).

getLocales properties

getLocales()[0] provides the following properties: languageTag, languageCode, textDirection, digitGroupingSeparator, decimalSeparator, measurementSystem, currencyCode, currencySymbol, regionCode.

getCalendars properties

getCalendars()[0] provides the following properties: calendar, timeZone, uses24hourClock, firstWeekday.

Locale settings example

Example accessing locale settings: ```ts import { getLocales, getCalendars } from 'expo-localization'; const { languageTag, languageCode, textDirection, digitGroupingSeparator, decimalSeparator, measurementSystem, currencyCode, currencySymbol, regionCode, } = getLocales()[0]; const { calendar, timeZone, uses24hourClock, firstWeekday } = getCalendars()[0]; ```

Temperature units limitation in expo-localization

There is yet to be a way to read temperature units from user preferences. On Android, you can use a lookup table based on locale. However, on iOS, the user can change it in device preferences but it cannot be read programmatically.

Some expo-localization properties may be null

Some properties from expo-localization can be null when they are unavailable on the current platform.

Intl API available with Hermes

If using Hermes in your app, you can use the Intl API on all platforms. It provides utilities to format lists, dates, numbers, monetary amounts, units, plural forms, and more.

Intl API with 'default' locale string

When passing 'default' as the locale string to the Intl API, it will use the device's locale automatically, so you don't need to rely on expo-localization to get the current locale. ```ts new Intl.NumberFormat('default', { style: 'currency', currency: 'EUR' }).format(5.0); ```

Intl API for formatting only, not getting locale info

Use Intl APIs to format strings and values once you know what the user expects to see. Intl APIs do not provide information about the device or current locale, so you cannot use them to get current locale units, currencies, or measurement systems. Use expo-localization for getting locale information.

Give your agent this brain