Django React with i18n
I do not claim this is best practice but it works for me. Separating the frontend and backend a bit.
Think about it, what part translation is related to ? UI/UX right ?
Therefore, why have it on the backend, why not just have it in your react project ?
Steps: install i18next for react:
npm install react-i18next@legacy i18next --save
Notice, you will not get a > v9 but this tutorial :https://react.i18next.com/legacy-v9/step-by-step-guide
is still valid,
step 1:create translation folder in your src folder like this:
-src -translations -ar transilationsAR.js -en transilationEN.js - i18n.js - App.js
The way I do it, is manually to insure amazing User experience.This code will turn any keywords From ENGLISH-ENGLISH to any language:data_pre.py
en_en= {"kw": "kw"}en_kw = []for kw in en_en: en_kw.append(kw)# translate the list of english kw to desired language via google translatear_kw = """ [en_to_desired_langauge] """ar_kw = ar_kw.replace("،", ",")ar_kw = eval(ar_kw)en_ar = dict()for i in range(0, len(ar_kw)): en_ar[en_kw[i]] = ar_kw[i]# en_ar key words are in en_ar variable.
transilationEN.js : Here we will have for example ENGLISH-ENGLISH keywords dictionary,there are some tools help you fetch all key words, phrases from your website.
export const TRANSLATIONS_EN = { 'Hello': 'Hello',}
transilationAR.js, here we have new dictionary out of data preprocessing.
export const TRANSLATIONS_AR = { 'Hello': 'مرحبا',}
run
npm install --save i18next-browser-languagedetector
i18n.js
import i18n from "i18next";import { initReactI18next } from "react-i18next";import LanguageDetector from "i18next-browser-languagedetector";import {TRANSLATIONS_AR } from "./ar/translationsAR";import { TRANSLATIONS_EN } from "./en/translationsEN";// the translations// (tip move them in a JSON file and import them)const resources = { en: { translation: TRANSLATIONS_EN }, ar: { translation: TRANSLATIONS_AR },};i18n .use(initReactI18next) .use(LanguageDetector) .init({ resources, lng:[ "en", 'ar'], keySeparator: false, interpolation: { escapeValue: false }, react: { useSuspense: false } });export default i18n;
App.js
import React, { Component } from "react";import { withTranslation } from 'react-i18next';import i18n from "./translations/i18n";class App extends Component { handleChangeLangToAR = () => { i18n.changeLanguage("ar") }; handleChangeLangToEN = () => { i18n.changeLanguage("en") }; render() { return ( <SomeComponent {...this.props} handleChangeLangToAR={() => this.handleChangeLangToAR()} handleChangeLangToEN={ () => this.handleChangeLangToEN()} /> ); }}export default (withTranslation()(App));
now in someComponent.js we have acess to t() via props, which can be use to translate any keywords, phrases on our website.
someComponent.js
import React from "react";class someComponent extends React.Component { render() { const { handleChangeLangToEN, handleChangeLangToAR, t} = this.props; return ( <h1>{t('Hello')}</h1>)}};export default someComponent();
handleChangeLangToEN: can be set to onClick on a button to switch site language to English.
handleChangeLangToAR : can be set to onClick a button to switch site language to Arabic.
Both sould be in layout component, so we do not have to pass them every where in our project.
for example:
<Button OnClick={ () => handleChangeLangToEN }> English </Button>
Or if we have another component we want to translate, simply we export the component with WithTranslation , then we have access to t():
anotherComponent.js
import React from "react";import { withTranslation } from 'react-i18next';class anotherComponent extends React.Component { render() { const {t} = this.props; return ( <h1>{t('Hello')}</h1>)}};export default (withTransilation()anotherComponent)
if you are connecting your props using redux store an still would like to use withTransilation(), do not get confused, you do it like this.
const mapStateToProps = state => { return { isAuthenticated: state.auth.token !== null };};const mapDispatchToProps = dispatch => { return { onTryAutoSignup: () => dispatch(actions.authCheckState()) };};export default connect( mapStateToProps, mapDispatchToProps,)(withTranslation()(App));'''