React Native uygulamalarında çoklu dil desteği nasıl yapılır?

Zafer Ayan
4 min readMay 2, 2020

Mobil uygulamalarda çoklu dil desteği, diğer dilleri konuşan kullanıcılara açılmak için önem arz ediyor. Bu yazımda da sizlere React Native uygulamalarında çoklu dil desteğini nasıl yapabileceğinizi anlatacağım.

Öncelikle projeminizi oluşturalım ve boş haliyle çalıştıralım:

npx react-native init SampleRNLocalization --template react-native-template-typescript
cd SampleRNLocalization
npx react-native run-ios

Projemize react-native-localize ve i18n-js kütüphanelerini ekleyelim, pod’ları yükleyelim, projeyi git’e ekleyelim ve vscode ile açalım:

yarn add react-native-localize i18n-js
yarn add -D @types/i18n-js
npx pod-install
git init
git add .
git commit -m "First commit"
code .

react-native-localize kütüphanesi, cihazın mevcut dili ile ilgili bilgilerin getirilmesini sağlar. i18n-js kütüphanesi ise belirlenen diller için uygun sözcüklerin arayüze aktarılması için gereklidir.

Şimdi merhaba kelimesinin diğer dillerde de görüntülenebilmesi için; İngilizce, Türkçe ve Arapça dillerine yönelik dil dosyalarını oluşturalım.

Dil dosyalarının oluşturulması

Şimdi uygulama içerisinde kullanacağımız metinler için uygun dil dosyalarını oluşturalım. Bunun için öncelikle proje dizininde src/lang adında bir dizin oluşturalım ve aşağıdaki dil dosyaları ekleyelim:

en.ts:

const en = {
hello: 'Hello',
};
export default en;

tr.ts:

const tr = {
hello: 'Merhaba',
};
export default tr;

ar.ts:

const ar = {
hello: 'مرحبا',
};
export default ar;

Sonrasında cihazdaki seçili dile göre uygun dosyanın kullanılabilmesi için src/lang dizini içerisinde _i18n.ts adında bir dosya oluşturalım:

import I18n from 'i18n-js';
import * as RNLocalize from 'react-native-localize';
import {I18nManager} from 'react-native';
import tr from './tr';
import en from './en';
import ar from './ar';
const locales = RNLocalize.getLocales();
I18n.locale = locales[0].languageTag;
export const isRtl = locales[0].isRTL;
I18nManager.forceRTL(isRtl);
I18n.fallbacks = true;
I18n.locales.no = 'en';
I18n.translations = {
en,
tr,
ar,
};
export default I18n;

Kodu açıklamak gerekirse:

  • RNLocalize.getLocales(): Cihazdaki tercih edilen dil listesini getirir.
  • languageTag: en, tr veya ar gibi dil kodunu getirir.
  • isRTL: İlgili dilin sağdan sola yazıldığını belirtir.
  • forceRTL: Arayüz bileşenlerinin soldan sağa yerine sağdan sola doğru dizilmesini zorunlu tutmak içindir. Örn: horizontal FlatList kullanımında liste elemanları soldan sağa yerine sağdan sola sıralanacaktır.
  • fallbacks=true: belirtilen dile ait kayıt bulunamadığında bir sonraki dilden telafi edilmesi gerektiğini belirtir.
  • locales.no: İstenen dil bulunamadığında, yerine telafi edilecek dil belirtilir.
  • translations: Uygulama içerisinde kullanılacak dillerin nesne olarak alınmasını sağlar.

Dil dosyalarının uygulamada kullanımı

I18n’in en basit haliyle kullanımı aşağıdaki gibidir:

I18n.t('hello')

Bu fonksiyonu App.tsx içerisinde aşağıdaki gibi kullanabiliriz:

import React from 'react';
import {SafeAreaView, StyleSheet, Text, StatusBar} from 'react-native';
import I18n from './src/lang/_i18n';
const App = () => {
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={styles.safeAreaView}>
<Text style={styles.text}>{I18n.t('hello')}</Text>
</SafeAreaView>
</>
);
};
const styles = StyleSheet.create({
safeAreaView: {
flex: 1,
padding: 18,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 24,
},
});
export default App;

