Making Your React Native App Multilingual with Internationalisation (i18n)

Making Your React Native App Multilingual with Internationalisation (i18n)
Sep 21, 2024196 views

Building a React Native app that supports multiple languages is a great way to reach a wider audience. Whether you're expanding to different countries or creating a more inclusive experience for users worldwide, internationalisation (i18n) is key to growing your audience.

In this post, we'll walk through how to make your app multilingual, how to handle different formats (like dates, numbers, and currencies), and how to give your app a localised touch.

What is Internationalisation (i18n)?

Internationalisation (i18n) sets the foundation for your app to support multiple languages and region-specific settings. Once i18n is in place, you can easily translate content and customize features like date formats, currencies, and more to fit different locales.

Setting Up i18n in React Native

To make your app multilingual, you'll need a library that handles i18n. React-i18next is a popular choice that offers straightforward tools for managing translations and locales in React Native.

Install react-i18next i18next react-native-localize

First, we need to install the library and a language detector:

npm install react-i18next i18next react-native-localize
npm install -D @types/i18next
cd ios && pod install

Or, if you use yarn:

yarn add react-i18next i18next react-native-localize
yarn add -D @types/i18next
cd ios && pod install

Make sure your tsconfig.json allows JSON imports:

{
 "compilerOptions": {
  // other configs
  "resolveJsonModule": true,
  "esModuleInterop": true
 }
} 

Set Up i18next Configuration

Let's create a folder structure to organise our localised text files and initialisation file like this:

src/
│   App.tsx
│
├── i18n/
│   ├── index.ts
│   └── locales/
│       ├── en.json
│       ├── yo.json
│       ├── ha.json
│       └── ig.json
│
└── screens/
    └── HomeScreen.tsx

Create an index.ts file in the src/i18n directory. This will handle the initialization of the i18n library and the language detection logic.

import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
import {getLocales} from 'react-native-localize';

// Add more languages as needed
import en from './locales/en.json';
import yo from './locales/yo.json';
import ha from './locales/ha.json';
import ig from './locales/ig.json';

// Custom language mapping for Nigerian languages
const LANG_MAP: Record<string, string> = {
  'en': 'en',
  'en-NG': 'en', // English (Nigeria)
  'yo': 'yo', // Yoruba
  'yo-NG': 'yo',
  'ha': 'ha', // Hausa
  'ha-NG': 'ha',
  'ig': 'ig', // Igbo
  'ig-NG': 'ig'
};

// Language detection
const languageDetector = {
  type: 'languageDetector' as const, // Explicitly set type
  async: true,
  detect: (callback: (lang: string) => void) => {
    const locales = getLocales();
    const firstLocale = locales[0]?.languageTag ?? 'en';
    callback(LANG_MAP[firstLocale] || 'en');
  },
  init: () => {},
  cacheUserLanguage: () => {}
};

// Initialize i18n
i18n
  .use(languageDetector)
  .use(initReactI18next)
  .init({
    resources: {
      en: {translation: en},
      yo: {translation: yo},
      ha: {translation: ha},
      ig: {translation: ig},
    },
    fallbackLng: 'en', // Default to English if the locale isn't available
    interpolation: {
      escapeValue: false
    },
   compatibilityJSON: 'v3'
 });

export default i18n;

Handling Multiple Languages (Including Nigerian Languages)

To make your React Native app accessible to a wider audience, it's essential to support multiple languages. In Nigeria, this means catering to Yoruba, Hausa, and Igbo speakers, alongside English.

Using a custom LANG_MAP, we can map device locale codes to our supported languages:

This ensures users see the right translations even if their devices use region-specific codes. If a device's language isn't supported, the app defaults to English.

This approach not only enhances the user experience but also makes your app more inclusive and culturally relevant.

JSON Files for Translations

Now, let's create our translation files. For this example, we'll support English (en.json), Yoruba (yo.json), Hausa (ha.json), and Igbo (ig.json).

locales/en.json (English as the default language)

{
  "welcome": "Welcome",
  "greeting": "Hello"
}

locales/ig.json (Igbo)

{
  "welcome": "Ndewo",
  "greeting": "Nnọọ"
}

locales/ha.json (Hausa)

{
  "welcome": "Barka da zuwa",
  "greeting": "Sannu"
}

locales/yo.json (Yoruba)

{
  "welcome": "Kaabo",
  "greeting": "Bawo ni"
}

Use Translations in Your App

Now that we've set up i18n and created translation files, let's use them in our components.

First, import the useTranslation hook from react-i18next to access the translations.

import React from 'react';
import { Text, View, Button, StyleSheet } from 'react-native';
import {useTranslation} from 'react-i18next';

const HomeScreen = () => {
  const {t, i18n} = useTranslation();

  const changeLanguage = (lang) => {
    18n.changeLanguage(lang);
  };

 return (
   <View style={styles.container}>
     <Text style={styles.text}>{t('greeting')}</Text>
     <Text style={styles.text}>{t('welcome')}</Text>

     // Optional: Buttons for manual language change
     <Button title="Yoruba" onPress={() => changeLanguage('yo')} />
     <Button title="Hausa" onPress={() => changeLanguage('ha')} />
     <Button title="Igbo" onPress={() => changeLanguage('ig')} />
     <Button title="English" onPress={() => changeLanguage('en')} />
   </View>
 );
};

const styles = StyleSheet.create({
 container: {
   flex: 1,
   justifyContent: 'center',
   alignItems: 'center',  
 },
 text: {
   fontSize: 48,
 },
});

export default HomeScreen;

After setting up internalization, make sure to check your app on both iOS and Android to confirm that the text is displayed correctly in all languages.