When i am integrating localization in nextjs getting many issues. so can create post for it. I have implement in client side.
First you need to create file for language which you want to include.
like
public/locales/
en.json , ar.json, de.json
en.json
{
"HEADING":"My First Page"
}
de.json
{
"HEADING":"Meine erste Seite"
}
like this you can add language keys.
package.json
{
"name": "translation-project",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"aos": "^2.3.4",
"bootstrap": "^5.3.3",
"i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.4",
"i18next-http-backend": "^3.0.2",
"next": "15.1.6",
"react": "^19.0.0",
"react-bootstrap": "^2.10.8",
"react-dom": "^19.0.0",
"react-i18next": "^15.4.1"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@types/node": "22.12.0",
"eslint": "^9",
"eslint-config-next": "15.1.6",
"sass": "^1.85.1",
"sass-loader": "^16.0.5",
"typescript": "5.7.3"
}
}
Base.tsx
import React, { useEffect, useState } from 'react'
import Footer from '../footer/page';
import { I18nextProvider, useTranslation } from "react-i18next";
import i18n from "../../../utils/i18n";
const Base = ({children}) => {
const { i18n: i18nInstance } = useTranslation();
const [loading, setLoading] = useState(true);
useEffect(() => {
if (i18nInstance.isInitialized) {
setLoading(false);
}
}, [i18nInstance.isInitialized]);
if (loading) {
return (
<div className="global-loading">
</div>
);
}
return (
<I18nextProvider i18n={i18n}>
{children}
<Footer />
</I18nextProvider>
)
}
export default Base;
i18n.ts
"use client";
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import HttpApi from "i18next-http-backend";
import LanguageDetector from "i18next-browser-languagedetector";
if (typeof window !== "undefined") {
i18n
.use(HttpApi) // Load translations dynamically
.use(LanguageDetector)
.use(initReactI18next)
.init({
supportedLngs: ["en", "ar"],
fallbackLng: "en",
debug: false, // Set false in production
detection: {
order: ["localStorage", "cookie", "navigator"],
caches: ["localStorage"]
},
backend: {
loadPath: "/locales/{{lng}}.json"
},
interpolation: {
escapeValue: false
}
});
}
export default i18n;
In this file i have show that how you can change language & use it.
Footer.tsx
"use client";
import React, { useEffect } from 'react';
import Link from 'next/link';
import './style.scss';
import { PolicyMenu, SocialMenu } from "../../../constant/const";
import { useTranslation } from 'react-i18next';
export default function Footer() {
const { t, i18n } = useTranslation();
const change = (lang) => {
if (i18n?.language == lang) return;
i18n?.changeLanguage(lang);
}
return (
<div className='footer-wrapper'>
<div className='container'>
<div className='row align-items-center justify-content-center gap-8'>
<div className='col-md-3'>
<p className='mb-0 text-white'>{t("SITE_BY")}</p>
</div>
<div className='col-md-6'>
<ul className='social-menu d-flex gap-8 justify-content-center flex-wrap'>
{SocialMenu.map((item, index) => (
<li key={index}><Link target="_blank" href={item.url}>{item.icon}</Link></li>
))}
</ul>
</div>
<div className='col-md-3'>
<ul className='footer-links d-flex flex-wrap'>
{PolicyMenu.map((value, index) => (
<li key={index}><Link className='text-white'
href={value.url}>{t(value.name)}</Link></li>
))
}
<div className='d-flex gap-2 text-white lang-active'>
<span className={ 'cursor-pointer ' +(i18n?.language=='en' && "active")}
onClick={() => change('en')}>EN</span>
<span className={ 'cursor-pointer ' +(i18n?.language=='ar' && "active")}
onClick={() => change('ar')}>AR</span>
</div>
</ul>
</div>
</div>
</div>
</div>
)
}
Top comments (0)