Internationalization
Next.js, birden fazla dili desteklemek için içeriğin yönlendirilmesini ve oluşturulmasını yapılandırmanıza olanak tanır. Sitenizi farklı yerel ayarlara uyumlu hale getirmek, çevrilmiş içerik (yerelleştirme) ve uluslararasılaştırılmış rotaları içerir.
Terminology
- Yerel ayar: Bir dizi dil ve biçimlendirme tercihi için bir tanımlayıcı. Bu genellikle kullanıcının tercih ettiği dili ve muhtemelen coğrafi bölgesini içerir.
en-US
: Amerika Birleşik Devletleri'nde konuşulan İngilizcenl-NL
: Hollanda'da konuşulduğu şekliyle Hollandacanl
: Hollandaca, belirli bir bölge yok
Routing Overview
Hangi yerel ayarın kullanılacağını seçmek için kullanıcının tarayıcıdaki dil tercihlerini kullanmanız önerilir. Tercih ettiğiniz dili değiştirmek, uygulamanıza gelen Accept-Language
başlığını değiştirecektir.
Örneğin, aşağıdaki kütüphaneleri kullanarak, Headers
, desteklemeyi planladığınız yerel ayarlar ve varsayılan yerel ayarı temel alarak hangi yerel ayarı seçeceğinizi belirlemek için gelen bir Request
adresine bakabilirsiniz.
import { match } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
let headers = { 'accept-language': 'en-US,en;q=0.5' }
let languages = new Negotiator({ headers }).languages()
let locales = ['en-US', 'nl-NL', 'nl']
let defaultLocale = 'en-US'
match(languages, locales, defaultLocale) // -> 'en-US'
Yönlendirme, alt yol (/fr/products
) veya etki alanı (my-site.fr/products
) ile uluslararasılaştırılabilir. Bu bilgi ile artık kullanıcıyı Middleware içindeki yerel ayara göre yönlendirebilirsiniz.
let locales = ['en-US', 'nl-NL', 'nl']
// Get the preferred locale, similar to the above or using a library
function getLocale(request) { ... }
export function middleware(request) {
// Check if there is any supported locale in the pathname
const { pathname } = request.nextUrl
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
)
if (pathnameHasLocale) return
// Redirect if there is no locale
const locale = getLocale(request)
request.nextUrl.pathname = `/${locale}${pathname}`
// e.g. incoming request is /products
// The new URL is now /en-US/products
return Response.redirect(request.nextUrl)
}
export const config = {
matcher: [
// Skip all internal paths (_next)
'/((?!_next).*)',
// Optional: only run on root (/) URL
// '/'
],
}
Son olarak, app/
içindeki tüm özel dosyaların app/[lang]
altında yuvalandığından emin olun. Bu, Next.js yönlendiricisinin rotadaki farklı yerel ayarları dinamik olarak işlemesini ve lang
parametresini her düzene ve sayfaya iletmesini sağlar. Örneğin:
// You now have access to the current locale
// e.g. /en-US/products -> `lang` is "en-US"
export default async function Page({ params: { lang } }) {
return ...
}
Kök düzen de yeni klasörün içine yerleştirilebilir (örn. app/[lang]/layout.js
).
Localization
Görüntülenen içeriğin kullanıcının tercih ettiği yerel ayara veya yerelleştirmeye göre değiştirilmesi Next.js'ye özgü bir şey değildir. Aşağıda açıklanan kalıplar herhangi bir web uygulamasında aynı şekilde çalışacaktır.
Uygulamamız içinde hem İngilizce hem de Hollandaca içeriği desteklemek istediğimizi varsayalım. Bize bazı anahtarlardan yerelleştirilmiş bir dizeye eşleme sağlayan nesneler olan iki farklı "sözlük" tutabiliriz. Örneğin:
{
"products": {
"cart": "Add to Cart"
}
}
{
"products": {
"cart": "Toevoegen aan Winkelwagen"
}
}
Daha sonra istenen yerel ayar için çevirileri yüklemek üzere bir getDictionary
işlevi oluşturabiliriz:
import 'server-only'
const dictionaries = {
en: () => import('./dictionaries/en.json').then((module) => module.default),
nl: () => import('./dictionaries/nl.json').then((module) => module.default),
}
export const getDictionary = async (locale) => dictionaries[locale]()
O anda seçili olan dil göz önüne alındığında, bir düzen veya sayfanın içindeki sözlüğü getirebiliriz.
import { getDictionary } from './dictionaries'
export default async function Page({ params: { lang } }) {
const dict = await getDictionary(lang) // en
return <button>{dict.products.cart}</button> // Add to Cart
}
app/
dizinindeki tüm düzenler ve sayfalar varsayılan olarak Sunucu Bileşenleri olduğundan, çeviri dosyalarının boyutunun istemci tarafı JavaScript paketimizin boyutunu etkilemesi konusunda endişelenmemize gerek yoktur. Bu kod yalnızca sunucuda çalışacak ve tarayıcıya yalnızca ortaya çıkan HTML gönderilecektir.
Static Generation
Belirli bir yerel ayar kümesi için statik rotalar oluşturmak üzere generateStaticParams
adresini herhangi bir sayfa veya düzenle birlikte kullanabiliriz. Bu, örneğin kök düzeninde global olabilir:
export async function generateStaticParams() {
return [{ lang: 'en-US' }, { lang: 'de' }]
}
export default function Root({ children, params }) {
return (
<html lang={params.lang}>
<body>{children}</body>
</html>
)
}