अपने प्रश्न को पूछें और दस्तावेज़ का सारांश प्राप्त करें, इस पृष्ठ और आपके चुने हुए AI प्रदाता का उपयोग करके
इस पृष्ठ की सामग्री एक AI द्वारा अनुवादित की गई है।
अंग्रेजी में मूल सामग्री के अंतिम संस्करण देखेंIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Intlayer का उपयोग करके अपने Next.js 15 को next-i18next वेबसाइट के साथ अनुवादित करें | अंतरराष्ट्रीयकरण (i18n)
यह गाइड किसके लिए है
- जूनियर: सटीक चरणों का पालन करें और कोड ब्लॉकों को कॉपी करें। आपको एक कार्यशील बहुभाषी ऐप मिलेगा।
- मिड-लेवल: सामान्य गलतियों से बचने के लिए चेकलिस्ट और सर्वोत्तम प्रथाओं के कॉलआउट का उपयोग करें।
- सीनियर: उच्च-स्तरीय संरचना, SEO, और ऑटोमेशन सेक्शन को स्किम करें; आपको समझदारी से चुने गए डिफ़ॉल्ट और विस्तार बिंदु मिलेंगे।
आप क्या बनाएंगे
- स्थानीयकृत रूट्स के साथ App Router प्रोजेक्ट (जैसे,
/,/fr/...) - स्थानीय भाषाओं, डिफ़ॉल्ट भाषा, RTL सपोर्ट के साथ i18n कॉन्फ़िग
- सर्वर-साइड i18n इनिशियलाइज़ेशन और क्लाइंट प्रोवाइडर
- नामस्थानित अनुवाद ऑन-डिमांड लोड होते हैं
hreflang, स्थानीयकृतsitemap,robotsके साथ SEO- स्थानीय भाषा रूटिंग के लिए मिडलवेयर
- अनुवाद वर्कफ़्लोज़ को स्वचालित करने के लिए Intlayer इंटीग्रेशन (टेस्ट, AI भराई, JSON सिंक)
नोट: next-i18next, i18next के ऊपर बनाया गया है। यह गाइड App Router में next-i18next के साथ संगत i18next प्रिमिटिव्स का उपयोग करता है, जबकि आर्किटेक्चर को सरल और प्रोडक्शन-रेडी बनाए रखता है। एक व्यापक तुलना के लिए, देखें next-i18next vs next-intl vs Intlayer।
1) प्रोजेक्ट संरचना
next-i18next डिपेंडेंसीज़ इंस्टॉल करें:
कोड को क्लिपबोर्ड पर कॉपी करें
npm install next-i18next i18next react-i18next i18next-resources-to-backendस्पष्ट संरचना के साथ शुरू करें। संदेशों को locale और namespace द्वारा विभाजित रखें।
कोड को क्लिपबोर्ड पर कॉपी करें
.├── i18n.config.ts└── src ├── locales │ ├── en │ │ ├── common.json │ │ └── about.json │ └── fr │ ├── common.json │ └── about.json ├── app │ ├── i18n │ │ └── server.ts │ └── [locale] │ ├── layout.tsx │ └── about.tsx └── components ├── I18nProvider.tsx ├── ClientComponent.tsx └── ServerComponent.tsxचेकलिस्ट (मिड/सीनियर):
- प्रत्येक locale के लिए प्रत्येक namespace में एक JSON रखें
- संदेशों को अधिक केंद्रीकृत न करें; छोटे, पेज/फीचर-स्कोप्ड namespace का उपयोग करें
- सभी locales को एक साथ इम्पोर्ट करने से बचें; केवल आवश्यक चीज़ें लोड करें
2) डिपेंडेंसीज़ इंस्टॉल करें
कोड को क्लिपबोर्ड पर कॉपी करें
bashpnpm add i18next react-i18next i18next-resources-to-backendयदि आप next-i18next APIs या config interop का उपयोग करने की योजना बना रहे हैं, तो साथ ही:
कोड को क्लिपबोर्ड पर कॉपी करें
pnpm add next-i18next3) कोर i18n कॉन्फ़िगरेशन
locales, डिफ़ॉल्ट locale, RTL, और localized paths/URLs के लिए हेल्पर्स को परिभाषित करें।
कोड को क्लिपबोर्ड पर कॉपी करें
export const locales = ["en", "fr"] as const;export type Locale = (typeof locales)[number];export const defaultLocale: Locale = "en";export const rtlLocales = ["ar", "he", "fa", "ur"] as const;export const isRtl = (locale: string) => (rtlLocales as readonly string[]).includes(locale);export function localizedPath(locale: string, path: string) { return locale === defaultLocale ? path : "/" + locale + path;}const ORIGIN = "https://example.com";export function abs(locale: string, path: string) { return ORIGIN + localizedPath(locale, path);}सीनियर नोट: यदि आप next-i18next.config.js का उपयोग करते हैं, तो इसे i18n.config.ts के साथ संरेखित रखें ताकि विसंगति न हो।
4) सर्वर-साइड i18n प्रारंभिककरण
i18next को सर्वर पर एक डायनामिक बैकएंड के साथ प्रारंभ करें जो केवल आवश्यक locale/namespace JSON को इम्पोर्ट करता है।
कोड को क्लिपबोर्ड पर कॉपी करें
import { createInstance } from "i18next";import { initReactI18next } from "react-i18next/initReactI18next";import resourcesToBackend from "i18next-resources-to-backend";import { defaultLocale } from "@/i18n.config";// JSON संसाधनों को src/locales/<locale>/<namespace>.json से लोड करेंconst backend = resourcesToBackend( (locale: string, namespace: string) => import(`../../locales/${locale}/${namespace}.json`));export async function initI18next( locale: string, namespaces: string[] = ["common"]) { const i18n = createInstance(); await i18n .use(initReactI18next) .use(backend) .init({ lng: locale, fallbackLng: defaultLocale, ns: namespaces, defaultNS: "common", interpolation: { escapeValue: false }, react: { useSuspense: false }, }); return i18n;}मध्य नोट: पेलोड को सीमित करने के लिए प्रति पेज namespace सूची को छोटा रखें। वैश्विक "catch-all" बंडलों से बचें।
5) React कंपोनेंट्स के लिए क्लाइंट प्रदाता
क्लाइंट कंपोनेंट्स को एक प्रदाता के साथ लपेटें जो सर्वर कॉन्फ़िग के समान हो और केवल अनुरोधित namespaces को लोड करे।
कोड को क्लिपबोर्ड पर कॉपी करें
"use client";import * as React from "react";import { I18nextProvider } from "react-i18next";import { createInstance } from "i18next";import { initReactI18next } from "react-i18next/initReactI18next";import resourcesToBackend from "i18next-resources-to-backend";import { defaultLocale } from "@/i18n.config";const backend = resourcesToBackend( (locale: string, namespace: string) => import(`../../locales/${locale}/${namespace}.json`));type Props = { locale: string; namespaces?: string[]; resources?: Record<string, any>; // { ns: bundle } children: React.ReactNode;};export default function I18nProvider({ locale, namespaces = ["common"], resources, children,}: Props) { const [i18n] = React.useState(() => { const i = createInstance(); i.use(initReactI18next) .use(backend) .init({ lng: locale, fallbackLng: defaultLocale, ns: namespaces, resources: resources ? { [locale]: resources } : undefined, defaultNS: "common", interpolation: { escapeValue: false }, react: { useSuspense: false }, }); return i; }); return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>;}जूनियर टिप: आपको क्लाइंट को सभी संदेश भेजने की आवश्यकता नहीं है। केवल पृष्ठ के namespaces से शुरू करें।
6) स्थानीयकृत लेआउट और रूट्स
भाषा और दिशा सेट करें, और स्थैतिक रेंडरिंग को प्राथमिकता देने के लिए प्रति locale रूट्स को पूर्व-जनरेट करें।
कोड को क्लिपबोर्ड पर कॉपी करें
import type { ReactNode } from "react";import { locales, defaultLocale, isRtl, type Locale } from "@/i18n.config";export const dynamicParams = false;// स्थैतिक पैरामीटर उत्पन्न करेंexport function generateStaticParams() { return locales.map((locale) => ({ locale }));}export default function LocaleLayout({ children, params,}: { children: ReactNode; params: { locale: string };}) { // यदि params.locale locales में है तो उसे उपयोग करें, अन्यथा defaultLocale का उपयोग करें const locale: Locale = (locales as readonly string[]).includes(params.locale) ? params.locale : defaultLocale; // दिशा निर्धारित करें: यदि भाषा RTL है तो "rtl", अन्यथा "ltr" const dir = isRtl(locale) ? "rtl" : "ltr"; return ( <html lang={locale} dir={dir}> <body>{children}</body> </html> );}7) सर्वर + क्लाइंट उपयोग के साथ उदाहरण पृष्ठ
कोड को क्लिपबोर्ड पर कॉपी करें
import I18nProvider from "@/components/I18nProvider";import { initI18next } from "@/app/i18n/server";import type { Locale } from "@/i18n.config";import ClientComponent from "@/components/ClientComponent";import ServerComponent from "@/components/ServerComponent";// पेज के लिए स्थैतिक रेंडरिंग को मजबूर करेंexport const dynamic = "force-static";export default async function AboutPage({ params: { locale },}: { params: { locale: Locale };}) { const namespaces = ["common", "about"] as const; const i18n = await initI18next(locale, [...namespaces]); const tAbout = i18n.getFixedT(locale, "about"); return ( <I18nProvider locale={locale} namespaces={[...namespaces]}> <main> <h1>{tAbout("title")}</h1> <ClientComponent /> <ServerComponent t={tAbout} locale={locale} count={0} /> </main> </I18nProvider> );}अनुवाद (प्रत्येक namespace के लिए एक JSON src/locales/... के अंतर्गत):
कोड को क्लिपबोर्ड पर कॉपी करें
{ "title": "About", "description": "About page description", "counter": { "label": "Counter", "increment": "Increment" }}कोड को क्लिपबोर्ड पर कॉपी करें
{ "title": "À propos", "description": "Description de la page À propos", "counter": { "label": "Compteur", "increment": "Incrémenter" }}क्लाइंट कंपोनेंट (केवल आवश्यक namespace लोड करता है):
कोड को क्लिपबोर्ड पर कॉपी करें
"use client";import React, { useState } from "react";import { useTranslation } from "react-i18next";const ClientComponent = () => { const { t, i18n } = useTranslation("about"); const [count, setCount] = useState(0); const numberFormat = new Intl.NumberFormat(i18n.language); return ( <div> <p>{numberFormat.format(count)}</p> <button aria-label={t("counter.label")} onClick={() => setCount((c) => c + 1)} > {t("counter.increment")} </button> </div> );};export default ClientComponent;सुनिश्चित करें कि पेज/प्रदाता में केवल आवश्यक namespaces शामिल हों (जैसे,
about)। यदि आप React < 19 का उपयोग कर रहे हैं, तो भारी फॉर्मेटर्स जैसेIntl.NumberFormatको मेमोइज़ करें।
सिंक्रोनस सर्वर कंपोनेंट जो क्लाइंट सीमा के अंतर्गत एम्बेड किया गया है:
कोड को क्लिपबोर्ड पर कॉपी करें
type ServerComponentProps = { t: (key: string) => string; locale: string; count: number;};const ServerComponent = ({ t, locale, count }: ServerComponentProps) => { const formatted = new Intl.NumberFormat(locale).format(count); return ( <div> <p>{formatted}</p> <button aria-label={t("counter.label")}>{t("counter.increment")}</button> </div> );};export default ServerComponent;8) SEO: मेटाडेटा, Hreflang, साइटमैप, रोबोट्स
सामग्री का अनुवाद पहुंच बढ़ाने का एक तरीका है। बहुभाषी SEO को पूरी तरह से कनेक्ट करें।
सर्वोत्तम प्रथाएँ:
- रूट पर
langऔरdirसेट करें - प्रत्येक लोकल के लिए
alternates.languagesजोड़ें (+x-default) sitemap.xmlमें अनुवादित URLs सूचीबद्ध करें औरhreflangका उपयोग करें- स्थानीयकृत निजी क्षेत्रों (जैसे,
/fr/admin) कोrobots.txtमें बाहर करें
कोड को क्लिपबोर्ड पर कॉपी करें
import type { Metadata } from "next";import { locales, defaultLocale, localizedPath } from "@/i18n.config";export async function generateMetadata({ params,}: { params: { locale: string };}): Promise<Metadata> { const { locale } = params; // src/locales से सही JSON बंडल आयात करें const messages = (await import("@/locales/" + locale + "/about.json")) .default; const languages = Object.fromEntries( locales.map((locale) => [locale, localizedPath(locale, "/about")]) ); return { title: messages.title, description: messages.description, alternates: { canonical: localizedPath(locale, "/about"), languages: { ...languages, "x-default": "/about" }, }, };}export default async function AboutPage() { return <h1>About</h1>;}import type { MetadataRoute } from "next";import { locales, defaultLocale, abs } from "@/i18n.config";export default function sitemap(): MetadataRoute.Sitemap { const languages = Object.fromEntries( locales.map((locale) => [locale, abs(locale, "/about")]) ); return [ { url: abs(defaultLocale, "/about"), lastModified: new Date(), changeFrequency: "monthly", priority: 0.7, alternates: { languages }, }, ];}कोड को क्लिपबोर्ड पर कॉपी करें
import type { MetadataRoute } from "next";import { locales, defaultLocale, localizedPath } from "@/i18n.config";const ORIGIN = "https://example.com";const expandAllLocales = (path: string) => [ localizedPath(defaultLocale, path), ...locales .filter((locale) => locale !== defaultLocale) .map((locale) => localizedPath(locale, path)),];export default function robots(): MetadataRoute.Robots { const disallow = [ ...expandAllLocales("/dashboard"), ...expandAllLocales("/admin"), ]; return { rules: { userAgent: "*", allow: ["/"], disallow }, host: ORIGIN, sitemap: ORIGIN + "/sitemap.xml", };}9) लोकल रूटिंग के लिए मिडलवेयर
लोकल का पता लगाएं और यदि गायब हो तो लोकलाइज्ड रूट पर रीडायरेक्ट करें।
कोड को क्लिपबोर्ड पर कॉपी करें
import { NextResponse, type NextRequest } from "next/server";import { defaultLocale, locales } from "@/i18n.config";const PUBLIC_FILE = /\.[^/]+$/; // एक्सटेंशन वाले फाइलों को बाहर करेंexport function middleware(request: NextRequest) { const { pathname } = request.nextUrl; if ( pathname.startsWith("/_next") || pathname.startsWith("/api") || pathname.startsWith("/static") || PUBLIC_FILE.test(pathname) ) { return; } const hasLocale = locales.some( (locale) => pathname === "/" + locale || pathname.startsWith("/" + locale + "/") ); if (!hasLocale) { const locale = defaultLocale; const url = request.nextUrl.clone(); url.pathname = "/" + locale + (pathname === "/" ? "" : pathname); return NextResponse.redirect(url); }}export const config = { matcher: [ // इन पथों को छोड़कर सभी पथों से मेल खाता है जो इनसे शुरू होते हैं और जिन फाइलों में एक्सटेंशन होता है "/((?!api|_next|static|.*\\..*).*)", ],};10) प्रदर्शन और DX सर्वोत्तम प्रथाएँ
- html
langऔरdirसेट करें:src/app/[locale]/layout.tsxमें किया गया है। - संदेशों को namespace द्वारा विभाजित करें: बंडलों को छोटा रखें (
common.json,about.json, आदि)। - क्लाइंट payload को न्यूनतम करें: पेजों पर, केवल आवश्यक namespaces को provider को पास करें।
- स्थैतिक पेजों को प्राथमिकता दें: प्रत्येक locale के लिए
export const dynamic = 'force-static'औरgenerateStaticParamsका उपयोग करें। - सर्वर कंपोनेंट्स को सिंक करें: रेंडर समय पर async कॉल के बजाय पूर्व-गणना की गई स्ट्रिंग्स/फॉर्मेटिंग पास करें।
- भारी ऑपरेशंस को मेमोइज़ करें: विशेष रूप से पुराने React संस्करणों के लिए क्लाइंट कोड में।
- कैश और हेडर: जब संभव हो, डायनामिक रेंडरिंग की तुलना में स्थैतिक या
revalidateको प्राथमिकता दें।
11) परीक्षण और CI
tका उपयोग करने वाले कंपोनेंट्स के लिए यूनिट टेस्ट जोड़ें ताकि यह सुनिश्चित किया जा सके कि keys मौजूद हैं।- सत्यापित करें कि प्रत्येक namespace में सभी locales में समान keys हों।
- डिप्लॉय से पहले CI के दौरान गायब keys को प्रदर्शित करें।
Intlayer इन कार्यों का अधिकांश भाग स्वचालित करेगा (अगले अनुभाग को देखें)।
12) Intlayer को ऊपर जोड़ें (स्वचालन)
Intlayer आपकी JSON अनुवादों को सिंक में रखने, गायब keys के लिए परीक्षण करने, और आवश्यकतानुसार AI के साथ भरने में मदद करता है।
Intlayer dependencies इंस्टॉल करें:
कोड को क्लिपबोर्ड पर कॉपी करें
npm install intlayer @intlayer/sync-json-plugin --save-devnpx intlayer initकोड को क्लिपबोर्ड पर कॉपी करें
import { type IntlayerConfig, Locales } from "intlayer";import { locales, defaultLocale } from "@/i18n";import { syncJSON } from "@intlayer/sync-json";export const locales = [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH];const config: IntlayerConfig = { internationalization: { locales, defaultLocale, }, ai: { apiKey: process.env.OPENAI_API_KEY, // AI API कुंजी पर्यावरण चर से }, plugins: [ syncJSON({ source: ({ locale }) => `./locales/${locale}.json`, // JSON स्रोत फ़ाइल पथ }), ],};export default config;पैकेज स्क्रिप्ट जोड़ें:
कोड को क्लिपबोर्ड पर कॉपी करें
{ "scripts": { "i18n:fill": "intlayer fill", // AI अनुवाद भरने के लिए स्क्रिप्ट "i18n:test": "intlayer test" // अनुपस्थित keys के लिए परीक्षण स्क्रिप्ट }}सामान्य प्रवाह:
pnpm i18n:testCI में अनुपस्थित keys पर बिल्ड विफल करने के लिएpnpm i18n:fillस्थानीय रूप से नए जोड़े गए keys के लिए AI अनुवाद प्रस्तावित करने के लिए
आप CLI आर्गुमेंट्स प्रदान कर सकते हैं; देखें Intlayer CLI दस्तावेज़।
13) समस्या निवारण
- कुंजियाँ नहीं मिलीं: सुनिश्चित करें कि पृष्ठ/प्रदाता सही namespaces सूचीबद्ध करता है और JSON फ़ाइल
src/locales/<locale>/<namespace>.jsonके अंतर्गत मौजूद है। - गलत भाषा/अंग्रेज़ी का फ्लैश:
middleware.tsमें locale पहचान और प्रदाताlngको दोबारा जांचें। - RTL लेआउट समस्याएँ: सत्यापित करें कि
dirisRtl(locale)से प्राप्त होता है और आपकी CSS[dir="rtl"]का सम्मान करती है। - SEO वैकल्पिक भाषाएँ गायब: पुष्टि करें कि
alternates.languagesमें सभी locales औरx-defaultशामिल हैं। - बंडल बहुत बड़े हैं: namespaces को और विभाजित करें और क्लाइंट पर पूरे
localesट्री को इम्पोर्ट करने से बचें।
14) आगे क्या है
- जैसे-जैसे फीचर्स बढ़ें, और अधिक लोकल और नेमस्पेस जोड़ें
- त्रुटि पृष्ठों, ईमेल और API-चालित सामग्री का स्थानीयकरण करें
- अनुवाद अपडेट के लिए PRs को स्वचालित रूप से खोलने के लिए Intlayer वर्कफ़्लो का विस्तार करें
यदि आप एक स्टार्टर पसंद करते हैं, तो इस टेम्पलेट को आज़माएं: https://github.com/aymericzip/intlayer-next-i18next-template।