Internationalization (i18n)
How to use React with i18n - free starter
This article will teach you how to integrate i18n with your project. You can start using directional classes with the latest Bootstrap 5.
Lets see how to integrate internationalization (i18n) with MDB 5 across our layout, components, and utilities.
Prerequisites
Before starting the project make sure to install the following utilities:
Creating a new project
First, we need to create a new CRA project.
Step 1
Init the project. You can add a name for your project as we did in example below
npx create-react-app my-react-app
Step 2
Navigate to app's directory.
cd my-react-app
Step 3
Setup MDB.
npm i mdb-react-ui-kit
Font Awesome
Install Font Awesome.
npm i @fortawesome/fontawesome-free
Step 4
Add the following lines in your index.js file before the App.js file import:
import 'mdb-react-ui-kit/dist/css/mdb.min.css';
import "@fortawesome/fontawesome-free/css/all.min.css";
Step 5
Import Font Awesome and Roboto font. Add the following lines in public/index.html file inside
head
section:
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap" rel="stylesheet" />
Step 6
Launch the application.
npm start
Installation
Once we have managed to launch our project, we have to add i18next and react-i18next package.
Step 1
Navigate to your project and in your terminal run:
npm install react-i18next i18next --save
Step 2
Create locales
folder inside your src
and create new json files with translations
{
"language": "English",
"date": "Date",
"question": "Please select a language",
"search": "Search",
"news1": "Some news",
"news2": "Another news",
"profile": "My profile",
"profileSettings": "Settings",
"profileLogout": "Logout",
"accordion1": "Item - One",
"accordion2": "Item - Two",
"accordion3": "Item - Three",
"accordionTxt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae magna lacus. Fusce pretium urna id tellus ornare sagittis. Sed ac sagittis nibh, nec vehicula dolor. Cras et posuere mi",
"maskText": "Can you see me?",
"slide1Label": "First slide label",
"slide2Label": "Second slide label",
"slide3Label": "Third slide label",
"slide1Description": "English - Nulla vitae elit libero, a pharetra augue mollis interdum.",
"slide2Description": "English - Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"slide3Description": "English - Praesent commodo cursus magna, vel scelerisque nisl consectetur."
}
{
"language": "Polski",
"date": "Data",
"question": "Prosze wybrać język",
"search": "Wyszukaj",
"news1": "Wiadomości",
"news2": "Inne wiadomości",
"profile": "Mój profil",
"profileSettings": "Ustawienia",
"profileLogout": "Wyloguj",
"accordion1": "Przedmiot - Jeden",
"accordion2": "Przedmiot - Dwa",
"accordion3": "Przedmiot - Trzy",
"accordionTxt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae magna lacus. Fusce pretium urna id tellus ornare sagittis. Sed ac sagittis nibh, nec vehicula dolor. Cras et posuere mi",
"maskText": "Czy mnie widzisz?",
"slide1Label": "Etykieta pierwszego slajdu",
"slide2Label": "Etykieta drugiego slajdu",
"slide3Label": "Etykieta trzeciego slajdu",
"slide1Description": "Polski - Nulla vitae elit libero, a pharetra augue mollis interdum.",
"slide2Description": "Polski - Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"slide3Description": "Polski - Praesent commodo cursus magna, vel scelerisque nisl consectetur."
}
{
"language": "日本語",
"date": "日にち",
"question": "言語を選択してください",
"search": "サーチ",
"news1": "ニュース",
"news2": "別のニュース",
"profile": "プロフィール",
"profileSettings": "セッティング",
"profileLogout": "ログアウト",
"accordion1": "アイテム - 1",
"accordion2": "アイテム - 2",
"accordion3": "アイテム - 3",
"accordionTxt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae magna lacus. Fusce pretium urna id tellus ornare sagittis. Sed ac sagittis nibh, nec vehicula dolor. Cras et posuere mi",
"maskText": "私がみえますか?",
"slide1Label": "1 枚目のスライド ラベル",
"slide2Label": "2 番目のスライド ラベル",
"slide3Label": "3 番目のスライド ラベル",
"slide1Description": "日本語 - Nulla vitae elit libero, a pharetra augue mollis interdum.",
"slide2Description": "日本語 - Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"slide3Description": "日本語 - Praesent commodo cursus magna, vel scelerisque nisl consectetur."
}
{
"language": "Deutsch",
"date": "Datum",
"question": "Bitte wähle eine Sprache",
"search": "Suchen",
"news1": "Nachrichten",
"news2": "Andere Nachrichten",
"profile": "Mein Profil",
"profileSettings": "Einstellungen",
"profileLogout": "Ausloggen",
"accordion1": "Post - Ein",
"accordion2": "Post - Zwei",
"accordion3": "Post - Drei",
"accordionTxt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae magna lacus. Fusce pretium urna id tellus ornare sagittis. Sed ac sagittis nibh, nec vehicula dolor. Cras et posuere mi",
"maskText": "Können Sie mich sehen?",
"slide1Label": "Etikett des ersten Objektträgers",
"slide2Label": "Etikett des zweiten Objektträgers",
"slide3Label": "Etikett des dritten Objektträgers",
"slide1Description": "Deutsch - Nulla vitae elit libero, a pharetra augue mollis interdum.",
"slide2Description": "Deutsch - Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"slide3Description": "Deutsch - Praesent commodo cursus magna, vel scelerisque nisl consectetur."
}
Step 3
Prepare i18n.js
file:
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import en from "./locales/en.json";
import pl from "./locales/pl.json";
import ja from "./locales/ja.json";
import de from "./locales/de.json";
i18n
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
debug: true,
fallbackLng: "en",
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
resources: {
en: {
translation: en,
},
pl: {
translation: pl,
},
ja: {
translation: ja,
},
de: {
translation: de,
},
},
});
export default i18n;
Step 4
Let's import that file somewhere in our index.js file:
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import 'mdb-react-ui-kit/dist/css/mdb.min.css';
// import i18n (needs to be bundled ;))
import './i18n';
const root = createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Adding new content
After we go through all the previous steps, we can start developing our application. Let's change the content of App.js so that we can check if the app is working properly.
You can try some example we have prepared for you. Just copy the code below.
import "./App.css";
import { useTranslation } from "react-i18next";
import {
MDBContainer,
MDBNavbar,
MDBDropdownMenu,
MDBDropdownItem,
MDBInput,
MDBIcon,
MDBDropdown,
MDBDropdownToggle,
MDBBadge,
MDBCol,
MDBFooter,
MDBRow,
MDBCarouselItem,
MDBCarousel,
MDBAccordion,
MDBAccordionItem,
} from "mdb-react-ui-kit";
import { useState } from "react";
function App() {
const { t, i18n } = useTranslation();
const [pickedLanguage, setPickedLanguage] = useState("united-kingdom");
return (
<div className="App">
<MDBNavbar light expand="lg" bgColor="light">
<MDBContainer fluid>
<form className="d-none d-md-flex input-group w-auto my-auto">
<MDBInput label={t("search")} />
<span className="input-group-text border-0">
<MDBIcon icon="search" />
</span>
</form>
<div className="navbar-nav ms-auto d-flex flex-row">
<MDBDropdown>
<MDBDropdownToggle
style={{ cursor: "pointer" }}
tag="a"
className="nav-link"
>
<MDBIcon icon="bell" />
<MDBBadge notification color="danger" pill>
1
</MDBBadge>
</MDBDropdownToggle>
<MDBDropdownMenu>
<MDBDropdownItem link>Action</MDBDropdownItem>
<MDBDropdownItem link>Another action</MDBDropdownItem>
<MDBDropdownItem link>Something else here</MDBDropdownItem>
</MDBDropdownMenu>
</MDBDropdown>
<MDBDropdown>
<MDBDropdownToggle
style={{ cursor: "pointer" }}
tag="a"
className="nav-link"
>
<i className={`flag flag-${pickedLanguage} mx-auto`}></i>
</MDBDropdownToggle>
<MDBDropdownMenu>
<MDBDropdownItem
onClick={() => {
i18n.changeLanguage("en");
setPickedLanguage("united-kingdom");
}}
link
href="#"
>
<i className="flag-united-kingdom flag"></i>English
</MDBDropdownItem>
<MDBDropdownItem
onClick={() => {
i18n.changeLanguage("pl");
setPickedLanguage("poland");
}}
link
href="#"
>
<i className="flag flag-poland"></i>Polski
</MDBDropdownItem>
<MDBDropdownItem
onClick={() => {
i18n.changeLanguage("ja");
setPickedLanguage("japan");
}}
link
href="#"
>
<i className="flag flag-japan"></i>日本語
</MDBDropdownItem>
<MDBDropdownItem
onClick={() => {
i18n.changeLanguage("de");
setPickedLanguage("germany");
}}
link
href="#"
>
<i className="flag flag-germany"></i>Deutsch
</MDBDropdownItem>
</MDBDropdownMenu>
</MDBDropdown>
<MDBDropdown>
<MDBDropdownToggle
style={{ cursor: "pointer" }}
tag="a"
className="nav-link"
>
<img
src="https://mdbootstrap.com/img/new/avatars/2.jpg"
className="rounded-circle"
height="22"
alt=""
loading="lazy"
/>
</MDBDropdownToggle>
<MDBDropdownMenu>
<MDBDropdownItem link>{t("profile")}</MDBDropdownItem>
<MDBDropdownItem link>{t("profileSettings")}</MDBDropdownItem>
<MDBDropdownItem link>{t("profileLogout")}</MDBDropdownItem>
</MDBDropdownMenu>
</MDBDropdown>
</div>
</MDBContainer>
</MDBNavbar>
<MDBContainer>
<MDBRow>
<MDBCol lg="6" className="mx-auto my-5">
<MDBCarousel showIndicators showControls fade>
<MDBCarouselItem
className="w-100 d-block"
itemId={1}
src="https://mdbootstrap.com/img/Photos/Slides/img%20(15).jpg"
alt="..."
>
<h5>{t("slide1Label")}</h5>
<p>{t("slide1Description")}</p>
</MDBCarouselItem>
<MDBCarouselItem
className="w-100 d-block"
itemId={2}
src="https://mdbootstrap.com/img/Photos/Slides/img%20(22).jpg"
alt="..."
>
<h5>{t("slide2Label")}</h5>
<p>{t("slide2Description")}</p>
</MDBCarouselItem>
<MDBCarouselItem
className="w-100 d-block"
itemId={3}
src="https://mdbootstrap.com/img/Photos/Slides/img%20(23).jpg"
alt="..."
>
<h5>{t("slide3Label")}</h5>
<p>{t("slide3Description")}</p>
</MDBCarouselItem>
</MDBCarousel>
</MDBCol>
</MDBRow>
<MDBRow className="mb-5">
<MDBCol lg="6" className="mb-4 mb-lg-0">
<section className="mx-auto d-flex align-items-center">
<div className="bg-image">
<img
src="https://mdbootstrap.com/img/new/standard/city/053.webp"
className="w-100"
alt="Sample"
/>
<div
className="mask"
style={{ backgroundColor: "rgba(0, 0, 0, 0.6" }}
>
<div className="d-flex justify-content-center align-items-center h-100">
<p className="text-white mb-0">{t("maskText")}</p>
</div>
</div>
</div>
</section>
</MDBCol>
<MDBCol lg="6" className="mb-4 mb-lg-0">
<MDBAccordion initialActive={1}>
<MDBAccordionItem collapseId={1} headerTitle={t("accordion1")}>
{t("accordionTxt")}
</MDBAccordionItem>
<MDBAccordionItem collapseId={2} headerTitle={t("accordion2")}>
{t("accordionTxt")}
</MDBAccordionItem>
<MDBAccordionItem collapseId={3} headerTitle={t("accordion3")}>
{t("accordionTxt")}
</MDBAccordionItem>
</MDBAccordion>
</MDBCol>
</MDBRow>
</MDBContainer>
<MDBFooter>
<div
className="text-center p-3"
style={{ backgroundColor: "rgba(0, 0, 0, 0.2" }}
>
© 2022 Copyright:
<a className="text-dark" href="https://mdbootstrap.com/">
MDBootstrap.com
</a>
</div>
</MDBFooter>
</div>
);
}
export default App;
More about i18n
For more information, see react i18n github page. There you can read about other options, bundle optimizations etc.
Frontend features
MDB UI KIT:
To create the project we used our ui kit, with which we can build basic views very quickly.
Views and Layouts:
In this project we used App.js
file, created by cra
in which we placed our React
code. We have successfully integrated i18n into the MDB package and can use the appropriate translations based on provided json
files.