

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, Weglot'nin ters proxy'si alt dizin ve alt etki alanı yönlendirmesini, hreflang ekleme ve çevrilmiş URL’ler dahil olmak üzere otomatik olarak yönetir. Çevirileri kod tabanınızın içinde tutmayı mı tercih edersiniz? O zaman @weglot/translate-react Bu paket, ziyaretçinin dilini bir çerezde saklar.
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:
| Özellik | next-intl | react-i18next | Lingui |
|---|---|---|---|
| RSC desteği | Yerli | Asenkron init aracılığıyla | Makrolar aracılığıyla |
| SEO/hreflang | Meta Veri aracılığıyla Kılavuz API | Meta Veri aracılığıyla Kılavuz API | Meta Veri aracılığıyla Kılavuz API |
| Rota | Entegre | next-i18n-router üzerinden | El Kitabı |
| TypeScript | Sıkı tipli | Eklentiler aracılığıyla | Ekstraksiyon yoluyla |
| Biçimlendirme | Uluslararası API'leri useFormatter üzerinden sarar | FormatJS'ye Delegeler | El Kitabı |
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 görüntüleme işlemlerini üstlenir. Yine de birinin çevirileri hazırlaması ve içerik değiştikçe bunları senkronize tutması gerekir. İşte bu, Weglot ’un ele aldığı alandır; markanıza özel olarak geliştirilmiş yapay zeka çevirileriyle. Bu hizmet, ters proxy aracılığıyla uygulamanızın önünde ya da @weglot/translate-react paket. Bunu bir kütüphane yerine geçecek bir şey 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 proxy(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)
}Next.js 15'te dosyaya şu adı verin: middleware.ts ve işlev ara yazılım.
Weglot kullanıyorsanız, bu adımı atlayabilirsiniz: ters proxy, yönlendirme işlemini sizin yerinize halleder. Eğer @weglot/translate-react paketini (beta sürümü) kullanırsa, dili bir çerezde saklar ve hazır bir LocaleSwitcher.
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>
)
}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 adresindeki ters proxy, önceki bölümde ele alınan her şeyi otomatik olarak halleder: hreflang etiketleri, çevrilmiş URL’ler, kanonik etiketler ve site haritası oluşturma. Çevrilmiş sayfalar sunucu tarafında sunulur; bu sayede arama motorlarında ve yapay zeka destekli keşif deneyimlerinde bulunmaya hazır hale gelirler.
⚠️ Weglot's JavaScript snippet entegrasyon SEO faydası sağlamaz. İstemci tarafı çeviri taranabilir değil. SEO önemliyse, ters proxy kurulumu gereklidir.
Ters proxy’nin bir diğer avantajı da derleme süresidir: Çevrilmiş sayfaları kendi CDN’sinden sunar; bu nedenle 10 dilin eklenmesi, bir sonraki derlemenin süresine hiçbir etki etmez.
Weglot ayrıca Next.js derlemenizin içinde şu ile de çalışır: @weglot/translate-react paket. Şunu sürdürmek yerine en.json ve fr.json Dosyalarda, bir derleyici eklentisi bileşenlerinizde yazılan metni algılar ve uygulamanız derlendiğinde bunu Weglot projeniz aracılığıyla çevirir. Sanity gibi başlıksız bir CMS adresinden alınan içerik, sayfa görüntülendiğinde sunucu tarafında çevrilir; böylece belgeleri her dil için ayrı ayrı çoğaltmak yerine tek bir belge kümesi tutarsınız.
Paketi yükleyin ve Weglot proje anahtarınızı şu dosyaya ekleyin: .env:
npm install @weglot/translate-react
# .env
WEGLOT_API_KEY=your_weglot_project_keyNext.js yapılandırmanızı şu kodla sarın: withWeglot():
// next.config.ts
import type { NextConfig } from "next";
import { withWeglot } from "@weglot/translate-react/next";
const nextConfig: NextConfig = {};
export default async function (): Promise<NextConfig> {
return await withWeglot(nextConfig, { sourceRoot: "./app" });
}Kök düzeninizi şu kodla sarın: WeglotProvider:
// app/layout.tsx
import { WeglotProvider } from "@weglot/translate-react/react/next";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<WeglotProvider>{children}</WeglotProvider>
</body>
</html>
);
}Ardından, Sanity'den aldığınız alanları şu yolla aktarın: tDynamic() bunları sunucu tarafında çevirmek için:
// app/blog/[slug]/page.tsx
import { tDynamic } from "@weglot/translate-react/dynamic";
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await getPost(slug); // fetched from Sanity
return <h1>{await tDynamic(post.title)}</h1>;
}Unutulmaması gereken iki nokta: Bir düzen veya veri alımı önbelleğe alınmışsa, önbelleği ziyaretçinin diline bağlı hale getirin; ayrıca yeni dizeler derleme sırasında çevrilir, bu nedenle metin eklediğinizde derleme işlemi biraz daha uzun sürebilir.
Başlamak için React ve Next.js’e giriş kılavuzuna, geliştiriciler için Sanity kılavuzuna ve Sanity + Next.js entegrasyon kurulumuna göz atın.
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.
Next.js siteniz Sanity gibi bir başsız (headless) CMS tarafından destekleniyorsa ve belgeleri her dil için ayrı ayrı çoğaltmak ya da çeviri dosyalarını yönetmek istemiyorsanız, Weglot React paketi hem bileşenlerinizi hem de CMS içeriğinizi çevirir. Sanity ile ilgili bilgi içinWeglot adresine bakın.
Çok dilli SEO ve sürekli çeviri yönetimi öncelikliyse, bu iki kütüphane de sorunu tam olarak çözmez. Yine de hreflang etiketlerini, site haritalarını ve içerik değiştikçe çevirileri güncel tutmak için bir iş akışı uygulamanız gerekecektir. Weglot adresindeki ters proxy, tüm bunları otomatik olarak halleder; ekibiniz ise Visual Editor adresinde çevirileri bağlam içinde inceleyebilir.
Weglot ve bileşen düzeyinde bir kütüphane birbirini dışlamaz. Weglot adresindeki ters proxy, HTML ve proxy katmanında çalışır; bu nedenle, bileşenlerinizin kullandığı herhangi bir kütüphaneyle bir arada kullanılabilir.
Bu yaklaşım sizin durumunuza uygunsa, başlangıç noktası olarak React ve Next.js’e giriş kılavuzuna veya JavaScript entegrasyonuna göz atın ve 14 günlük ücretsiz deneme sürümümüzü deneyin!
Son 90 gün içinde çevrilmiş sayfalardan gelen ziyaret sayısı:0.