What's the best way to get device locale in react native (iOS)?

React Native

React Native Problem Overview


Something similar to [NSLocale currentLocale] in Objective-C.

React Native Solutions


Solution 1 - React Native

There's no need for an external library. You can find what you're looking for in React's Native Modules

import { NativeModules } from 'react-native'

// iOS:
const locale = NativeModules.SettingsManager.settings.AppleLocale ||
               NativeModules.SettingsManager.settings.AppleLanguages[0] // "fr_FR"

// Android:
const locale = NativeModules.I18nManager.localeIdentifier // "fr_FR"

To test this, I changed the language on my device to French. Here's a sample of what you'll find in the NativeModules.SettingsManager.settings object related to locale:

{
    ...
    AppleKeyboards: [
        "fr_FR@hw=US;sw=QWERTY",
        "en_US@sw=QWERTY;hw=Automatic",
        "es_419@sw=QWERTY-Spanish;hw=Automatic",
        "emoji@sw=Emoji"
    ]
    AppleLanguages: ["fr-US", "en-US", "es-US", "en"]
    AppleLanguagesDidMigrate: "9.2"
    AppleLocale: "fr_FR"
    NSLanguages: ["fr-US", "en-US", "es-US", "en"]
    ...
}

Solution 2 - React Native

import { Platform, NativeModules } from 'react-native'

const deviceLanguage =
      Platform.OS === 'ios'
        ? NativeModules.SettingsManager.settings.AppleLocale ||
          NativeModules.SettingsManager.settings.AppleLanguages[0] //iOS 13
        : NativeModules.I18nManager.localeIdentifier;

console.log(deviceLanguage); //en_US

Solution 3 - React Native

I am using the i18n package (react-native-i18n). And then it's just:

I18n = require('react-native-i18n')
locale = I18n.currentLocale()

Solution 4 - React Native

Nothing of the above worked for me, but this component.

console.log("Device Locale", DeviceInfo.getDeviceLocale()); // e.g en-US

Solution 5 - React Native

function getLocale() {
  if (React.Platform.OS === 'android') {
    return I18n.locale;
  } else {
    return NativeModules.SettingsManager.settings.AppleLocale.replace(/_/, '-');
  }
}

Solution 6 - React Native

iOS 13 workaround here:

locale = NativeModules.SettingsManager.settings.AppleLocale // "fr_FR"
console.log(" ==> Current settings: ", NativeModules.SettingsManager.settings)
if (locale === undefined) {
    // iOS 13 workaround, take first of AppleLanguages array 
    locale = NativeModules.SettingsManager.settings.AppleLanguages[0]
    if (locale == undefined) {
          return "en" // default language
    }
}

Solution 7 - React Native

You can install react-native-i18n and use this function:

import React, { NativeModules } from 'react-native'
...
function getLocale () {
  if (React.Platform.OS === 'android') {
    return NativeModules.RNI18n.getCurrentLocale(locale => locale.replace(/_/, '-'))
  } else {
    return NativeModules.RNI18n.locale.replace(/_/, '-')
  }
}

Works both under Android and iOS.

Solution 8 - React Native

This code is future proof

import {NativeModules} from 'react-native';

function getSystemLocale(): string {
  let locale: string;
  // iOS
  if (
    NativeModules.SettingsManager &&
    NativeModules.SettingsManager.settings &&
    NativeModules.SettingsManager.settings.AppleLanguages
  ) {
    locale = NativeModules.SettingsManager.settings.AppleLanguages[0];
    // Android
  } else if (NativeModules.I18nManager) {
    locale = NativeModules.I18nManager.localeIdentifier;
  }

  if (typeof locale === 'undefined') {
    console.log('Couldnt get locale');
    return 'en';
  }

  return locale;
}

export default {
  getSystemLocale,
};

Solution 9 - React Native

You may need to extend react native yourself to get this info. But, depending on your use case, this localization component (stefalda/ReactNativeLocalization) may work for you.

Solution 10 - React Native

I found this solution for Android and iOS (RN 0.35)

import React, {NativeModules} from 'react-native';

