Top

Multi-Language Support

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.

How does multi-language functionality works?

We have used the package react-i18next, you can install it by running the following command in the terminal.

npm i i18next react-i18next

react-i18next package configuration and implementation in the project:

After you finished installing react-i18next package in your project, follow the below given steps to add the multi-language support.

  1. 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 'common.json'. Now add corresponding translated word for the arabic words.

    Refer the below folder structure

    • src
      • app
        • i18n
          • locales
            • ae
              • common.json
    //common.json 
      {
          "General": "جنرال لواء",
          "Dashboard": "لوحة القيادة",
          "Default": "إفتراضي",
          "Ecommerce": "التجارة الإلكترونية",
          "OnlineCource":"دورة على شبكة الإنترنت",
          "Crypto":"تشفير",
          "Social":"اجتماعي",
          "Chart": "مخطط"
      }
      

  2. Now add object having an exact keys used in below languageData.

    1. languageParameter : stands for language locale.

    2. languageName : stands for your language name.

    3. languageIconClassName : represents the national flag of the nation where this language originated.


    path : src/Data/Layout/Header/LanguageData.ts

                            
        export let languageData = [
        {
          languageParameter: "du",
          languageName: "Deutsch",
          languageIconClassName: "de",
        },
        {
          languageParameter: "es",
          languageName: "Español",
          languageIconClassName: "es",
        },
        {
          languageParameter: "ae",
          languageName: "لعربي",
          languageIconClassName: "ae",
          subTitle: "ae",
        },
      ];
                        
  3. 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

    1. 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.

    2. 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,
        };
      }
                        
  4. 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 NoSsr from "@/utils/NoSsr";
      import "../../src/index.scss";
      import MainProvider from "./MainProvider";
      import { detectLanguage } from "./i18n/server";
      import { I18nProvider } from "./i18n/i18n-context";
      
      export const metadata: Metadata = {
        title: "Create Next App",
        description: "Generated by create next app",
      };
      
      export default async function RootLayout({children,}: Readonly<{children: React.ReactNode;}>) {
        const lng = await detectLanguage();
        return (
          <I18nProvider language={lng}>
          <html lang={lng}>
            <head>
              <link href='https://fonts.googleapis.com/css2?family=Lexend:wght@100;200;300;400;500;600;700;800;900&family=Nunito+Sans:ital,opsz,wght@0,6..12,200;0,6..12,300;0,6..12,400;0,6..12,500;0,6..12,600;0,6..12,700;0,6..12,800;0,6..12,900;0,6..12,1000;1,6..12,200;1,6..12,300;1,6..12,400;1,6..12,500;1,6..12,600;1,6..12,700;1,6..12,800;1,6..12,900;1,6..12,1000&display=swap' rel='stylesheet' />
              <script type='text/javascript' src='https://maps.googleapis.com/maps/api/js?v=3.exp'></script>
              <link rel='stylesheet' type='text/css' href='../assets/css/font-awesome.css' />
            </head>
            <body>
              <NoSsr>
                <MainProvider>{children}</MainProvider>
              </NoSsr>
            </body>
          </html>
          </I18nProvider>
        );
      }
       

  5. 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 { LanguageDataType } from "@/Type/Layout/Header";
      import { useRouter } from "next/navigation";
      import { useEffect, useState } from "react";
      import { useTranslation } from "react-i18next";
      import Cookies from "js-cookie";
      import { useAppDispatch } from "@/Redux/Hooks";
      import { setLayoutType } from "@/Redux/Reducers/ThemeCustomizerSlice";
                        
      
      const Languages = () => {
        const router = useRouter();
        const { i18n } = useTranslation();
        const currentLanguage = i18n.resolvedLanguage;
        const [selectedLang, setSelectedLang] = useState({});
        const Language = Cookies.get("i18next");
        const [open, setOpen] = useState(false);
        const [lang, setLang] = useState("EN");
        const [flag, setFlag] = useState("us");
        const dispatch = useAppDispatch();
      
        const changeLanguage = (lng: LanguageDataType) => {
          setLang(lng.languageParameter);
          setFlag(lng.languageIconClassName);
          i18n.changeLanguage(lng.languageParameter);
          setOpen(false);
        };
      
        const LanguageSelection = (open: boolean) => {
          if (open) {
            setOpen(!open);
          } else {
            setOpen(!open);
          }
        };
      
        useEffect(() => {
          const defaultLanguage = languageData.find((data) => data.languageParameter == currentLanguage);
          setSelectedLang(defaultLanguage);
          router.refresh();
        }, []);
      
        useEffect(() => {
          if (Language === "ae") dispatch(setLayoutType("rtl"));
          else dispatch(setLayoutType("ltr"));
        }, [Language]);
      
        return (
          <li className="language-nav">
          <div className={`translate_wrapper ${open ? "active" : ""}`}>
          <div className="current_lang">
          <div className="lang" onClick={() => LanguageSelection(open)}>
          <span className="lang-txt">{Language} </span >
          </div>
          </div>
          <div className={`more_lang ${open ? "active" : ""}`}>
              {languageData.map((data, index) => (
                <div className="lang selected" key={index} onClick={() => changeLanguage(data)}>
                <i className={`flag-icon fi flag-icon-${data.languageIconClassName}`}> </i>
                <span className="lang-txt ms-1">
                    {data.languageName}
                    {data.subTitle &&  <span> ({data.subTitle})</span >}
                    </span>
                    </div>
              ))}
              </div>
              </div>
          </li>
        );
      };
      
      export default Languages;

  6. 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("common");
      
      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