Uygulamayı çalıştırdığınızda, cihazınızda tercih edilen dile göre aşağıdaki gibi görüntülenecektir:

Dilerseniz cihazınızın ayarlar bölümünden dili değiştirip uygulama içerisine yeniden geldiğinizde dilin değişmiş olduğunu görebilirsiniz:

Sistem dilinin değiştirilmesi

İsteğe bağlı olarak dil seçimi

Sistem dilinin kullanımı yerine isteğe bağlı olarak seçilen dilin parametre olarak verilmesi için aşağıdaki gibi locale özelliğinden yararlanılır:

I18n.t('hello', {locale: 'tr'})

RadioButton kullanarak istenilen dilin seçilmesi için src/components dizini oluşturarak içerisine repodaki RadioButton bileşenlerini ekleyebilirsiniz.

App.tsx’e uygulayalım:

import React, {useState} from 'react';
import {SafeAreaView, StyleSheet, Text, StatusBar, View} from 'react-native';
import I18n from './src/lang/_i18n';
import {Item} from './src/components/RadioButton';
import RadioGroup from './src/components/RadioGroup';
const App = () => {
const items: Item[] = [
{id: 'system', name: 'System'},
{id: 'en', name: 'English'},
{id: 'tr', name: 'Turkish'},
{id: 'ar', name: 'Arabic'},
];
console.log(items);
const [selected, setSelected] = useState<Item>(items[0]);
const onSelected = (item: Item) => {
setSelected(item);
};
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={styles.safeAreaView}>
<View style={styles.container}>
<Text style={styles.text}>
{I18n.t(
'hello',
selected.id === 'system' ? {} : {locale: selected.id},
)}
</Text>
</View>
<View style={styles.bottomBar}>
<RadioGroup
selected={selected}
onSelected={onSelected}
items={items}
/>
</View>
</SafeAreaView>
</>
);
};
const styles = StyleSheet.create({
safeAreaView: {
flex: 1,
justifyContent: 'space-between',
},
container: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
},
text: {
fontSize: 24,
},
bottomBar: {
alignItems: 'center',
justifyContent: 'flex-start',
},
});
export default App;

Kodu çalıştırdığınızda uygulamanın son hali aşağıdaki gibi görüntülenecektir:

Bonus: Karakterlerden dil tespiti

Uygulamanız birden fazla dili aynı anda destekleyebilir. Bu nedenle metindeki karakterlerin içeriğine bağlı olarak, arayüzün RTL (right-to-left) (sağdan-sola) sıralanması için dil tespiti yapmanız gerekebilir. Sağdan sola yazılan diller arasında bize en yakın olan Arapça dili yaygın olarak kullanıldığı için, Arapça dili tespitinde aşağıdaki regex’i içeren fonksiyondan yararlanabilirsiniz:

const isArabic = (text: string) => /[\u0590-\u06FF]/.test(text);

Bu fonksiyonu aşağıdaki gibi App.tsx’te kullanabilirsiniz:

I18nManager.forceRTL(isArabic(text));

Sonuç olarak

Uygulamalarımızı sadece Türkçe dili ile yayımlamak yerine İngilizce ve Arapça gibi diğer dillerde de yayımlamak, hitap edilen kullanıcı kitlesini arttırdığı için oldukça önemli. Arayüzde de buna bağlı değişikliklerin yapılması önem arz ediyor. Örneğin, marginLeft yerine marginStart, marginRight yerine marginEnd gibi ifadeler kullanarak, RTL diller için arayüzün sağdan sola doğru sıralanırken düzgün bir şekilde görüntülenmesini sağlayabilirsiniz.

Projenin bitmiş halini react-native-localize-sample reposunda bulabilirsiniz. Bu yazım hakkında soru ve görüşlerinizi aşağıdaki yorumlar kısmından yazabilirsiniz. Bana destek vermek için alkış simgesine tıklayabilirsiniz. Sonraki yazımda görüşmek üzere…

Kaynaklar:

--

--