以前、下記の記事を記載しましたが、TypeScript化されていなかったので、TypeScript版を記事にします。
インストールなどは、前回の記事を参考にしてください。
実装
translations/i18n.ts
import {default as i18n} from 'i18next';
import {initReactI18next} from 'react-i18next';
import {getLocales} from 'react-native-localize';
import EN from 'locales/en.json';
import JA from 'locales/ja.json';
export const defaultNS = 'en';
export const resources = {
ja: {
translation: JA,
},
en: {
translation: EN,
},
} as const;
const locales = getLocales();
i18n.use(initReactI18next).init({
resources,
lng: locales[0] && locales[0].languageCode,
fallbackLng: defaultNS,
compatibilityJSON: 'v3',
interpolation: {
escapeValue: false,
},
});
export default i18n;
型定義ファイル
TypeScriptで使用する型定義を行う。
types/i18next.d.ts
import 'react-i18next';
import {resources, defaultNS} from 'locales/i18n';
declare module 'react-i18next' {
interface CustomTypeOptions {
defaultNS: typeof defaultNS;
resources: typeof resources;
}
}
実際に使ってみる
App.tsx
import {useTranslation} from 'react-i18next';
import './translations/i18n';
const App = () => {
const {t} = useTranslation();
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<Text style={styles.sectionTitle}>{t('TITLE')}</Text>
</ScrollView>
</SafeAreaView>
);
};
トランス コンポーネント
翻訳で、コンポーネントを挿入する。
ja.json
{
"TITLE": "<terms>利用規約</terms> と <policy>プライバシーポリシー</policy>",
"TERMS": "利用規約",
"POLICY": "プライバシーポリシー",
}
import {Trans, useTranslation} from 'react-i18next';
const onLinkPressed = () => {
Linking.openURL('https://google.com');
};
<Trans
i18nKey="app.text.consent"
components={{
terms: (
<Text style={styles.sectionTitle} onPress={onLinkPressed}>
{t('TERMS')}
</Text>
),
policy: (
<Text style={styles.sectionTitle} onPress={onLinkPressed}>
{t('POLICY')}
</Text>
),
}}
/>
React Nativeでの翻訳関連の記事が少ないので、参考になればと思います。