If you want to grow your application and attract users from all around the world, offering multi-language support is crucial. By catering to a wider audience, you can expand your user base significantly. In this blog post, we will cover the topic of implementing multi-language support in React Native.
npx create-expo-app react-native-multi-language
Next, navigate to the project directory:
cd react-native-multi-language
i18n-js is a small library to provide the i18n translations on the JavaScript , also we can use in React Native projects too 🌍🗣️🌐
npm i i18n-js
We will also use React-Navigation for handling screens ✌️
npm install @react-navigation/native
npx expo install react-native-screens react-native-safe-area-context
npm install @react-navigation/native-stack
npx expo start
Great! Now that our project is up and running, let's move on to the implementation.
For this tutorial, we will focus on four languages that English 🇬🇧, German 🇩🇪, Italian 🇮🇹 and Turkish 🇹🇷
Create four language files under ./src/langs/
English
// ./src/langs/en.json
{
"home" : "Home" ,
"settings" : "Settings" ,
"select-language" : "Select Language" ,
"english" : "English" ,
"german" : "German" ,
"italian" : "Italian" ,
"turkish" : "Turkish" ,
"fruits" : "Fruits" ,
"grapes" : "Grapes" ,
"watermelon" : "Watermelon" ,
"pear" : "Pear" ,
"pineapple" : "Pineapple" ,
"strawberry" : "Strawberry" ,
"peach" : "Peach" ,
"kiwi" : "Kiwi" ,
"cherries" : "Cherries"
}
// ./src/langs/gr.json
{
"home" : "Startseite" ,
"settings" : "Einstellungen" ,
"select-language" : "Sprache auswählen" ,
"english" : "Englisch" ,
"german" : "Deutsch" ,
"italian" : "Italienisch" ,
"turkish" : "Türkisch" ,
"fruits" : "Obst" ,
"grapes" : "Trauben" ,
"watermelon" : "Wassermelone" ,
"pear" : "Birne" ,
"pineapple" : "Ananas" ,
"strawberry" : "Erdbeere" ,
"peach" : "Pfirsich" ,
"kiwi" : "Kiwi" ,
"cherries" : "Kirschen"
}
// ./src/langs/it.json
{
"home" : "Home" ,
"settings" : "Impostazioni" ,
"select-language" : "Seleziona Lingua" ,
"english" : "Inglese" ,
"german" : "Tedesco" ,
"italian" : "Italiano" ,
"turkish" : "Turco" ,
"fruits" : "Frutta" ,
"grapes" : "Uva" ,
"watermelon" : "Anguria" ,
"pear" : "Pera" ,
"pineapple" : "Ananas" ,
"strawberry" : "Fragola" ,
"peach" : "Pesca" ,
"kiwi" : "Kiwi" ,
"cherries" : "Ciliegie"
}
// ./src/langs/tr.json
{
"home" : "Ana Sayfa" ,
"settings" : "Ayarlar" ,
"select-language" : "Dil Seçin" ,
"english" : "İngilizce" ,
"german" : "Almanca" ,
"italian" : "İtalyanca" ,
"turkish" : "Türkçe" ,
"fruits" : "Meyveler" ,
"grapes" : "Üzüm" ,
"watermelon" : "Karpuz" ,
"pear" : "Armut" ,
"pineapple" : "Ananas" ,
"strawberry" : "Çilek" ,
"peach" : "Şeftali" ,
"kiwi" : "Kivi" ,
"cherries" : "Kiraz"
}
To manage languages and language switching, we will use an AppContext
// ./src/context/AppContext.js
import React from 'react' ;
export const AppContext = React. createContext ();
Implementing HomeScreen.jsx
// ./src/screens/HomeScreen.jsx
import React from 'react' ;
import { View, Text, TouchableOpacity } from 'react-native'
import { FontAwesome5 } from '@expo/vector-icons' ;
import { AppContext } from '../context/AppContext' ;
const HomeScreen = ({ route , navigation }) => {
const { t } = React. useContext (AppContext);
const fruits = [
{ id: 1 , icon: '🍇' , value: 'grapes' , background: 'rgba(107, 67, 139, 0.2)' },
{ id: 2 , icon: '🍉' , value: 'watermelon' , background: 'rgba(248, 49, 47, 0.2)' },
{ id: 3 , icon: '🍐' , value: 'pear' , background: 'rgba(195, 239, 60, 0.2)' },
{ id: 4 , icon: '🍍' , value: 'pineapple' , background: 'rgba(243, 173, 96, 0.2)' },
{ id: 5 , icon: '🍓' , value: 'strawberry' , background: 'rgba(248, 49, 47, 0.2)' },
{ id: 6 , icon: '🍑' , value: 'peach' , background: 'rgba(255, 130, 45, 0.2)' },
{ id: 7 , icon: '🥝' , value: 'kiwi' , background: 'rgba(69, 224, 118, 0.2)' },
{ id: 8 , icon: '🍒' , value: 'cherries' , background: 'rgba(246, 50, 47, 0.2)' }
]
const navigateToSettings = () => {
navigation. navigate ( 'Settings' )
}
return (
< View style = {{
flex: 1 ,
paddingHorizontal: 16 ,
paddingVertical: 32
}}>
< View style = {{
flexDirection: 'row' ,
alignItems: 'center' ,
justifyContent: 'space-between'
}}>
< Text style = {{
fontSize: 32 ,
fontWeight: '800'
}}>{ t ( 'home' )}</ Text >
< TouchableOpacity onPress = {() => navigateToSettings ()}>
< FontAwesome5 name = 'cog' size = { 24 } color = 'black' />
</ TouchableOpacity >
</ View >
< Text style = {{ fontSize: 16 , fontWeight: '600' }}>{ t ( 'fruits' )}</ Text >
{fruits. map ( item => < View
key = {item.id}
style = {{
backgroundColor: item.background,
flexDirection: 'row' ,
alignItems: 'center' ,
padding: 16 ,
borderWidth: 2 ,
marginTop: 8 ,
borderRadius: 10
}}>
< Text style = {{ fontSize: 20 }}>{item.icon}</ Text >
< Text style = {{ marginLeft: 8 , fontWeight: 500 }}>{ t (item.value)}</ Text >
</ View >)}
</ View >
)
};
export default HomeScreen;
Implementing SettingsScreen.jsx
// ./src/screens/SettingsScreen.jsx
import React from 'react' ;
import { View, Text, TouchableOpacity } from 'react-native'
import { FontAwesome5 } from '@expo/vector-icons' ;
import { AppContext } from '../context/AppContext' ;
const SettingsScreen = ({ }) => {
const { t , locale , setLocale } = React. useContext (AppContext);
const languages = [
{ id: 'en' , value: 'english' },
{ id: 'gr' , value: 'german' },
{ id: 'it' , value: 'italian' },
{ id: 'tr' , value: 'turkish' }]
return (
< View style = {{
flex: 1 ,
paddingHorizontal: 16 ,
paddingVertical: 32
}}>
< View style = {{
flexDirection: 'row' ,
alignItems: 'center' ,
justifyContent: 'space-between'
}}>
< Text style = {{
fontSize: 32 ,
fontWeight: '800'
}}>{ t ( 'settings' )}</ Text >
</ View >
< Text >{ t ( 'select-language' )}</ Text >
{languages. map ( item =>
< TouchableOpacity
key = {item.id}
style = {{
flexDirection: 'row' ,
alignItems: 'center' ,
padding: 16 ,
borderWidth: 0.8 ,
marginTop: 8 ,
borderRadius: 10
}}
onPress = {() => setLocale (item.id)}>
< FontAwesome5 name = {locale === item.id ? 'check-square' : 'square' } size = { 24 } color = 'black' />
< Text style = {{ marginLeft: 8 }}>{ t (item.value)}</ Text >
</ TouchableOpacity >)}
</ View >
)
};
export default SettingsScreen;
// ./App.js
import React, { useState, useMemo } from 'react' ;
import { StatusBar } from 'expo-status-bar' ;
import { SafeAreaProvider } from 'react-native-safe-area-context' ;
import { NavigationContainer } from '@react-navigation/native' ;
import { createNativeStackNavigator } from '@react-navigation/native-stack' ;
import HomeScreen from './src/screens/HomeScreen' ;
import SettingsScreen from './src/screens/SettingsScreen' ;
import { I18n } from 'i18n-js' ;
import en from './src/langs/en.json' ;
import gr from './src/langs/gr.json' ;
import it from './src/langs/it.json' ;
import tr from './src/langs/tr.json' ;
const i18n = new I18n ({ en, gr, it, tr });
const Stack = createNativeStackNavigator ();
import { AppContext } from './src/context/AppContext' ;
export default function App () {
const [ locale , setLocale ] = useState ( 'tr' );
const appContext = useMemo (() => {
return {
t : ( scope , options ) => {
return i18n. t (scope, { locale, ... options });
},
locale,
setLocale
}
}, [locale]);
return (
< SafeAreaProvider style = {{ flex: 1 }}>
< StatusBar />
< NavigationContainer >
< AppContext.Provider value = {appContext}>
< Stack.Navigator initialRouteName = 'Home' screenOptions = {{ headerShown: false }}>
< Stack.Screen name = 'Home' component = {HomeScreen} />
< Stack.Screen name = 'Settings' component = {SettingsScreen} />
</ Stack.Navigator >
</ AppContext.Provider >
</ NavigationContainer >
</ SafeAreaProvider >
);
}
We have imported all the languages and initialized the i18n
object. The t
function is responsible for handling translations. We have also shared the t
function through the AppContext
, making it accessible to all screens via the AppContext
. The setLocale
function is used to update the translation value, which can be set to en
, gr
, it
, or tr
in the code.
"dependencies" : {
"@react-navigation/native" : "^6.1.7",
"@react-navigation/native-stack" : "^6.9.13",
"expo" : "~48.0.18",
"expo-status-bar" : "~1.4.4",
"i18n-js" : "^4.2.3",
"react" : "18.2.0",
"react-native" : "0.71.8",
"react-native-safe-area-context" : "4.5.0",
"react-native-screens" : "~3.20.0"
},
Github Repository Link
By following the steps outlined in this blog post, you can seamlessly integrate multi-language support into your React Native applications, allowing users to interact with your app in their preferred language. Thank you for reading this guide on implementing multi-language support in React Native . We hope you found it informative and helpful for your development journey. Happy coding! 👨💻👩💻