← वापस यूरोप का पुराना कागज़ वाला नक्शा लकड़ी की मेज़ पर एक एस्प्रेसो कप के साथ, उदास संपादकीय रोशनी, 35mm फिल्म ग्रेन

Next.js i18n 2026 में: राउटिंग, hreflang, और SEO

Next.js और हेडलेस

2023 में मैंने बर्लिन स्थित एक क्लाइंट के लिए एक बहुभाषी ई-कॉमर्स साइट लॉन्च की थी। बारह भाषाएं, App Router, सब कुछ साफ-सुथरा लग रहा था। तीन महीने बाद उनके जर्मन प्रोडक्ट पेज यूके के SERPs में रैंक कर रहे थे और उनके अंग्रेजी पेज मुंबई के उपयोगकर्ताओं को serve हो रहे थे। hreflang tags तकनीकी रूप से मौजूद थे। वे सिर्फ इस तरह गलत थे कि मुझे एक शर्मनाक दोपहर इसे सुलझाने में लगी। उस अनुभव ने मुझे किसी भी documentation page से कहीं ज़्यादा Next.js i18n के बारे में सिखाया।

यह "यहाँ official docs को सारांशित किया गया है" वाली post नहीं है। यह वह है जो मैंने Seahawk Media में बहुभाषी साइटें बनाते हुए सीखा है, जो चीजें लोगों को बार-बार काटती हैं, और वह विशिष्ट निर्णय जो 2026 में वाकई rankings को प्रभावित करते हैं।

---

App Router ने सब कुछ बदल दिया (और सब कुछ अच्छे के लिए नहीं)

Pages Router के पास built-in i18n support था। आप next.config.js में एक block डालते थे और Next.js लगभग स्वचालित रूप से locale detection, sub-path routing, और Link component locale switching को संभालता था। यह परिपूर्ण नहीं था, लेकिन यह opinionated था, जिसका मतलब था कम footguns।

App Router ने native i18n routing को पूरी तरह हटा दिया है। next.config.js में कोई i18n key नहीं। कोई automatic locale detection नहीं। अब आप पूरे routing logic के लिए जिम्मेदार हैं, और यही वह जगह है जहाँ ज्यादातर teams चुपचाप गड़बड़ कर देती हैं।

2026 में सबसे मान्य तरीका आपकी app/ directory के root में [locale] dynamic segment का उपयोग करना है। कुछ इस तरह: app/[locale]/page.tsx। इसे next-intl या i18next के साथ react-i18next के माध्यम से जोड़ दें, एक middleware file जो Accept-Language headers को पढ़े और accordingly redirect करे, और आपके पास एक काम करने वाली foundation है।

Middleware को गलतफहमी क्यों होती है

Middleware file दो अलग-अलग काम कर रही है जिन्हें लोग एक मानते हैं। पहला, locale detection: Accept-Language header (या एक cookie, या एक URL prefix) को पढ़ना और यह तय करना कि कौन सा locale serve करना है। दूसरा, URL को redirect या rewrite करना ताकि user /produkte के बजाय /de/produkte पर पहुँचे, कुछ hidden locale state के साथ नहीं।

दोनों को page render होने से पहले होना चाहिए। यह obvious लगता है। लेकिन मैंने teams को locale detection को React context provider के अंदर चलाते हुए देखा है, जिसका मतलब है कि Googlebot को serve किया गया initial HTML के पास कोई locale signal ही नहीं है। Bot को एक page दिखता है, वह इसे root URL के तहत index करता है, और अचानक आपके पास एक canonical mess हो जाता है।

Locale resolution को middleware में रखें। हमेशा।

---

Sub-path vs Sub-domain: एक चुनें और प्रतिबद्ध रहें

