Top
Considering that there will be users from multiple different countries, you might need to add the support for multiple languages.To help you with that, we have made the sidebar compatible with the multiple language functionality.
You can find the dropdown that changes the language in the header.
We have used the package react-i18next, you can install it by running the following command in the terminal.
npm i i18next react-i18next
After you finished installing react-i18next package in your project, follow the below given steps to add the multi-language support.
To enable translation for a new language, you need to create a JSON file following this path: 'src/app/i18n/locales'. Create a folder for the language, such as 'ae' for Arabic. Inside this folder, create a file named 'translation.json'. Now add corresponding translated word for the arabic words.
Refer the below folder structure
//translation.json
{
"General": "جنرال لواء",
"Dashboard": "لوحة القيادة",
"Default": "إفتراضي",
"Ecommerce": "التجارة الإلكترونية",
"OnlineCource":"دورة على شبكة الإنترنت",
"Crypto":"تشفير",
"Social":"اجتماعي",
"Chart": "مخطط"
}
Now add object having an exact keys used in below languageData.
data : stands for language locale.
language : stands for your language name.
logo : represents the national flag of the nation where this language originated.
path : src/Data/HeaderData/Language.tsx
export const LanguagesData = [
{
data: "en",
logo: "flag-icon flag-icon-us",
language: "English",
},
{
data: "es",
logo: "flag-icon flag-icon-is",
language: "Spanish",
},
{
data: "pt",
logo: "flag-icon flag-icon-uy",
language: "Portuegse",
},
{
data: "fr",
logo: "flag-icon flag-icon-nz",
language: "French",
},
{
data: "ae",
logo: "flag-icon flag-icon-ae",
language: "لعربية",
},
{
data: "du",
logo: "flag-icon flag-icon-de",
language: "Deutsch",
},
{
data: "cn",
logo: "flag-icon flag-icon-cn",
language: "简体中文",
},
];
If you have to change the default langauge or have to add new
langauge in your application,you will
need to follow some steps.
first of all open the setting.ts file. //
src/app/i18n/settings.ts
fallbackLng is your application's default language. if you have change the default language replace value of fallbackLng with your desire langauge locale. for example: replace "en" with "ae" if you need to switch the default language from English to Arabic.
languages is a term that describes the number of languages that your application supports. if you have to add more language, add the folder name which you have created in locales in languages variable.
export const fallbackLng = "en";
export const languages = [fallbackLng, "ar", "fr", "es"];
export const defaultNS = "translation";
export function getOptions(lng = fallbackLng, ns = defaultNS) {
return {
supportedLngs: languages,
fallbackLng,
lng,
fallbackNS: defaultNS,
defaultNS,
ns,
};
}
We have now wrapped the entire app component with an I18nProvider that has a prop language whose value will be your current language in order to access the languages throughout the entire app.
import type { Metadata } from "next";
import "../index.scss";
import { Metadata } from "next";
import LayoutProvider from "./Provider";
import NoSsr from "@/utils/NoSsr";
import { detectLanguage } from "./i18n/server";
import { I18nProvider } from "./i18n/i18n-context";
import CustomErrorBoundary from "@/CommonComponents/ErrorBoundry";
export const metadata: Metadata = {
title: "Viho - Premium Admin Template",
description: "Viho - Premium Admin Template",
};
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const lng = await detectLanguage();
return (
<I18nProvider language={lng}>
<html lang={lng}>
<head>
<link rel='icon' href='/assets/images/favicon.png' type='image/x-icon' />
<link rel='shortcut icon' href='/assets/images/favicon.png' type='image/x-icon' />
<title>Viho - Premium Admin Template</title>
<link rel='preconnect' href='https://fonts.gstatic.com' />
<link href='https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap' rel='stylesheet' />
<link href='https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap' rel='stylesheet' />
<link href='https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap' rel='stylesheet' />
<script type='text/javascript' src='https://maps.googleapis.com/maps/api/js?v=3.exp'></script>
</head>
<body className='light-only'>
<CustomErrorBoundary>
<NoSsr>
<LayoutProvider>{children}</LayoutProvider>
</NoSsr>
</CustomErrorBoundary>
</body>
</html>
</I18nProvider>
);
}
In the Language file we are passing the params as same as we have mention in the JSON file. To get more idea about this refer the below code.
import { languageData } from "@/Data/Layout/LanguageData";
import { LanguagesData, languageDataType } from "@/Data/HeaderData/Language";
import { useRouter } from "next/navigation";
import { Fragment, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
const LanguageClass = () => {
const [langdropdown, setLangdropdown] = useState(false);
const { i18n } = useTranslation();
const currentLanguage = i18n.resolvedLanguage;
const [selectedLang, setSelectedLang] = useState({});
const router = useRouter();
const [lang, setLang] = useState("EN");
const [flag, setFlag] = useState("us");
const changeLng = (lng: languageDataType) => {
setLang(lng.data);
setFlag(lng.logo);
i18n.changeLanguage(lng.data);
};
const LanguageSelection = (language: any) => {
if (language) {
setLangdropdown(!language);
} else {
setLangdropdown(!language);
}
};
useEffect(() => {
const defaultLanguage = LanguagesData.find((data) => data.data == currentLanguage);
setSelectedLang(defaultLanguage);
router.refresh();
}, []);
useEffect(() => {
if (lang === "ae") {
document.body.classList.add("rtl");
document.body.classList.remove("ltr");
document.body.classList.remove("box-layout");
document.documentElement.dir = "rtl";
} else {
document.body.classList.add("ltr");
document.body.classList.remove("rtl");
document.body.classList.remove("box-layout");
document.documentElement.dir = "ltr";
}
}, [lang])
return (
<Fragment>
<li className='onhover-dropdown'>
<div className={`translate_wrapper ${langdropdown ? "active" : ""}`}>
<div className='current_lang'>
<div className='lang d-flex' onClick={() => LanguageSelection(langdropdown)}>
<i className={`flag-icon flag-icon-${flag}`}></i>
<span className='lang-txt'>{lang}</span>
</div>
</div>
<div className={`more_lang onhover-show-div ${langdropdown ? "active" : ""}`}>
{LanguagesData.map((item, i) => (
<div key={i} className='lang' onClick={() => changeLng(item)}>
<div className='lang-txt' data-lng={item.data}>
<i className={item.logo} /> {item.language}
</div>
</div>
))}
</div>
</div>
</li>
</Fragment>
);
};
export default LanguageClass;
Now we need to wrap the content to get reflect of languages. Below are the given example.
import React, { Fragment, useState } from 'react';
import { useTranslation } from 'react-i18next';
const SidebarMenuItems = () => {
const { t } = useTranslation("translation");
return(
<ul>
<li>{t('Dashboard')}</li>
<li>{t('Ecommerce')}</li>
</ul>
)
}
export default SidebarMenuItems;
Tip: For more information on react-i18next you can visit the official documentation on react-i18next