if (NativeModules.I18nManager) {
	const {localeIdentifier, isRTL} = NativeModules.I18nManager;
}

May be this will help to someone, but iOS not shows locale property. It shows only rtl support now.

Solution 11 - React Native

if you develop over Expo... you can use:

console.log(await NativeModules.ExponentUtil.getCurrentLocaleAsync());
console.log(await NativeModules.ExponentUtil.getCurrentDeviceCountryAsync());
console.log(await NativeModules.ExponentUtil.getCurrentTimeZoneAsync());

Solution 12 - React Native

NativeModules solution can be changed over time by Facebook developers.
Because of this reason I had prepared a component. (It works only on Android for now)

Sample usage:

import SystemSettings from 'react-native-system-settings'

SystemSettings.get(
	settings => console.log('settings: ', settings)
)

Also promise-then can be used:

SystemSettings.get().then(settings => console.log('settings: ', settings)).done()

Also ES7 async-await method can be used!

class App extends React.Component {
	componentWillMount() {
		this._loadInitialState()
	}
	
	_loadInitialState = async () => {
		try {
			let settings = await SystemSettings.get()
			// Now settings variable would be filled and can be used!
		} catch (error) {}
	};
}

A sample result:

{
	densityDpi: 320,
	fontScale: 1,
	hardKeyboardHidden: "no",
	keyboard: "qwerty",
	keyboardHidden: "no",
	localization: {
		country: "US",
		displayCountry: "United States",
		displayLanguage: "English",
		displayName: "English (United States)",
		is24HourFormat: false,
		language: "en",
		locale: "en_US",
		networkCountry: "US",
		simCountry: "US",
		timeZone: {
			ID: "Europe/Amsterdam",
			displayName: {
				long: "Amsterdam Standard Time",
				short: "GMT+01:00",
			},
			offset: 3600000
		}
	},
	orientation: "portrait",
	screenHeightDp: 615,
	screenLayout: "normal",
	screenWidthDp: 360,
	smallestScreenWidthDp: 360,
	uiModeType: "normal"
}

Solution 13 - React Native

Personally I prefer use react-native-i18n. then you can use like this inside the documentation..

import { getLanguages } from 'react-native-i18n'

getLanguages().then(languages => {
  console.log(languages) // ['en-US', 'en']
})

link: https://github.com/AlexanderZaytsev/react-native-i18n

Solution 14 - React Native

$ npm install --save react-native-localize

--- or ---

$ yarn add react-native-localize

import * as RNLocalize from "react-native-localize";

console.log(RNLocalize.getLocales());

let defaultLanguage = RNLocalize.getLocales()[0].languageCode;

console.log('defaultLanguage', defaultLanguage);

Solution 15 - React Native

I am using react-native-i18n

in order to access the device's language I used:

import { getLanguages } from 'react-native-i18n';

getLanguages().then(languages => {
  console.log(languages); // ['en-US', 'en']
});

It's all in the documentation.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfaaezView Question on Stackoverflow
Solution 1 - React Nativeevan_schmevanView Answer on Stackoverflow
Solution 2 - React NativeFiroz AhmedView Answer on Stackoverflow
Solution 3 - React Nativeeyal83View Answer on Stackoverflow
Solution 4 - React Nativebr4nniganView Answer on Stackoverflow
Solution 5 - React NativeRogerParisView Answer on Stackoverflow
Solution 6 - React NativeOleksii RadetskyiView Answer on Stackoverflow
Solution 7 - React NativeambView Answer on Stackoverflow
Solution 8 - React NativeCodlerView Answer on Stackoverflow
Solution 9 - React NativeChris GeirmanView Answer on Stackoverflow
Solution 10 - React NativeSerzN1View Answer on Stackoverflow
Solution 11 - React Nativecrazyx13thView Answer on Stackoverflow
Solution 12 - React NativeefkanView Answer on Stackoverflow
Solution 13 - React NativeHazim AliView Answer on Stackoverflow
Solution 14 - React NativeGeetanjali BasakareView Answer on Stackoverflow
Solution 15 - React NativeLuminita BalasView Answer on Stackoverflow