यह अनंत बहस है। /en/about बनाम en.yoursite.com/about। अधिकांश projects के लिए मैं sub-path routing की सलाह देता हूँ, और यह कारण है: यह आपके domain authority को केंद्रित करता है। आपके .com की ओर pointing करने वाली हर link सभी locales को फायदा पहुँचाती है। Sub-domains के साथ आप Google की नजर में effectively अलग-अलग sites चला रहे हैं, जिसका मतलब है कि आपको प्रत्येक के लिए independently authority build करनी पड़ती है।

एक exception है। अगर आप एक ऐसे market में हैं जहाँ local TLD trust के लिए भारी मायने रखता है (.de Germany में, .fr France में), तो country-code TLD sub-paths और sub-domains दोनों को perceived local credibility के लिए मात देता है। यह एक SEO claim नहीं है, यह एक conversion claim है। मैंने A/B tests देखे हैं जहाँ .de बनाम yourbrand.com/de ने trust metrics को meaningfully आगे बढ़ाया, भले ही rankings identical थे।

लेकिन आप एक ccTLD सेटअप को एक single Next.js app के अंदर आसानी से run नहीं कर सकते। तो 99% projects के लिए: sub-paths, एक app, एक domain।

---

hreflang: वह Tag जो आपसे झूठ बोलता है

यह वह जगह है जहाँ मुझे सबसे ज्यादा नुकसान दिखता है। hreflang conceptually मुश्किल नहीं है। यह search engines को बताता है: "इस page के अन्य भाषाओं में समतुल्य हैं, ये रहे।" व्यवहार में, implementation के तीन specific failure modes हैं जो मुझे बार-बार मिलते हैं।

Failure Mode 1: Tags एक-दूसरे को Reference नहीं करते

आपके hreflang set के हर page को दूसरे सभी pages को reference करना चाहिए, अपने आप को भी। अगर /en/about के पास /de/about की ओर pointing करने वाला hreflang है लेकिन /de/about के पास /en/about की ओर pointing करने वाला hreflang नहीं है, तो Google पूरे set को ignore कर देता है। Penalise नहीं करता। Ignore करता है। जैसे कि tags exist ही नहीं करते।

Seahawk के पास पिछले साल एक fintech project था जहाँ 40% hreflang tags non-reciprocal थे क्योंकि दो developers ने independently उन्हें different components में implement किया था बिना coordinate किए। Fix को एक घंटा लगा। Rankings recovery को दो महीने लगे।

Failure Mode 2: x-default Tag गायब या गलत जगह पर है

x-default उन pages के लिए है जो किसी specific language या region को target नहीं करते। आमतौर पर आपका root / या एक language-selector page। कुछ teams अपने English page पर x-default रखते हैं, जो ठीक है अगर English genuinely आपका fallback है सभी unmatched locales के लिए। लेकिन अगर आप ऐसे users को एक different page serve करते हैं जिनकी language आप support नहीं करते, तो x-default को वहाँ point करना चाहिए।

मैंने x-default को completely omit होते हुए देखा है। Google कोई error throw नहीं करता। यह सिर्फ अपना निर्णय लेता है कि unmatched queries के लिए कौन सा version दिखाना है, और वह निर्णय अक्सर गलत होता है।

विफलता मोड 3: ट्रेलिंग स्लैश और कैनोनिकल कॉन्फ्लिक्ट

आपका hreflang टैग कहता है https://yoursite.com/de/ueber-uns। उसी पेज पर आपका canonical टैग कहता है https://yoursite.com/de/ueber-uns/ (ध्यान दें ट्रेलिंग स्लैश)। Google उन्हें अलग-अलग URLs मानता है। अब आपका canonical और hreflang अलग-अलग चीजों की ओर इशारा कर रहे हैं, और आपने एक सिग्नल कॉन्फ्लिक्ट बना दिया है जो रैंकिंग को चुपचाप दबाता है बिना Search Console में कोई दिखने वाली त्रुटि दिए।

next.config.js में trailingSlash सेट करें और हर जगह consistent रहें। जांचें। वाकई अपने URLs को curl करके और आउटपुट पढ़कर जांचें।

