

Next.js, tamamen farklı sistemleri tanımlayan iki resmi i18n docs sayfası var, aralarında çapraz referans bulunmadan.
Biri Pages Router'ı kapsıyor. Diğeri ise App Router'ı kapsar. Hiçbiri, bu ikisinin nasıl ilişkilendirildiğini, hangi kütüphaneleri kullanacağını veya çok dilli SEO için hreflang'ı nasıl kullanacağını açıklamıyor.
Her iki yönlendiriciyi de köprüleyeceğiz. Yönlendirme stratejilerini, kütüphane seçimini, ara yazılım kurulumunu, Sunucu Bileşeni çevirilerini ve çok dilli SEO'yu ele alacağız.
Amacımız, bir Next.js uygulamasına dil desteği eklemeleri istenen ve bir yaklaşıma karar vermeden önce net bir tabloya ihtiyaç duyan geliştiriciler için faydalı bir kaynak yaratmaktır. Hadi başlayalım!
Uluslararasılaşmanın üç katmanı vardır:
Next.js sadece yönlendirme konusunda yardımcı olur.
Pages Router, v10.0.0'dan beri yerleşik i18n yönlendirmeye sahiptir. next.config.js'de üç alanlı bir yapılandırma bloğu, yerel algılama, URL ön eki ve yönlendirmeleri otomatik olarak yönetir.
App Router farklı. i18n docs sayfası, middleware kullanarak kendiniz oluşturduğunuz bir deseni belgeliyor, bir [Mekan] dinamik bölüm ve bir kütüphane.
Çeviri ve biçimlendirme için, hangi yönlendiriciyi kullanırsanız kullanın tamamen kendi başınızasınız. App Router dokümanında tüm uyumlu kütüphaneler listeleniyor, ancak hangi kütüphaneyi seçeceğimiz konusunda hiçbir rehberlik vermiyor. Hiçbir belge sayfası hreflang etiketlerini veya çok dilli site haritalarını kapsamıyor.
Pages Router yaklaşımı bir yapılandırma değişikliğidir. next.config.js'ye üç alanlı bir i18n bloğu ekleyin:
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
}Hepsi bu.
Next.js otomatik olarak yerel olarak Kabul Dili Başlık, saygı gösterir NEXT_LOCALE cookie geçersiz kılma ve aktif locale'i şu şekilde açığa çıkarır useRouter().locale. Herhangi bir ara yazılım veya dizin yeniden yapılandırmasına ihtiyacınız yok.
App Router'ın eşdeğer bir yapılandırması yok. Yönlendirmeyi kendiniz üç parçadan kurarsınız:
@formatjs/intl-localematcher ve müzakereci ayrıştırmak Kabul Dili başlıklar. Resmi belgeler gerçek tespit mantığını üç nokta olarak bırakır: function getLocale(request) { ... }. Bunu bir sonraki bölümde dolduracağız.[Mekan] dinamik segment tüm bölümünüzü sarar uygulama/ dizin. Her rota klasör yapısı aracılığıyla yerel olarak bilinç kazanır.generateStaticParams Her yerel varyantı derleme zamanında önceden render eder.Üç parçadan, generateStaticParams, Pages Router'ın derleme sırasında otomatik olarak işlediği şeyi değiştiren olanıdır.
export function generateStaticParams() {
return [{ locale: 'en' }, { locale: 'fr' }, { locale: 'de' }]
}🚨 Pages Router'ın dahili i18n işletim sistemi Çıktı: 'Ihracat'. Tamamen statik bir dışa aktarma gerekiyorsa, manuel klasör tabanlı yönlendirme gerekir. Bu sınırlama yalnızca yerleşik yapılandırmaya uygulanır. Her iki yönlendirici de manuel kurulumla statik ihracat desteği sağlıyor.
Bir kütüphane seçmeden önce bir yönlendirme stratejisi seçin. SEO, DNS kurulumu ve yazacağınız ara yazılım miktarını etkiler:
next-intl birinci sınıf bir seçenek olarak destekliyor.SEO'nun hayati olduğu halka açık siteler için alt yol yönlendirme doğru varsayılan seçimdir. Alan yönlendirmesi karmaşıklığa değer ancak güçlü jeo-hedefleme sinyalleri özel bir gereksinim ise.
URL yapısını manuel olarak yönetmek istemiyorsanız, Weglotters proxy, hreflang enjeksiyonu ve çevrili URL'ler dahil olmak üzere alt dizin ve alt alan yönlendirmesini otomatik olarak yönetir.
Daha önce de belirttiğimiz gibi, resmi belgeler kütüphaneleri listeliyor ama hiçbirini önermiyor. Ana seçeneklerin karşılaştırma şekli şöyle:
next-intl , uygulama yönlendiricisi için fiili standarttır. RSC desteği dahili olarak sağlanmış, yönlendirme entegre edilmiş ve TypeScript otomatik tamamlama ek yapılandırma olmadan çalışır.
Eğer Pages Router'daysanız veya zaten i18next'i başka bir yerde kullanıyorsanız react-i18next daha iyi uyum sağlar. App Router desteği çalışıyor ama daha fazla manuel kurulum gerektiriyor.
Lingui, mevcut .po dosya pipeline'larına sahip ekiplere uygundur. Çeviriler derleme zamanında çıkarılır, bu yüzden kullanılmayan mesajlar asla gönderilmez.
💡 Paraglide JS büyük oyuncular arasında pek yer almıyor, ancak daha küçük paket çıktısına sahip derleyici tabanlı bir alternatif olarak dikkat çekmekte fayda var. Ama ilgileniyorsanız, ekosisteminin diğerlerinden daha genç olduğunu kabul etmeniz gerekecek.
Tarih ve sayı biçimlendirmesi için next-intl, yerel Uluslararası API'leri useFormatter üzerinden sarar. Diğerleri ise FormatJS'ye devr verir veya doğrudan Intl.DateTimeFormat ve Intl.NumberFormat'ı aramanızı size bırakır.
💡 Bu kütüphaneler render ile ilgilenir. Birinin çevirileri üretmesi ve içerik değiştikçe senkronize tutması gerekiyor. Weglot tamamen farklı bir katmanda çalışır ve çeviri içeriğini kod tabanının dışındaki ters proxy üzerinden yönetir. Bunu bir kütüphane yerine geçmek olarak düşünmeyin.
16 Next.js middleware.ts adını proxy.ts olarak değiştirdi. Bunun sebebi "middleware"in yanıltıcı olması ve genel uygulama içi mantığı ima etmesi nedeniyleydi. Gerçekte, dosya ağ sınırında çalışır, istekleri uygulamaya ulaşmadan önce bir proxy gibi yakalayıp değiştirir.
İşte resmi dokümanturadaki üç noktayı dolduran tam bir yerel tespit ve yönlendirme uygulaması:
// 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)
}
Dosyalar yuva altında app/[locale]/, bir Sözlükler/ klasörü düzenlerinizin ve sayfalarınızın yanında. Kök düzeni Bölge param olarak ve onu html Etiket:
export default async function RootLayout({ children, params }) {
const { locale } = await params
return (
<html lang={locale}>
<body>{children}</body>
</html>
)
}
Çeviriler için, resmi belgeler kütüphaneye ihtiyaç duymayan ham bir sözlük desenini gösterir:
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]()
Bu işe yarıyor ama çoğulma veya ara verim desteği yok. next-intl Her ikisini de Via getTranslations() ve useTranslations() içinde Sunucu Bileşenleri ve İstemci Bileşenleri sırasıyla bu konuda.
Her halükarda, çeviri dosyaları sunucuda işlenir ve sadece ortaya çıkan HTML tarayıcıya ulaşır, bu yüzden mesaj dosyası boyutu istemci paket boyutunu etkilemez.
İstemci Bileşenleri için, mümkün olduğunda çevirilmiş dizileri bir Server Bileşeni ebeveyninden prop olarak aktarın. Kullanım NextIntlClientProvider kapsamlı mesaj alt kümesi yalnızca bir İstemci Bileşeni doğrudan çevirileri yönetmesi gerektiğinde kullanılır.
Bir dil değiştiricisi için, bir Sunucu Bileşeni yerel etiketleri oluştururken, bir İstemci Bileşeni useRouter() Ara:
// LocaleSwitcher.tsx (Server Component)
import LocaleSwitcherClient from './LocaleSwitcherClient'
export default function LocaleSwitcher({ locale }) {
return <LocaleSwitcherClient locale={locale} labels={{ en: 'English', fr: 'Français' }} />
}İstemci seçim değişikliklerini yarı dinler ve yeni yerel rotayı iter:
// 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>
)
}Eğer kullanıyorsan Weglot, bunların hiçbiri geçerli değildir. Weglot yerleşik bir dil değiştirici widget'ı içerir ve proxy yapılandırması veya ara yazılım gerektirmez.
Hiçbir yönlendirici çoklu dilli SEO'yu otomatik olarak yönetmiyor:
html dil Doğru ama belgeleri Hreflang uygulamasının "size kalmış" olduğunu söylüyor.Uygulama yönlendiricisi ile meta veri API Otomasyona en yakın olanı sağlar. Yerel URL'leri içinde tanımlayın üreteMetadata aracılığıyla alternates.languages nesne ve Next.js otomatik enjeksiyonlar link rel="alternate" hreflang="..." Etiketler:
export async function generateMetadata({ params: { locale } }) {
return {
alternates: {
languages: {
'en': 'https://example.com/en',
'fr': 'https://example.com/fr',
'de': 'https://example.com/de',
},
},
}
}Manuel kısmı, her sayfa için her yerel varyant için doğru URL'yi toplamaktır. Bu mantığı yazmak senin.
Hangi yönlendiriciyi kullanırsanız kullanın iki başka şey manuel uygulama gerektiriyor. Kanonik URL'ler, tekrarlanan içerik sinyallerini önlemek için yerel olarak ayarlanmalıdır. Senin sitemap.ts İhtiyaçlar xhtml:link Her sayfanın her yerel varyantı için girişler.
Üzerinde hreflang değerin kendisi, kullanım hreflang="en-US" belirli bir bölgeyi hedef aldığında, ve hreflang="en" Tüm İngilizce konuşanları hedef alırken. Bunları karıştırmak arama motorlarına çelişkili sinyaller gönderir.
next-intl Kısmi bir otomasyon ekliyor: Proxy'si otomatik olarak Hreflang enjekte ediyor Bağlantı Yanıt başlıkları yerel yol adı yönlendirmesi kullandığınızda. Diğer yönlendirme yapılandırmaları ise hâlâ manuel uygulama gerektirir.
Bu, siteniz büyüdükçe anlamlı bir sürekli bakım miktarıdır. Neyse ki, Weglot'nin ters proxy'si sunucudaki her şeyi otomatik olarak yönetir, böylece çevrilmiş sayfalar ek kod olmadan tamamen indekslenebilir.
Aslında, Weglot'nin ters proxy'si, önceki bölümde kapsanan her şeyi otomatik olarak yönetir: hreflang etiketleri, çevrilmiş URL'ler, kanonik etiketler ve site haritası oluşturma. Çevrilmiş sayfalar sunucu tarafında sunulur, bu yüzden arama motorları tarafından tamamen indekslenebilirler.
⚠️ Weglot's JavaScript snippet entegrasyon SEO faydası sağlamaz. İstemci tarafı çeviri taranabilir değil. SEO önemliyse, ters proxy kurulumu gereklidir.
İkincil bir fayda ise yapım süresi. Weglot çevirilmiş sayfaları kendi CDN'sinden hizmet veriyor, onları derleme sırasında üretmiyor. Bir dile 10 dil eklemek Weglot-powered site, ne kadar süreyle ilgili bir etkisi yok Sonraki yapım Alıyor.
Doğru seçim, neyi optimize ettiğinize bağlı.
Eğer App Router üzerinde inşa ediyor ve sıfırdan başlıyorsan, next-intl varsayılan seçimdir. Yönlendirme, çeviriler, TypeScript otomatik tamamlama ve RSC desteğini tek bir pakette kapsar.
Eğer Pages Router'daysanız veya zaten i18next birikiminizdeyse, react-i18next en az dirençli yoldur.
Çok dilli SEO ve sürekli çeviri yönetimi öncelikse, hiçbir kütüphane tüm sorunu çözmez. Hâlâ hreflang, site haritaları ve içerik değiştikçe çevirileri güncel tutmak için bir iş akışı uygulamanız gerekecek. Weglotters proxy bunların hepsini otomatik olarak yönetiyor.
Weglot ve bileşen düzeyindeki bir kütüphane birbirini dışlamaz. Weglot HTML ve proxy katmanında çalışır, böylece bileşenlerinizin kullandığı kütüphaneyle birlikte var olabilir.
Eğer bu yaklaşım durumunuza uyuyorsa, göz atın WeglotJavaScript entegrasyon sayfasını başlangıç noktası olarak kullanın ve 14 günlük ücretsiz denememizi deneyin!
Weglot'un gücünü anlamanın en iyi yolu, onu bizzat görmektir. Hiçbir taahhüt olmadan ücretsiz deneyin.
Web sitenizi henüz bağlamaya hazır değilseniz, kontrol panelinizde bir demo web sitesi mevcuttur.