Introduction
In a world where there are millions of application users, we need to understand that this goes beyond the code. By necessity we have to prepare our application to receive people from different countries and different languages and to do this we will use internationalization(i18n)
What is internationalization(i18n)?
The application of internationalization will help us to adapt our app to different languages, making it easy and avoiding many unnecessary changes or checks in our code.
The adapted elements will be texts and the lib we will use is: react-i18next
Implementation
- install lib
yarn add i18next react-i18next
- Create the files with the custom texts: create a folder with the languages and create the respective languages, we will use the following languages -> pt, en, es
- Create a json for each language with all the texts
{
"translation": {
"name": "Nome",
"welcome": "Seja Bem-Vindo",
"choose": "Selecione um idioma",
"portuguese": "Português",
"english": "Inglês",
"spanish": "Espanhol"
}
}
{
"translation": {
"name": "Nombre",
"welcome": "Bienvenido",
"choose": "Seleccione un idioma",
"portuguese": "Portugués",
"english": "Inglés",
"spanish": "Español"
}
}
{
"translation": {
"name": "Name",
"welcome": "Welcome",
"choose": "Select a language",
"portuguese": "Portuguese",
"english": "English",
"spanish": "Spanish"
}
}
- now that we have the json and the texts all assigned, we need to do the configuration:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
// importing languages
import PtBR from "./languages/pt.json"
import EN from "./languages/en.json"
import ES from "./languages/es.json"
// Here are the languages used and the contents of each one
const resources = {
pt: PtBR,
en: EN,
es: ES
};
// in this snippet is being initialized so we can use the lib
i18n
.use(initReactI18next)
.init({
compatibilityJSON: 'v3',
// language resources
resources,
// here is the language you will use by default
lng: 'pt',
});
export default i18n;
Defining a language through a select
- We will use the lib react-native-dropdown-picker to implement the dropdown, below is the implemented code
import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, View } from 'react-native';
import DropDownPicker from 'react-native-dropdown-picker';
import i18n from './internacionalization/i18n';
export default function App() {
// it is important to use the hook useTranslation(), it already updates the texts
// as soon as the user makes a change
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [value, setValue] = useState(null);
const [items, setItems] = useState([
{ label: t('portuguese'), value: 'pt' },
{ label: t('english'), value: 'en' },
{ label: t('spanish'), value: 'es' },
]);
return (
<View style={styles.container}>
<Text style={styles.greeting}>{t('welcome')}</Text>
<Text style={styles.name}>{`${t('name')} Luiz Gabriel`}</Text>
<View style={styles.dropDown}>
<DropDownPicker
open={open}
value={value}
items={items}
setOpen={setOpen}
setValue={setValue}
onChangeValue={(value) => {
// this function changes the language on the i18n
i18n.changeLanguage(value);
}}
setItems={setItems}
placeholder={t('choose')}
/>
</View>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
dropDown: {
marginTop: 20,
paddingHorizontal: 40,
},
greeting: {
fontSize: 30,
fontWeight: 'bold',
},
name: {
fontSize: 20,
},
});
Defining language by user location
- before getting the location you need to ask the user for permission
- We will use the lib expo-location
- install the library
npx expo install expo-location
- config your app.json
{
"expo": {
"plugins": [
[
"expo-location",
{
"locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location.",
"locationAlwaysPermission": "Allow $(PRODUCT_NAME) to use your location",
"locationWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location"
}
]
]
}
}
- solution below
import { StatusBar } from 'expo-status-bar';
import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, View } from 'react-native';
import i18n from './internacionalization/i18n';
import * as Location from 'expo-location';
export default function App() {
const { t } = useTranslation();
const setLanguageByLocation = async (latitude, longitude) => {
try {
// geocoding a location to a postal address
const geocode = await Location.reverseGeocodeAsync({ latitude, longitude });
// return country code
const country = geocode[0]?.isoCountryCode;
const countryToLanguage = {
BR: 'pt',
US: 'en',
ES: 'es',
};
const language = countryToLanguage[country] || 'pt';
// change the language
i18n.changeLanguage(language);
} catch (error) {
console.error("Erro ao definir idioma pela localização", error);
}
};
useEffect(() => {
(async () => {
// get permission to get location
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
console.log('Permissão para acessar a localização foi negada');
return;
}
// get current location
let location = await Location.getCurrentPositionAsync({});
setLanguageByLocation(location.coords.latitude, location.coords.longitude)
})();
}, []);
return (
<View style={styles.container}>
<Text style={styles.greeting}>{t('welcome')}</Text>
<Text style={styles.name}>{`${t('name')} Luiz Gabriel`}</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
greeting: {
fontSize: 30,
fontWeight: 'bold',
},
name: {
fontSize: 20,
},
});
Setting language by device language
- we will use the lib expo-localization, I chose this lib because it provides access to locale data on the native device and under the hood uses libs like react-i18next
- install lib
npx expo install expo-localization
- config json
{
"expo": {
"plugins": ["expo-localization"]
}
}
- solution above
import { StatusBar } from 'expo-status-bar';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, View } from 'react-native';
import * as Localization from "expo-localization";
import i18n from './internacionalization/i18n';
export default function App() {
const { t } = useTranslation();
useEffect(() => {
// get the current language of the device
const langCode = Localization.getLocales()[0].languageCode;
// if language is null, set language to default value
const language = langCode || 'pt';
// change language
i18n.changeLanguage(language);
}, []);
return (
<View style={styles.container}>
<Text style={styles.greeting}>{t('welcome')}</Text>
<Text style={styles.name}>{`${t('name')} Luiz Gabriel`}</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
greeting: {
fontSize: 30,
fontWeight: 'bold',
},
name: {
fontSize: 20,
},
});
- Explaining what i18n is
- Setting the language manually
- Setting the language by user location
- Set app language according to device language
Linkedin: Luiz Gabriel Rebelatto Bianchi
Github: Luizrebelatto
Top comments (0)