Google Search Central का hreflang पर documentation सच में पूरा पढ़ने लायक है। यह उन दुर्लभ official docs में से एक है जो काफी specific है कि उपयोगी हो सके।

---

Next.js में बड़े पैमाने पर hreflang जेनरेट करना

5-भाषा की साइट के लिए आप hreflang टैग हाथ से लिख सकते हैं। 12 locales में 3,000 product pages के लिए, आपको एक systematic approach चाहिए।

यहाँ मैं जो use करता हूँ:

  1. अपनी locale लिस्ट एक बार, एक single config file में define करें। कुछ इस तरह locales.config.ts export करते हुए एक array: ['en', 'de', 'fr', 'es', 'nl'...]
  2. एक utility function getHreflangAlternates(pathname: string) build करें जो एक locale-agnostic path (/about) लेता है और हर locale के लिए { hreflang, href } objects का एक array return करता है।
  3. इस फंक्शन को अपने root layout.tsx में कॉल करें और Next.js के metadata API का उपयोग करके alternates.languages फील्ड के जरिए परिणामों को इंजेक्ट करें। यह Next.js 13.3 में जोड़ा गया था और यह <head> में स्वचालित रूप से सही <link rel="alternate" hreflang="..."> टैग जेनरेट करता है।
  4. डायनामिक कंटेंट वाले पेजों के लिए (ब्लॉग पोस्ट, प्रोडक्ट पेज) जहाँ हर लोकेल का ट्रांसलेशन नहीं है, अपनी यूटिलिटी को supportedLocales एरे पास करें और केवल उन लोकेल्स के लिए टैग जेनरेट करें जहाँ कंटेंट वास्तव में मौजूद है। एक hreflang टैग जो 404 रिटर्न करने वाले पेज की ओर इशारा करता है, कोई hreflang टैग न होने से बदतर है।

metadata API में alternates.languages अप्रोच इसे हैंडल करने का सबसे क्लीन तरीका है जो मुझे मिला। कोई कस्टम <Head> जुगाड़ नहीं, टैग्स के लिए कोई थर्ड-पार्टी पैकेज नहीं।

---

लोकेल डिटेक्शन बिना परेशान किए

यहाँ एक UX ट्रैप है जिसके SEO प्रभाव भी हैं। ब्राउजर लोकेल के आधार पर आक्रामक ऑटोमेटिक रीडायरेक्शन दोनों के लिए ही खराब है।

अगर जर्मनी में कोई यूजर yoursite.com/en/article विज़िट करता है और आपका मिडलवेयर उन्हें बिना पूछे /de/artikel पर हार्ड-रीडायरेक्ट कर देता है, तो आपने उनके इरादे को तोड़ दिया है। आपने लिंक शेयरिंग को भी संभावित रूप से तोड़ दिया है: कोई अंग्रेजी URL शेयर करता है, फ्रांस में प्राप्तकर्ता को फ्रेंच पर भेज दिया जाता है, और जो कंटेंट उन्हें दिखाया जाना था वह फ्रेंच में अभी मौजूद नहीं हो सकता।

मेरा नियम: डिटेक्ट करें, सुझाव दें, जबरदस्ती न करें। पहली विज़िट पर Accept-Language हेडर का उपयोग करके एक समझदारी भरा डिफ़ॉल्ट सेट करें (कुकी में स्टोर किया गया), लेकिन यूजर्स को मैन्युअली ओवरराइड करने दें और हर बाद की विज़िट पर उस ओवरराइड को सम्मान दें। कुकी हेडर पर प्राथमिकता लेती है।

SEO के लिए विशेष रूप से: Googlebot साथ में सार्थक Accept-Language हेडर नहीं भेजता। यह आपके URLs को जैसे हैं वैसे ही क्रॉल करेगा। तो सुनिश्चित करें कि हर लोकेल URL सीधे एक्सेसिबल है बिना रीडायरेक्शन के, और आपका sitemap सभी लोकेल वेरिएंट को स्पष्ट रूप से शामिल करता है।

