İçindekiler
React i18n: React Uygulamalarında Uluslararasılaştırmaya Kapsamlı Kılavuz
Uluslararasılaştırma (i18n), dışarıdan basit görünen ancak uygulamaya başladığınızda haftalarca süren bir maceraya dönüşen özelliklerden biridir. Kullanıcılara İngilizce selamlama gösteren bir React uygulaması, gerçek anlamda küresel bir kitleye hizmet etmek için yalnızca string değiştirmeden çok daha fazlasına ihtiyaç duyar. Para birimi biçimlendirmesi, çoğul kuralları, tarih yerelleştirmesi, sağdan sola düzen desteği ve bir geliştirici her anahtar adını değiştirdiğinde bozulmayan bir çeviri iş akışı gerektirir.
Bu kılavuz, 2026 yılında üretime hazır çok dilli bir React uygulaması yayınlamak için bilmeniz gereken her şeyi ele alıyor — doğru kütüphaneyi seçmekten ileride size zaman kaybettirecek hataları önlemeye kadar.
Özet / Temel Çıkarımlar
- React'in yerleşik bir i18n desteği yoktur. Tarayıcının
IntlAPI'si biçimlendirmeyi yönetir, ancak çeviri stringlerini, dinamik yüklemeyi ve yerel ayar yönlendirmesini yönetmek için özel bir kütüphaneye ihtiyacınız vardır. - react-intl (FormatJS) ve react-i18next, büyük toplulukları ve yılların üretim deneyimiyle en yaygın kullanılan seçeneklerdir.
- LinguiJS, derleme zamanı çıkarımı ve minimum çalışma zamanı paket boyutu istiyorsanız en iyi seçimdir.
- Better i18n en yeni katılımcıdır — yapay zeka destekli çeviriler ve CDN dağıtımı ekler, ancak topluluğu yerleşik alternatiflere kıyasla daha küçüktür.
- Doğru kütüphane, ekip büyüklüğünüze, SSR gereksinimlerinize ve çeviri iş akışı otomasyonuna ne kadar değer verdiğinize göre değişir.
React Neden bir i18n Kütüphanesine İhtiyaç Duyar?
React, kullanıcı arayüzü oluşturur. Çevirileri yönetmez, tarayıcı yerel ayarlarını algılamaz, dil dosyalarını asenkron olarak yüklemez veya diller arasında farklılık gösteren karmaşık biçimlendirme kurallarını işlemez. Bu, tasarım gereğidir — React bir görünüm kütüphanesidir.
Tarayıcı, gerçekten güçlü olan Intl API'siyle birlikte gelir. Intl.DateTimeFormat, Intl.NumberFormat ve Intl.PluralRules, herhangi bir harici bağımlılık olmaksızın yerel ayara duyarlı biçimlendirme sağlar. Ancak Intl, string yönetimini değil biçimlendirmeyi çözer.
Intl'nin ötesinde hâlâ ihtiyaç duyduklarınız:
- Bir string kataloğu — Çevrilmiş stringleri yerel ayar ve mesaj kimliğine göre saklayan bir yapı.
- Bir React bağlantısı — Katalogdan okuyan ve yerel ayar değiştiğinde yeniden render eden hook'lar ve bileşenler.
- Dinamik yükleme — Tüm yerel ayarların stringlerini aynı anda değil, yalnızca mevcut yerel ayarın stringlerini yükleme.
- Çoğullama ve enterpolasyon —
"1 öğe"ile"3 öğe"arasındaki farkı yönetme ve mesajlara kullanıcı adları gibi dinamik değerler ekleme. - Bir çeviri iş akışı — Çevirmenlerin yeni stringleri nasıl aldığı, bunları nasıl çevirdiği ve bu çevirilerin uygulamanıza nasıl geri döndüğü.
Bunların hepsini kendiniz oluşturmak mümkündür, ancak tavsiye edilmez. Aşağıdaki kütüphaneler bu sorunları milyonlarca üretim dağıtımında çözmüştür. Bunlardan biriyle başlayın.
Popüler React i18n Kütüphanelerinin Karşılaştırması
| Kütüphane | Paket Boyutu | ICU Desteği | TypeScript Desteği | SSR Desteği | Öğrenme Eğrisi |
|---|---|---|---|---|---|
| react-intl (FormatJS) | ~20KB gzipped | Tam | Güçlü | Evet | Orta |
| react-i18next | ~6KB gzipped | Eklenti ile | Güçlü | Evet | Düşük-Orta |
| LinguiJS | ~2KB çalışma zamanı | Tam | Güçlü | Evet | Orta-Yüksek |
| Better i18n React SDK | ~2KB | Kısmi | Tam (çıkarsanmış) | Evet | Düşük |
Paket boyutları yaklaşık değerlerdir ve tree-shaking ile kullandığınız özelliklere göre değişir. ICU (International Components for Unicode) mesaj formatı, karmaşık çoğullama, cinsiyet seçimi ve koşullu metin için standarttır — her kütüphane bunu doğal olarak desteklemez.
react-intl (FormatJS)
react-intl, Formatly (eski adıyla Yahoo) tarafından sürdürülen FormatJS paketinin bir parçasıdır. Yıllardır React'te karmaşık i18n için fiili standart olmuştur ve ekosistemde ICU mesaj formatının en eksiksiz uygulamasını sunar.
Kurulum
npm install react-intl
Uygulamanızı IntlProvider ile Sarmalama
IntlProvider, tüm bileşen ağacınız için yerel ayar bağlamını oluşturur. Altındaki her FormattedMessage ve useIntl çağrısı bu bağlamdan okur.
// src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import { IntlProvider } from "react-intl";
import App from "./App";
import enMessages from "./locales/en.json";
import frMessages from "./locales/fr.json";
const messages: Record<string, Record<string, string>> = {
en: enMessages,
fr: frMessages,
};
const userLocale = navigator.language.split("-")[0] ?? "en";
const activeLocale = userLocale in messages ? userLocale : "en";
ReactDOM.createRoot(document.getElementById("root")!).render(
<IntlProvider locale={activeLocale} messages={messages[activeLocale]}>
<App />
</IntlProvider>
);
Mesaj kataloğunuz düz bir JSON dosyasıdır:
// src/locales/en.json
{
"greeting": "Hello, {name}!",
"itemCount": "{count, plural, one {# item} other {# items}}",
"welcomeBack": "Welcome back, <bold>{name}</bold>!"
}
FormattedMessage Bileşeni
Çevirilerinizde zengin metin biçimlendirmesine veya satır içi JSX'e ihtiyaç duyduğunuzda FormattedMessage kullanın:
// src/components/Welcome.tsx
import React from "react";
import { FormattedMessage } from "react-intl";
interface WelcomeProps {
name: string;
itemCount: number;
}
export function Welcome({ name, itemCount }: WelcomeProps) {
return (
<div>
<h1>
<FormattedMessage
id="greeting"
values={{ name }}
/>
</h1>
<p>
<FormattedMessage
id="itemCount"
values={{ count: itemCount }}
/>
</p>
<p>
<FormattedMessage
id="welcomeBack"
values={{
name,
bold: (chunks) => <strong>{chunks}</strong>,
}}
/>
</p>
</div>
);
}
useIntl Hook'u
Zorunlu kullanım için — JSX dışında, olay işleyicileri içinde veya aria-label nitelikleri için stringleri biçimlendirmek amacıyla — useIntl hook'unu kullanın:
// src/components/SearchBar.tsx
import React from "react";
import { useIntl } from "react-intl";
export function SearchBar() {
const intl = useIntl();
const placeholder = intl.formatMessage({
id: "search.placeholder",
defaultMessage: "Search products...",
});
const formattedPrice = intl.formatNumber(29.99, {
style: "currency",
currency: "USD",
});
const formattedDate = intl.formatDate(new Date(), {
year: "numeric",
month: "long",
day: "numeric",
});
return (
<div>
<input type="search" placeholder={placeholder} aria-label={placeholder} />
<span>{formattedPrice}</span>
<time>{formattedDate}</time>
</div>
);
}
react-intl dokümantasyonu formatjs.io/docs/react-intl adresindedir.
react-i18next
react-i18next, en yaygın kullanılan JavaScript i18n çerçevesi olan i18next için React bağlantısıdır. Güçlü yönü esnekliktir: React, React Native, Node.js ve React dışı ortamlarda çalışır. Ekibiniz başka bir yerde zaten i18next kullanıyorsa, paylaşılan zihinsel model gerçek bir avantaj sağlar.
Kurulum
npm install i18next react-i18next
Yapılandırma
// src/i18n/config.ts
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import enCommon from "./locales/en/common.json";
import enDashboard from "./locales/en/dashboard.json";
import frCommon from "./locales/fr/common.json";
import frDashboard from "./locales/fr/dashboard.json";
i18n
.use(initReactI18next)
.init({
resources: {
en: {
common: enCommon,
dashboard: enDashboard,
},
fr: {
common: frCommon,
dashboard: frDashboard,
},
},
lng: "en",
fallbackLng: "en",
defaultNS: "common",
interpolation: {
escapeValue: false, // React zaten değerleri kaçırır
},
});
export default i18n;
Herhangi bir bileşen render edilmeden önce yapılandırmayı uygulamanızın giriş noktasında içe aktarın:
// src/main.tsx
import "./i18n/config";
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
useTranslation Hook'u ve Ad Alanı Bölme
Ad alanı bölme, büyük uygulamalar için react-i18next'in en kullanışlı özelliklerinden biridir. Tek bir devasa JSON dosyası yüklemek yerine, çevirileri özellik veya etki alanına göre böler ve ad alanlarını talep üzerine yüklersiniz.
// src/i18n/locales/en/common.json
{
"nav.home": "Home",
"nav.dashboard": "Dashboard",
"nav.settings": "Settings",
"button.save": "Save",
"button.cancel": "Cancel"
}
// src/i18n/locales/en/dashboard.json
{
"title": "Your Dashboard",
"stats.users": "{{count}} active user",
"stats.users_other": "{{count}} active users",
"welcome": "Welcome back, {{name}}!"
}
// src/components/Dashboard.tsx
import React from "react";
import { useTranslation } from "react-i18next";
interface DashboardProps {
userName: string;
activeUsers: number;
}
export function Dashboard({ userName, activeUsers }: DashboardProps) {
// Özellikle "dashboard" ad alanını yükle
const { t } = useTranslation("dashboard");
return (
<main>
<h1>{t("title")}</h1>
<p>{t("welcome", { name: userName })}</p>
<p>{t("stats.users", { count: activeUsers })}</p>
</main>
);
}
// src/components/Nav.tsx
import React from "react";
import { useTranslation } from "react-i18next";
export function Nav() {
// Varsayılan "common" ad alanını kullanır
const { t, i18n } = useTranslation();
const switchLanguage = (locale: string) => {
i18n.changeLanguage(locale);
};
return (
<nav>
<a href="/">{t("nav.home")}</a>
<a href="/dashboard">{t("nav.dashboard")}</a>
<button onClick={() => switchLanguage("fr")}>Francais</button>
<button onClick={() => switchLanguage("en")}>English</button>
</nav>
);
}
react-i18next dokümantasyonu react.i18next.com adresindedir.
LinguiJS
LinguiJS, temelden farklı bir yaklaşım benimser. Kimliğe göre referans verdiğiniz JSON dosyalarındaki çeviri anahtarlarını yönetmek yerine, kullanıcı arayüzünüzü doğrudan JSX içinde doğal dilde yazarsınız. Ardından bir CLI bu stringleri bir kataloga çıkarır; çevirmenler bu kataloğu doldurur. Derleme zamanında mesajlar optimize edilmiş bir ikili formata derlenir.
Sonuç, daha küçük bir çalışma zamanı paketi ve bozuk anahtar referansları riskinin azalmasıdır — ancak diğer kütüphanelerin gerektirmediği bir derleme adımı gerektirir.
Kurulum
npm install @lingui/react @lingui/core npm install --save-dev @lingui/cli @lingui/macro @lingui/vite-plugin
Yapılandırma
// lingui.config.js
/** @type {import('@lingui/conf').LinguiConfig} */
module.exports = {
locales: ["en", "fr", "de"],
sourceLocale: "en",
catalogs: [
{
path: "src/locales/{locale}/messages",
include: ["src"],
},
],
format: "po",
};
@lingui/macro Kullanımı
Makro, doğal dil stringlerini derleme zamanında dönüştürür; böylece kaynak kodunuz düz İngilizce gibi okunurken tam olarak yerelleştirilebilir kalır:
// src/components/ProductCard.tsx
import React from "react";
import { Trans, Plural } from "@lingui/macro";
import { useLingui } from "@lingui/react";
interface ProductCardProps {
productName: string;
price: number;
reviewCount: number;
}
export function ProductCard({ productName, price, reviewCount }: ProductCardProps) {
const { i18n } = useLingui();
const formattedPrice = i18n.number(price, {
style: "currency",
currency: "USD",
});
return (
<article>
<h2>
<Trans>Buy {productName} today</Trans>
</h2>
<p>{formattedPrice}</p>
<p>
<Plural
value={reviewCount}
one="# customer review"
other="# customer reviews"
/>
</p>
<p>
<Trans>
Free shipping on orders over <strong>$50</strong>.
</Trans>
</p>
</article>
);
}
Çıkarım İş Akışı
Bileşenlerinizi yazdıktan sonra, stringleri çıkarmak için CLI'yi çalıştırın:
# Tüm stringleri kaynak dosyalardan kataloğa çıkar npx lingui extract # .po dosyalarını çevirin (veya çeviri servisinize gönderin) # Ardından üretim için derleyin npx lingui compile
Derlenen kataloglar küçük ve hızlı yüklenir. LinguiJS, çevirmen dostu PO dosyası iş akışı ve mümkün olan en küçük çalışma zamanı yükü isteyen ekipler için özellikle çekicidir.
Tam dokümantasyon lingui.dev adresindedir.
Better i18n React SDK
Better i18n, React i18n alanındaki daha yeni bir katılımcıdır. Yalnızca bir çeviri-render kütüphanesi olarak rekabet etmek yerine, eksiksiz bir iş akışı platformu sunar: marka bağlamı farkındalığına sahip yapay zeka destekli çeviriler, AST taraması yoluyla otomatik anahtar keşfi ve çeviri güncellemelerinin yeniden derleme gerektirmeden yayına girmesini sağlayan CDN dağıtımı.
Seçmeden önce ödünleşimler konusunda dürüst olun: Topluluk, react-intl veya i18next'in bir kesimidir. Stack Overflow cevapları seyrek. Bir kenar durumla karşılaşırsanız, topluluk çözümlerine değil, resmi dokümantasyona veya destek kanalına güvenmeniz daha olasıdır. Kütüphane iyi bakımlıdır ve aktif olarak geliştirilmektedir, ancak yerleşik seçeneklerin sahip olduğu yılların üretim sınavından henüz geçmemiştir.
Kurulum
npm install @better-i18n/react
Kurulum
// src/providers/I18nProvider.tsx
import React, { type ReactNode } from "react";
import { BetterI18nProvider } from "@better-i18n/react";
interface I18nProviderProps {
children: ReactNode;
locale: string;
}
export function I18nProvider({ children, locale }: I18nProviderProps) {
return (
<BetterI18nProvider
projectId={process.env.VITE_BETTER_I18N_PROJECT_ID!}
locale={locale}
>
{children}
</BetterI18nProvider>
);
}
// src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { I18nProvider } from "./providers/I18nProvider";
const locale = navigator.language.split("-")[0] ?? "en";
ReactDOM.createRoot(document.getElementById("root")!).render(
<I18nProvider locale={locale}>
<App />
</I18nProvider>
);
useTranslations Hook'u
// src/components/HeroSection.tsx
import React from "react";
import { useTranslations } from "@better-i18n/react";
interface HeroSectionProps {
userName: string;
planName: string;
}
export function HeroSection({ userName, planName }: HeroSectionProps) {
const t = useTranslations("hero");
return (
<section>
<h1>{t("title", { name: userName })}</h1>
<p>{t("subtitle", { plan: planName })}</p>
<a href="/signup">{t("cta")}</a>
</section>
);
}
Çeviri anahtarları, Better i18n panosunda tanımlanır veya CLI tarayıcısı tarafından kaynak kodunuzdan otomatik olarak keşfedilir. Bir çevirmen değişikliği onayladığında, Cloudflare'ın CDN edge ağı aracılığıyla uygulamanıza iletilir — yeniden derleme veya yeniden dağıtım gerekmez.
Better i18n dokümantasyonu better-i18n.com/docs adresindedir.
Better i18n'i alternatiflere tercih etme zamanı: Ekibiniz kutudan çıktığı gibi yapay zeka destekli çeviriler istiyor, tamamen bağımsız bir kütüphane yerine yönetilen bir platform kullanmaktan rahatsız değilsiniz ve iş akışı otomasyonu (otomatik anahtar keşfi, CDN dağıtımı, GitHub PR tabanlı eşitleme) ekosistem genişliğinden daha değerli.
Başka bir şey seçme zamanı: Mümkün olan en büyük topluluğa, yılların Stack Overflow cevaplarına veya harici servis bağımlılığı olmayan tamamen kendi barındırılan bir çözüme ihtiyacınız var. Bu durumda, react-i18next veya react-intl daha güvenli seçimdir.
Temel Uygulama Kalıpları
Dil Değiştirme
Dil değiştirme, kullanıcıların yerelleştirilmiş bağlantıları paylaşabilmesi için durum bilgili ve URL'ye yansıtılmış olmalıdır. En basit yaklaşım, yerel ayarı state'te saklar ve provider'ınıza iletir; ancak URL tabanlı bir yaklaşım, SSR ve derin bağlantı için daha sağlamdır.
// src/hooks/useLocale.ts
import { useState, useCallback } from "react";
const SUPPORTED_LOCALES = ["en", "fr", "de", "es"] as const;
type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];
function getInitialLocale(): SupportedLocale {
const fromUrl = window.location.pathname.split("/")[1] as SupportedLocale;
if (SUPPORTED_LOCALES.includes(fromUrl)) return fromUrl;
const fromBrowser = navigator.language.split("-")[0] as SupportedLocale;
if (SUPPORTED_LOCALES.includes(fromBrowser)) return fromBrowser;
return "en";
}
export function useLocale() {
const [locale, setLocale] = useState<SupportedLocale>(getInitialLocale);
const switchLocale = useCallback((next: SupportedLocale) => {
setLocale(next);
document.documentElement.lang = next;
// İsteğe bağlı: URL tabanlı yönlendirme için router geçmişine ekle
}, []);
return { locale, switchLocale, supportedLocales: SUPPORTED_LOCALES };
}
Çevirileri Gecikmeli Yükleme
Tüm yerel ayar paketlerini önceden yüklemek bant genişliği israfına yol açar. Yalnızca aktif yerel ayarı yükleyin ve diğerlerini talep üzerine getirin:
// src/i18n/loader.ts
const localeCache = new Map<string, Record<string, string>>();
export async function loadLocale(locale: string): Promise<Record<string, string>> {
if (localeCache.has(locale)) {
return localeCache.get(locale)!;
}
// Dinamik import — paketleyici bunu yerel ayar başına ayrı bir parçaya böler
const messages = await import(`./locales/${locale}.json`);
const resolved = messages.default as Record<string, string>;
// Yerinde mutasyon yerine yeni bir map girişi döndür
const updated = new Map(localeCache);
updated.set(locale, resolved);
localeCache.clear();
updated.forEach((v, k) => localeCache.set(k, v));
return resolved;
}
SSR / SSG Hususları
Sunucuda render edildiğinde, yerel ayar algılama navigator.language'dan HTTP başlıklarına (Accept-Language) veya URL segmentlerine taşınır. Sunucu ve istemcinin özdeş HTML üretmesi için yerel ayar, render başlamadan önce çözümlenmiş olmalıdır.
// src/app/[locale]/layout.tsx (Next.js App Router örneği)
import { notFound } from "next/navigation";
import { type ReactNode } from "react";
const SUPPORTED_LOCALES = ["en", "fr", "de"];
interface LocaleLayoutProps {
children: ReactNode;
params: { locale: string };
}
export default function LocaleLayout({ children, params }: LocaleLayoutProps) {
if (!SUPPORTED_LOCALES.includes(params.locale)) {
notFound();
}
return (
<html lang={params.locale} dir={params.locale === "ar" ? "rtl" : "ltr"}>
<body>{children}</body>
</html>
);
}
export function generateStaticParams() {
return SUPPORTED_LOCALES.map((locale) => ({ locale }));
}
URL Tabanlı Yerel Ayar Yönlendirmesi
Arama motorları example.com/fr/produits ve example.com/en/products'ı ayrı, dizine eklenebilir sayfalar olarak değerlendirir. URL tabanlı yönlendirme, SEO için çerez tabanlı veya başlık tabanlı algılamaya kıyasla güçlü bir şekilde tercih edilir. Rotalarınızı kökte [locale] segmentiyle yapılandırın ve desteklenen her yerel ayar için <head>'e hreflang link etiketleri ekleyin.
Çoğullama
Burada ele alınan her kütüphane çoğullamayı farklı şekilde işler; ancak temel kurallar CLDR'den (Common Locale Data Repository) gelir. İngilizcenin iki çoğul biçimi vardır. Arapçanın altı. Çoğullama mantığını asla kendiniz sabit kodlamayın.
react-i18next ile (_one / _other son ekleri kullanarak):
{
"notification": "{{count}} notification",
"notification_other": "{{count}} notifications"
}
t("notification", { count: 1 }); // "1 notification"
t("notification", { count: 5 }); // "5 notifications"
Tarih ve Sayı Biçimlendirme
Kütüphanenin yerleşik biçimlendirme araçlarını kullanın veya doğrudan Intl'e geri dönün. Biçimlendirilmiş değerleri asla string olarak birleştirmeyin — birimlerin sırası yerel ayara göre farklılık gösterir.
// Intl'i doğrudan kullanma (herhangi bir kütüphaneyle çalışır)
const formatter = new Intl.NumberFormat(locale, {
style: "currency",
currency: "EUR",
});
// en-US'ta "€1,234.56", fr-FR'de "1 234,56 €" — aynı sayı, farklı format
formatter.format(1234.56);
Yaygın Hatalar
String birleştirme. Çevrilmiş parçaları + veya şablon literal'leriyle birleştirerek asla cümle oluşturmayın. Kelime sırası dile göre değişir. "Merhaba " + t("dünya"), selamlama isimden sonra gelen dillerde bozulur. Her zaman enterpolasyon değişkenlerini çeviri fonksiyonuna geçirin.
Bağlamı unutmak. İngilizcedeki "File" kelimesi isim (bir belge) veya fiil (şikayet etmek) anlamına gelebilir. Çevirmenler doğru kelimeyi seçmek için bağlama ihtiyaç duyar. Çoğu kütüphane bir context parametresi veya açıklama alanı destekler — bunları kullanın.
Yükleme durumlarını işlememek. Çeviriler asenkron olarak yüklendiğinde, bileşeninizin stringler hazır olmadan render edildiği bir pencere oluşur. İskelet, döndürücü veya hiçbir şey render edin — ancak kullanıcıya asla "dashboard.title" gibi ham çeviri anahtarları göstermeyin.
Tüm yerel ayarları bir arada paketleme. Yalnızca İngilizce okuyan bir kullanıcıya Fransızca, Almanca, İspanyolca ve Japonca çeviriler göndermek bant genişliği israfına yol açar ve Etkileşim Sürenizi (Time to Interactive) artırır. Yalnızca gerekli olanı yüklemek için dinamik import'lar veya CDN tabanlı bir dağıtım stratejisi kullanın.
Yerel ayara özgü biçimlendirmeyi sabit kodlamak. MM/DD/YYYY gibi tarih formatlarını sabit kodlamayın. Alman kullanıcılar DD.MM.YYYY bekler. Biçimlendirmeyi her zaman Intl'e veya kütüphanenizin biçimlendirme araçlarına devredin.
Çevrilmiş HTML'i ham işaretleme olarak render etmek. Çevrili stringleri ham HTML olarak enjekte etmek, çeviri kaynağınız tehlikeye girerse XSS riski oluşturur. HTML stringlerini doğrudan render etmek yerine kütüphanenizin güvenli zengin metin bileşenlerini kullanın — react-intl'de element değerleriyle FormattedMessage veya react-i18next'te Trans bileşeni.
SSS
S: ICU mesaj formatı desteğine ihtiyacım var mı?
ICU, çoğullar, cinsiyet seçimi ve koşullu metin içeren karmaşık mesajlar için standarttır. Uygulamanızda "John ve 3 diğeri bunu beğendi" gibi cümleler varsa, ICU bu kuralları temiz ve taşınabilir şekilde ifade etmeyi sağlar. Uygulamanız yalnızca basit string değiştirmeye ihtiyaç duyuyorsa, ICU isteğe bağlı bir ek yüktür. react-intl ve LinguiJS, ICU'yu doğal olarak destekler. react-i18next, i18next-icu eklentisini gerektirir.
S: Hangi kütüphane Next.js App Router ile en iyi çalışır?
react-i18next ve react-intl'nin her ikisi de bazı yapılandırmalarla App Router'ı destekler. Next.js ekosistemi, birinci sınıf Server Component desteği nedeniyle App Router projeleri için next-intl etrafında bir araya gelmiştir. Better i18n ayrıca özel bir Next.js SDK sunar. LinguiJS çalışır, ancak derleme ardışık düzenindeki derleme adımının dikkatli şekilde yönetilmesini gerektirir.
S: Çeviri dosyalarımı nasıl yapılandırmalıyım?
Küçük uygulamalar için, yerel ayar başına tek bir JSON dosyası (en.json, fr.json) uygundur. Daha büyük uygulamalar için, özellik veya etki alanına göre bölün (i18next'te ad alanları, LinguiJS'te ayrı kataloglar). Derin iç içe nesnelerden kaçının — düz veya bir seviye derinliğindeki anahtarlar büyük ölçekte yönetimi daha kolay kılar ve birleştirme çakışmalarına daha az eğilimlidir.
S: Kalın metin veya bağlantılar gibi işaretleme içeren çevirileri nasıl yönetirim?
Çoğu kütüphane, render prop veya slot sistemi aracılığıyla zengin metni destekler. react-intl'de FormattedMessage'a değer olarak bir JSX öğesi geçirin. react-i18next'te Trans bileşenini kullanın. Bu yaklaşımlar, HTML'i string kataloğunuza işaretleme karıştırmak yerine düzgün şekilde kaçırılıp sanitize edilebildiği React'te tutar.
S: i18n hakkında ne zaman düşünmeye başlamalıyım? Sandığınızdan daha erken. Mevcut bir kod tabanına i18n eklemek, her sabit kodlanmış stringi, her tarih formatını, her çoğul varsayımını ve daha uzun Almanca kelimelerle bozulan her düzeni avlamak anlamına gelir. Uygulamanızın İngilizce konuşmayanlar tarafından kullanılma ihtimali varsa, ilk kurulumunuzda — yalnızca İngilizce yayınsanız bile — i18n altyapısı ekleyin.
Sonuç
React i18n'nin tek doğru cevabı yoktur. Doğru kütüphane, ekibinizin iş akışına, uygulamanızın karmaşıklığına ve ekosistem riskine toleransınıza göre değişir.
Yeni bir projeye başlıyorsanız ve en fazla topluluk desteğini ve en derin ekosistemi istiyorsanız, react-i18next güvenli varsayılandır. Ad alanı sistemi iyi ölçeklenir, dokümantasyonu kapsamlıdır ve çoğu kenar durumun cevabını Stack Overflow'da bulabilirsiniz.
Uygulamanızda gerçekten karmaşık mesaj biçimlendirme gereksinimleri varsa — koşullu cinsiyet, çok düzeyli çoğullar, zengin satır içi işaretleme — react-intl, React ekosisteminde ICU standardının en eksiksiz uygulamasıdır.
En küçük çalışma zamanı paketini ve derleyici tarafından zorunlu kılınan çıkarım iş akışını istiyorsanız, LinguiJS, özellikle bir derleme adımı eklemeye alışkın ekipler için cazip bir alternatif sunar.
Yapay zeka destekli çeviriler, yeniden derleme döngüsü olmadan CDN dağıtımı ve çeviri sürecini otomatikleştiren yönetilen bir platform istiyorsanız, Better i18n değerlendirmeye değer — daha genç bir ekosisteme daha küçük bir toplulukla bahis yaptığınızı dürüstçe kabul ederek.
Her ne seçerseniz seçin, erken bağlanın, çeviri dosyalarınızı düzenli tutun ve i18n'e sonradan düşünülen bir şey olarak değil, birinci sınıf bir özellik olarak davranın. Uluslararası kullanıcılarınız farkı fark edecektir.
Referanslar
- react-intl (FormatJS): formatjs.io/docs/react-intl
- react-i18next: react.i18next.com
- i18next core: www.i18next.com
- LinguiJS: lingui.dev
- Better i18n React SDK: better-i18n.com/docs
- Unicode CLDR Plural Rules: cldr.unicode.org/index/cldr-spec/plural-rules
- MDN Intl API reference: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl