

Next.js के दो आधिकारिक i18n दस्तावेज़ पृष्ठ हैं जो पूरी तरह से अलग-अलग प्रणालियों का वर्णन करते हैं, और उनके बीच कोई क्रॉस-रेफरेंस नहीं है।
एक लेख पेज राउटर के बारे में बताता है । दूसरा ऐप राउटर के बारे में बताता है । दोनों में से कोई भी यह नहीं बताता कि ये दोनों कैसे संबंधित हैं, कौन सी लाइब्रेरी का उपयोग करना है, या बहुभाषी एसईओ के लिए hreflang को कैसे संभालना है।
हम दोनों राउटरों को ब्रिज करेंगे। हम राउटिंग रणनीतियों, लाइब्रेरी चयन, मिडलवेयर सेटअप, सर्वर कंपोनेंट अनुवाद और बहुभाषी एसईओ पर चर्चा करेंगे।
हमारा उद्देश्य उन डेवलपर्स के लिए एक उपयोगी संसाधन बनाना है जिन्हें Next.js ऐप में भाषा समर्थन जोड़ने के लिए कहा गया है और जो किसी भी दृष्टिकोण को अपनाने से पहले स्पष्ट जानकारी चाहते हैं। चलिए शुरू करते हैं!
अंतर्राष्ट्रीयकरण के तीन स्तर हैं:
Next.js केवल रूटिंग में मदद करता है।
Pages Router में v10.0.0 से ही अंतर्निहित i18n राउटिंग मौजूद है। next.config.js में तीन फ़ील्ड वाला कॉन्फ़िगरेशन ब्लॉक लोकेल डिटेक्शन, URL प्रीफ़िक्सिंग और रीडायरेक्ट को स्वचालित रूप से संभालता है।
ऐप राउटर अलग है। इसके i18n दस्तावेज़ पृष्ठ में एक पैटर्न का दस्तावेजीकरण किया गया है जिसे आप मिडलवेयर का उपयोग करके स्वयं असेंबल करते हैं। [स्थान] डायनामिक सेगमेंट और एक लाइब्रेरी।
अनुवाद और फ़ॉर्मेटिंग के लिए, चाहे आप कोई भी राउटर इस्तेमाल करें, आपको खुद ही सब कुछ करना होगा। ऐप राउटर के दस्तावेज़ों में सभी संगत लाइब्रेरीज़ की सूची दी गई है, लेकिन यह नहीं बताया गया है कि कौन सी लाइब्रेरी चुननी चाहिए। दस्तावेज़ों के किसी भी पृष्ठ में hreflang टैग या बहुभाषी साइटमैप के बारे में जानकारी नहीं दी गई है।
पेजेस राउटर दृष्टिकोण एक कॉन्फ़िगरेशन परिवर्तन है। next.config.js में तीन फ़ील्ड के साथ एक i18n ब्लॉक जोड़ें:
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
}इतना ही।
Next.js स्वचालित रूप से लोकेल का पता लगाता है स्वीकार करें-भाषा हेडर, सम्मान करता है अगला_स्थान कुकी ओवरराइड, और सक्रिय लोकेल को उजागर करता है useRouter().localeआपको किसी मिडलवेयर या डायरेक्टरी के पुनर्गठन की आवश्यकता नहीं है।
ऐप राउटर में इसके समकक्ष कोई कॉन्फ़िगरेशन नहीं है। आपको रूटिंग को तीन भागों से स्वयं बनाना होगा:
@formatjs/intl-localematcher और मध्यस्थ पार्स करने के लिए स्वीकार करें-भाषा शीर्षक। आधिकारिक दस्तावेज़ वास्तविक पहचान तर्क को एक एलिप्सिस के रूप में छोड़ देते हैं: फ़ंक्शन getLocale(अनुरोध) { ... }हम अगले भाग में इसे भरेंगे।[स्थान] डायनामिक सेगमेंट आपके पूरे को कवर करता है अनुप्रयोग/ निर्देशिका। फ़ोल्डर संरचना के माध्यम से प्रत्येक रूट स्थानीयता के प्रति जागरूक हो जाता है।जनरेटस्टैटिकपैरामीटर्स यह बिल्ड टाइम पर प्रत्येक लोकेल वेरिएंट को प्री-रेंडर करता है।इन तीनों घटकों में से, generateStaticParams वह घटक है जो उस कार्य को प्रतिस्थापित करता है जिसे Pages Router ने बिल्ड समय पर स्वचालित रूप से संभाला था।
export function generateStaticParams() {
return [{ locale: 'en' }, { locale: 'fr' }, { locale: 'de' }]
}🚨 पेजेस राउटर का बिल्ट-इन i18n इसके साथ काम नहीं करता है आउटपुट: 'निर्यात'यदि आपको पूरी तरह से स्टैटिक एक्सपोर्ट की आवश्यकता है, तो आपको मैन्युअल फ़ोल्डर-आधारित रूटिंग की आवश्यकता होगी। यह सीमा केवल बिल्ट-इन कॉन्फ़िगरेशन पर लागू होती है। दोनों राउटर मैन्युअल सेटअप के साथ स्टैटिक एक्सपोर्ट का समर्थन करते हैं।
लाइब्रेरी चुनने से पहले, रूटिंग रणनीति चुनें। यह एसईओ, डीएनएस सेटअप और आपके द्वारा लिखे जाने वाले मिडलवेयर की मात्रा को प्रभावित करता है:
अगला-अंतर्राष्ट्रीय इसे एक बेहतरीन विकल्प के रूप में समर्थन करता है।सार्वजनिक वेबसाइटों के लिए जहां एसईओ अत्यंत महत्वपूर्ण है, सब-पाथ रूटिंग सही डिफ़ॉल्ट विकल्प है। डोमेन रूटिंग की जटिलता तभी सार्थक है जब मजबूत भौगोलिक लक्ष्यीकरण संकेत एक विशिष्ट आवश्यकता हो।
यदि आप यूआरएल संरचना को मैन्युअल रूप से प्रबंधित नहीं करना चाहते हैं, तो Weglot का रिवर्स प्रॉक्सी स्वचालित रूप से सबडायरेक्टरी और सबडोमेन रूटिंग को संभालता है, जिसमें एचआरईएफएलएनजी इंजेक्शन और अनुवादित यूआरएल शामिल हैं।
जैसा कि हमने पहले बताया, आधिकारिक दस्तावेज़ों में लाइब्रेरीज़ की सूची तो दी गई है, लेकिन किसी की सिफ़ारिश नहीं की गई है। मुख्य विकल्पों की तुलना इस प्रकार है:
next-intl ऐप राउटर के लिए सर्वमान्य मानक है। इसमें RSC सपोर्ट अंतर्निहित है, राउटिंग एकीकृत है, और TypeScript ऑटो-कंप्लीशन बिना किसी अतिरिक्त कॉन्फ़िगरेशन के काम करता है।
यदि आप Pages Router का उपयोग कर रहे हैं या पहले से ही अपने स्टैक में कहीं और i18next का उपयोग कर रहे हैं, तो react-i18next बेहतर विकल्प है। App Router सपोर्ट काम करता है, लेकिन इसके लिए अधिक मैन्युअल सेटअप की आवश्यकता होती है।
Lingui उन टीमों के लिए उपयुक्त है जिनके पास पहले से ही .po फ़ाइल पाइपलाइन मौजूद हैं। बिल्ड के समय ही अनुवाद निकाले जाते हैं, इसलिए अप्रयुक्त संदेश कभी भी भेजे नहीं जाते।
💡 Paraglide JS वैसे तो प्रमुख कंपाइलरों में शुमार नहीं है, लेकिन छोटे बंडल आउटपुट के साथ एक कंपाइलर-आधारित विकल्प के रूप में इसका उल्लेख करना उचित है। हालांकि, अगर आपकी इसमें रुचि है, तो आपको इस तथ्य को स्वीकार करना होगा कि इसका इकोसिस्टम अन्य कंपाइलरों की तुलना में नया है।
दिनांक और संख्या फ़ॉर्मेटिंग के लिए, next-intl, useFormatter के माध्यम से नेटिव Intl API का उपयोग करता है। अन्य API FormatJS को यह कार्य सौंपते हैं या आपको Intl.DateTimeFormat और Intl.NumberFormat को सीधे कॉल करने की अनुमति देते हैं।
💡 ये लाइब्रेरी रेंडरिंग का काम संभालती हैं। अनुवाद तैयार करने और सामग्री में बदलाव होने पर उन्हें अपडेट रखने का काम अभी भी किसी को करना ही होगा। Weglot यह पूरी तरह से एक अलग स्तर पर काम करता है, कोडबेस के बाहर रिवर्स प्रॉक्सी के माध्यम से अनुवाद सामग्री का प्रबंधन करता है। इसे लाइब्रेरी के विकल्प के रूप में न समझें।
Next.js 16 में middleware.ts का नाम बदलकर proxy.ts कर दिया गया। ऐसा इसलिए किया गया क्योंकि "मिडिलवेयर" शब्द भ्रामक था और इससे सामान्य इन-ऐप लॉजिक का आभास होता था। वास्तव में, यह फ़ाइल नेटवर्क सीमा पर चलती है और एप्लिकेशन तक पहुंचने से पहले प्रॉक्सी की तरह अनुरोधों को रोककर उनमें बदलाव करती है।
यहां एक संपूर्ण लोकेल डिटेक्शन और रीडायरेक्ट कार्यान्वयन है जो आधिकारिक दस्तावेज़ों में उल्लिखित रिक्त स्थान को भरता है:
// proxy.ts
import { match } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
import { NextRequest, NextResponse } from 'next/server'
const locales = ['en', 'fr', 'de']
const defaultLocale = 'en'
function getLocale(request: NextRequest): string {
const cookie = request.cookies.get('NEXT_LOCALE')?.value
if (cookie && locales.includes(cookie)) return cookie
const headers = { 'accept-language': request.headers.get('accept-language') ?? '' }
const languages = new Negotiator({ headers }).languages()
return match(languages, locales, defaultLocale)
}
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
const hasLocale = locales.some(l => pathname.startsWith(`/${l}/`) || pathname === `/${l}`)
if (hasLocale) return
const locale = getLocale(request)
request.nextUrl.pathname = `/${locale}${pathname}`
return NextResponse.redirect(request.nextUrl)
}
फ़ाइलें एक दूसरे के नीचे समाहित होती हैं ऐप/[लोकेल]/, के साथ शब्दकोश/ यह फ़ोल्डर आपके लेआउट और पेजों के साथ स्थित होता है। रूट लेआउट को यह फ़ोल्डर मिलता है। स्थान इसे एक पैरामीटर के रूप में लेता है और इसे सेट करता है। एचटीएमएल टैग:
export default async function RootLayout({ children, params }) {
const { locale } = await params
return (
<html lang={locale}>
<body>{children}</body>
</html>
)
}
अनुवाद के लिए, आधिकारिक दस्तावेज़ एक रॉ डिक्शनरी पैटर्न दिखाते हैं जिसके लिए किसी लाइब्रेरी की आवश्यकता नहीं होती है:
const dictionaries = {
en: () => import('./dictionaries/en.json').then(m => m.default),
fr: () => import('./dictionaries/fr.json').then(m => m.default),
}
export const getDictionary = async (locale: string) => dictionaries[locale]()
यह काम करता है लेकिन इसमें बहुवचन या अंतर्विभाजन का समर्थन नहीं है। अगला-अंतर्राष्ट्रीय दोनों को कवर करता है अनुवाद प्राप्त करें() और useTranslations() में सर्वर घटक और क्लाइंट घटक क्रमश।
दोनों ही स्थितियों में, अनुवाद फ़ाइलों को सर्वर पर संसाधित किया जाता है और केवल परिणामी HTML ही ब्राउज़र तक पहुँचता है, इसलिए संदेश फ़ाइल का आकार क्लाइंट बंडल के आकार पर कोई प्रभाव नहीं डालता है।
क्लाइंट कंपोनेंट्स के लिए, जहां संभव हो, सर्वर कंपोनेंट पैरेंट से प्रॉप्स के रूप में अनुवादित स्ट्रिंग्स पास करें। नेक्स्टइंटलक्लाइंटप्रोवाइडर किसी क्लाइंट कंपोनेंट को सीधे अनुवाद संभालने की आवश्यकता होने पर ही, सीमित संदेश उपसमूह का उपयोग किया जाता है।
भाषा स्विचर के लिए, सर्वर कंपोनेंट लोकेल लेबल को रेंडर करता है जबकि क्लाइंट कंपोनेंट इसे हैंडल करता है। useRouter() पुकारना:
// LocaleSwitcher.tsx (Server Component)
import LocaleSwitcherClient from './LocaleSwitcherClient'
export default function LocaleSwitcher({ locale }) {
return <LocaleSwitcherClient locale={locale} labels={{ en: 'English', fr: 'Français' }} />
}क्लाइंट आधा चयन परिवर्तनों को सुनता है और नए लोकेल रूट को आगे बढ़ाता है:
// LocaleSwitcherClient.tsx
'use client'
import { useRouter } from 'next/navigation'
export default function LocaleSwitcherClient({ locale, labels }) {
const router = useRouter()
return (
<select value={locale} onChange={e => router.push(`/${e.target.value}`)}>
{Object.entries(labels).map(([value, label]) => (
<option key={value} value={value}>{label}</option>
))}
</select>
)
}यदि आप उपयोग कर रहे हैं Weglot इनमें से कोई भी बात लागू नहीं होती। Weglot इसमें एक अंतर्निर्मित भाषा स्विचर विजेट शामिल है और इसके लिए किसी प्रॉक्सी कॉन्फ़िगरेशन या मिडलवेयर की आवश्यकता नहीं है।
दोनों में से कोई भी राउटर बहुभाषी एसईओ को स्वचालित रूप से हैंडल नहीं करता है:
एचटीएमएल लैंग सही है, लेकिन इसके दस्तावेज़ों में लिखा है कि hreflang का कार्यान्वयन "आप पर निर्भर है।"ऐप राउटर के साथ, मेटाडेटा एपीआई आपको स्वचालन के सबसे करीब ले जाता है। इसमें स्थानीय यूआरएल परिभाषित करें। जनरेटमेटाडेटा के माध्यम से विकल्प.भाषाएँ ऑब्जेक्ट और Next.js ऑटो-इंजेक्ट लिंक rel="alternate" hreflang="..." टैग:
export async function generateMetadata({ params: { locale } }) {
return {
alternates: {
languages: {
'en': 'https://example.com/en',
'fr': 'https://example.com/fr',
'de': 'https://example.com/de',
},
},
}
}मैनुअल भाग में प्रत्येक पृष्ठ के लिए प्रत्येक स्थानीय संस्करण के लिए सही यूआरएल एकत्र करना शामिल है। वह लॉजिक आपको लिखना है।
दो अन्य चीजें हैं जिन्हें मैन्युअल रूप से लागू करना आवश्यक है, चाहे आप कोई भी राउटर इस्तेमाल करें। डुप्लिकेट कंटेंट सिग्नल से बचने के लिए कैनोनिकल यूआरएल को प्रत्येक लोकेल के अनुसार सेट करना होगा। sitemap.ts आवश्यकताओं xhtml:लिंक प्रत्येक पृष्ठ के प्रत्येक स्थानीय संस्करण के लिए प्रविष्टियाँ।
पर ह्रफलैंग स्वयं मूल्य, उपयोग hreflang="en-US" किसी विशिष्ट क्षेत्र को लक्षित करते समय, और hreflang="en" जब सभी अंग्रेज़ी बोलने वालों को लक्षित किया जाता है। इन दोनों को मिलाने से सर्च इंजनों को विरोधाभासी संकेत मिलते हैं।
अगला-अंतर्राष्ट्रीय इसमें एक आंशिक स्वचालन जोड़ा गया है: इसका प्रॉक्सी स्वचालित रूप से hreflang को इंजेक्ट करता है। जोड़ना स्थानीयकृत पाथनेम रूटिंग का उपयोग करते समय प्रतिक्रिया हेडर दिखाई देते हैं। अन्य रूटिंग कॉन्फ़िगरेशन के लिए अभी भी मैन्युअल कार्यान्वयन की आवश्यकता होती है।
आपकी साइट के विकास के साथ-साथ यह निरंतर रखरखाव की एक महत्वपूर्ण राशि है। सौभाग्य से, Weglot इसका रिवर्स प्रॉक्सी सर्वर पर सब कुछ स्वचालित रूप से संभालता है, इसलिए अनुवादित पृष्ठ बिना किसी अतिरिक्त कोड के पूरी तरह से अनुक्रमणीय होते हैं।
वास्तव में, Weglot इसका रिवर्स प्रॉक्सी पिछले अनुभाग में वर्णित सभी कार्यों को स्वचालित रूप से संभालता है: hreflang टैग , अनुवादित URL, कैननिकल टैग और साइटमैप जनरेशन। अनुवादित पृष्ठ सर्वर-साइड पर उपलब्ध कराए जाते हैं, इसलिए वे सर्च इंजनों द्वारा पूरी तरह से अनुक्रमित किए जा सकते हैं।
⚠️ Weglot जावास्क्रिप्ट snippet एकीकरण से एसईओ लाभ नहीं मिलते। क्लाइंट-साइड अनुवाद क्रॉल करने योग्य नहीं है। यदि एसईओ महत्वपूर्ण है, तो रिवर्स प्रॉक्सी सेटअप आवश्यक है ।
इसका एक अतिरिक्त लाभ निर्माण समय में कमी है। Weglot यह बिल्ड टाइम पर अनुवादित पेज जनरेट करने के बजाय अपने स्वयं के CDN से अनुवादित पेज प्रदान करता है। इसमें 10 भाषाएँ जोड़ने से Weglot -संचालित साइट का समय पर कोई प्रभाव नहीं पड़ता अगला निर्माण लेता है।
सही विकल्प इस बात पर निर्भर करता है कि आप किस चीज को बेहतर बनाना चाहते हैं।
यदि आप ऐप राउटर पर निर्माण कर रहे हैं और बिल्कुल नए सिरे से शुरुआत कर रहे हैं, अगला-अंतर्राष्ट्रीय यह डिफ़ॉल्ट विकल्प है। इसमें रूटिंग, अनुवाद, टाइपस्क्रिप्ट ऑटो-कंप्लीशन और आरएससी सपोर्ट एक ही पैकेज में शामिल हैं।
यदि आप पेजेस राउटर का उपयोग कर रहे हैं या आपके स्टैक में पहले से ही i18next मौजूद है, रिएक्ट-i18नेक्स्ट यह सबसे सरल मार्ग है।
यदि बहुभाषी एसईओ और निरंतर अनुवाद प्रबंधन आपकी प्राथमिकता है, तो इनमें से कोई भी लाइब्रेरी पूरी समस्या का समाधान नहीं करती है। आपको अभी भी hreflang, साइटमैप और सामग्री में बदलाव होने पर अनुवादों को अद्यतन रखने के लिए एक कार्यप्रणाली लागू करनी होगी। Weglot इसका रिवर्स प्रॉक्सी इन सभी चीजों को स्वचालित रूप से संभालता है।
Weglot और एक कंपोनेंट-लेवल लाइब्रेरी परस्पर विरोधी नहीं हैं। Weglot यह एचटीएमएल और प्रॉक्सी लेयर पर काम करता है, इसलिए यह आपके कंपोनेंट्स द्वारा उपयोग की जाने वाली किसी भी लाइब्रेरी के साथ सह-अस्तित्व में रह सकता है।
अगर यह तरीका आपकी स्थिति के लिए उपयुक्त है, तो शुरुआती बिंदु के रूप में Weglot के जावास्क्रिप्ट एकीकरण पृष्ठ को देखें और हमारे 14-दिवसीय निःशुल्क परीक्षण का लाभ उठाएं!
शक्ति को समझने का सबसे अच्छा तरीका Weglot इसे स्वयं अनुभव करके देखें। बिना किसी शुल्क और प्रतिबद्धता के इसका परीक्षण करें।
यदि आप अभी अपनी वेबसाइट को कनेक्ट करने के लिए तैयार नहीं हैं, तो आपके डैशबोर्ड में एक डेमो वेबसाइट उपलब्ध है।