next-intl मिडलवेयर डॉक्यूमेंटेशन इस डिटेक्शन स्ट्रैटेजी को अच्छी तरह कवर करता है, और यह वह जगह है जहाँ मैं किसी को नई प्रोजेक्ट शुरू करते समय भेजता।

---

बहुभाषी साइटों के लिए साइटमैप

एक साथ हर लोकेल वेरिएंट को शामिल करने वाला sitemap.xml छोटी साइटों के लिए ठीक है। बड़ी साइटों के लिए (कई लोकेल्स में हजारों URL) मैं इसे विभाजित करता हूँ: /sitemap.xml पर एक sitemap इंडेक्स, फिर /sitemaps/en.xml, /sitemaps/de.xml आदि में प्रति लोकेल अलग sitemap फ़ाइलें।

हर URL एंट्री में <xhtml:link rel="alternate"> टैग होने चाहिए जो आपकी hreflang सेटअप को दर्शाते हों। यह पेज के अंदर के टैग के साथ अनावश्यक है लेकिन यह Googlebot को ऐसे पेजों को जोड़ने में मदद करता है जिन्हें इसने अभी क्रॉल नहीं किया है।

Next.js 14+ में आप app/sitemap.ts के माध्यम से sitemap को डायनामिकली जेनरेट कर सकते हैं। रिटर्न टाइप metadata API के समान शेप में alternates.languages को सपोर्ट करता है। इसे उसी getHreflangAlternates यूटिलिटी से कनेक्ट करें जो आपने पहले बनाई थी और आपको मुफ्त में कंसिस्टेंसी मिल जाती है।

एक ठोस संख्या: 8 लोकेल्स और 4,500 प्रोडक्ट्स वाली एक प्रोजेक्ट पर, sitemap को विभाजित करने से GSC क्रॉल स्टैट्स के आधार पर प्रति लोकेल औसत क्रॉल समय में लगभग 30% की कमी आई। बहुत बड़ी बात नहीं है, लेकिन मायने रखती है।

---

ट्रांसलेशन लाइब्रेरीज: मैं वास्तव में क्या यूज करता हूँ

तीन लाइब्रेरीज लायक हैं जानने के लिए। next-intl मेरा App Router प्रोजेक्ट्स के लिए डिफ़ॉल्ट है। इसमें server components के लिए फर्स्ट-क्लास सपोर्ट है, प्लूरलाइजेशन को सही तरीके से हैंडल करता है, और API क्लीन है। मैंने इसे मध्य-2023 के बाद से लगभग 40 प्रोजेक्ट्स पर यूज किया है।

react-i18next युद्ध-परीक्षित है और इसका एक बहुत बड़ा इकोसिस्टम है, लेकिन इसका मानसिक मॉडल क्लाइंट components के लिए बनाया गया था और i18next कोर के माध्यम से server component सपोर्ट जोड़ना next-intl के नेटिव अप्रोच की तुलना में bolted-on लगता है।

Lingui को देखना लायक है अगर आपके अनुवाद workflow में पेशेवर अनुवादक शामिल हैं, CMS नहीं। इसका extraction tooling बेहतर है। लेकिन ज्यादातर agency projects के लिए जहाँ content Contentful या Sanity से आता है, next-intl ज्यादा सरल है।

जिससे मैं बचता हूँ: अपना खुद का बनाना। मैंने 2020 में एक बार ऐसा किया था जहाँ client ने जोर दिया कि उनकी मौजूदा PHP translation files सीधे दुबारा इस्तेमाल की जाएँ। यह काम किया, मुश्किल से, और मैंने दो साल कुछ maintain करते हुए गँवा दिए जिसे next-intl अब एक single useTranslations() call में handle करता है।

---

FAQ

क्या Next.js App Router पुरानी `next.config.js` i18n block को support करता है?

नहीं। i18n configuration key Pages Router के लिए विशেष था। अगर आप App Router में migrate कर रहे हैं, तो आपको एक [locale] dynamic segment और middleware file के जरिए routing implement करनी होगी। पुरानी config block को App Router projects में चुपचाप ignore किया जाता है।

क्या मुझे URL path में `lang` इस्तेमाल करना चाहिए या subdomains पर निर्भर रहना चाहिए?

ज्यादातर projects के लिए, URL path में lang (sub-path routing जैसे /de/) सही call है। Subdomains आपके domain authority को तोड़ते हैं और अलग DNS configuration की ज़रूरत होती है। ccTLDs सिर्फ इस complexity के लायक हैं अगर local trust signals genuinely आपके specific markets में conversion rates को बढ़ा रहे हों।

Googlebot JavaScript-rendered locale content को कैसे handle करता है?

ख़राब, कभी-कभी। अगर आपका locale detection पूरी तरह client-side एक React context में चलता है और initial HTML में कोई locale marker नहीं है, तो Googlebot pre-hydration state को index कर सकता है। हमेशा locale को middleware में resolve करें और सुनिश्चित करें कि सही lang attribute server-rendered HTML में <html> element पर है। इसे browser devtools का इस्तेमाल करके नहीं, source को देखकर check करें (जो post-hydration state दिखाते हैं)।

किसी साइट के लिए सही `x-default` hreflang वैल्यू क्या है जिसके पास कोई लैंग्वेज सिलेक्टर पेज नहीं है?

इसे आपने प्राइमरी लोकेल के होमपेज की ओर इंगित करें, आमतौर पर /en/। यह Google को सिग्नल देता है कि अंग्रेजी उन यूजर्स के लिए आपका फॉलबैक है जिनकी लैंग्वेज आप सपोर्ट नहीं करते। ऐसा करना कोई पेनल्टी नहीं है, यह सिर्फ एक सॉफ्ट प्रेफरेंस सिग्नल है जिसे Google मान भी सकता है और नहीं भी।

क्या मैं बिना किसी पेड SEO टूल के अपने hreflang इंप्लीमेंटेशन को वेरिफाई कर सकता हूँ?

हाँ। Google Search Console का URL Inspection टूल किसी भी इंडेक्स किए गए URL के लिए पहचाने गए hreflang टैग दिखाएगा। यह रिसिप्रोसिटी को ऑटोमैटिक रूप से वेलिडेट नहीं करेगा, लेकिन आप कुछ रेप्रेजेंटेटिव पेज को मैन्युअली चेक कर सकते हैं। बल्क वेलिडेशन के लिए, Screaming Frog (500 URLs तक फ्री) अपने hreflang टैब में रिसिप्रोसिटी चेक को हैंडल करता है।

---

मल्टीलिंग्वुअल Next.js को सही तरीके से सेटअप करना वास्तव में उबाऊ काम है। यह कॉन्फ़िग फाइलें, URL कंसिस्टेंसी, और यह सुनिश्चित करना है कि दो डेवलपर्स ने एक ही चीज को दो अलग-अलग कॉम्पोनेंट में इंप्लीमेंट नहीं किया है। लेकिन जिन साइट्स पर मैंने इसे सही तरीके से करने में समय लगाया है, उनकी रैंकिंग पूरे रीजन में स्थिर रहती है, और जिन पर मैंने कोनों में कटौती की है, उन्होंने मुझे वे सीख सिखाई है जो मैंने यहाँ लिखी है।

बर्लिन क्लायंट, वैसे, आखिरकार अपने जर्मन पेज को जर्मनी में रैंक करवाने में कामयाब हुए। हमें एक पूरे रीक्रॉल साइकल और बहुत सारी कॉफी लगी।

← वापस