2026'da i18n ve AI Destekli Modern Web Uygulaması Nasıl Geliştirilir?
Lingui ve AI çevirileriyle çok dilli web uygulamaları geliştirme rehberi. Next.js, Claude ve T3 Turbo kullanarak 17 dili otomatik olarak destekleyin.

Bakın, 2026'da i18n (uluslararasılaştırma) hakkında konuşmamız lazım.
Çoğu eğitim size metinleri manuel olarak çevirmenizi, tercüman tutmanızı veya dandik Google Translate API'larını kullanmanızı söyleyecektir. Ama olay şu: Siz Claude Sonnet 4.5 çağında yaşıyorsunuz. Neden hala 2019'daymışız gibi çeviri yapıyorsunuz?
Size, gerçekten mantıklı olan iki parçalı bir i18n mimarisi kullanarak, 17 dili akıcı bir şekilde konuşan production seviyesinde bir web uygulamasını nasıl geliştirdiğimizi göstereceğim:
- Lingui: Çıkarma (extraction), derleme ve runtime sihri için.
- Özel bir i18n paketi: Otomatik, bağlam duyarlı (context-aware) çeviriler için LLM'lerden güç alan bir paket.
Teknoloji yığınımız (stack) mı? Next.js, tRPC, Drizzle, Postgres, Tailwind ve AI SDK ile Create T3 Turbo. Eğer 2026'da bunu kullanmıyorsanız, oturup farklı bir konuşma yapmamız lazım.
Hadi inşa edelim.
Geleneksel i18n İle İlgili Sorun
Geleneksel i18n iş akışları şuna benzer:
# Metinleri çıkar (extract)
$ lingui extract
# ??? Bir şekilde çevirileri al ???
# (tercüman tut, şüpheli servisler kullan, ağla)
# Derle (compile)
$ lingui compile
O ortadaki adım var ya? Tam bir kabus. Ya:
- İnsan çevirmenlere $$$ ödüyorsunuz (yavaş, pahalı)
- Temel çeviri API'ları kullanıyorsunuz (bağlamdan habersiz, robotik duyuluyor)
- Manuel çeviriyorsunuz (ölçeklenemez)
Biz daha iyisini yapıyoruz.
İki Parçalı Mimari
İşte bizim kurulumumuz:
┌─────────────────────────────────────────────┐
│ Next.js Uygulaması (Lingui Entegrasyonu) │
│ ├─ Makrolarla metinleri çıkarma │
│ ├─ Kodunuzda Trans/t bileşenleri │
│ └─ Derlenmiş kataloglarla runtime i18n │
└─────────────────────────────────────────────┘
↓ .po dosyaları üretir
┌─────────────────────────────────────────────┐
│ @acme/i18n Paketi (LLM Çevirisi) │
│ ├─ .po dosyalarını okur │
│ ├─ Claude/GPT-5 ile toplu çeviri yapar │
│ ├─ Bağlam duyarlı, ürüne özel │
│ └─ Çevrilmiş .po dosyalarını yazar │
└─────────────────────────────────────────────┘
↓ TypeScript'e derlenir
┌─────────────────────────────────────────────┐
│ Derlenmiş Mesaj Katalogları │
│ └─ Hızlı, tip güvenli runtime çevirileri │
└─────────────────────────────────────────────┘
1. Parça (Lingui) geliştirici deneyimini (DX) halleder. 2. Parça (Özel i18n Paketi) çeviri sihrini halleder.
Hadi her birine derinlemesine bakalım.

Bölüm 1: Next.js İçinde Lingui Kurulumu
Kurulum
T3 Turbo monorepo'nuzda:
# apps/nextjs içinde
pnpm add @lingui/core @lingui/react @lingui/macro
pnpm add -D @lingui/cli @lingui/swc-plugin
Lingui Konfigürasyonu
apps/nextjs/lingui.config.ts dosyasını oluşturun:
import type { LinguiConfig } from "@lingui/conf";
const config: LinguiConfig = {
locales: [
"en", "zh_CN", "zh_TW", "ja", "ko",
"de", "fr", "es", "pt", "ar", "it",
"ru", "tr", "th", "id", "vi", "hi"
],
sourceLocale: "en",
fallbackLocales: {
default: "en"
},
catalogs: [
{
path: "<rootDir>/src/locales/{locale}/messages",
include: ["src"],
},
],
};
export default config;
Kutudan çıktığı gibi 17 dil. Neden olmasın ki?
Next.js Entegrasyonu
Lingui'nin SWC eklentisini kullanmak için next.config.js dosyasını güncelleyin:
const linguiConfig = require("./lingui.config");
module.exports = {
experimental: {
swcPlugins: [
[
"@lingui/swc-plugin",
{
// Bu, buildlerinizi hızlandırır
},
],
],
},
// ... konfigürasyonunuzun geri kalanı
};
Sunucu Tarafı (Server-Side) Kurulumu
src/utils/i18n/appRouterI18n.ts dosyasını oluşturun:
import { setupI18n } from "@lingui/core";
import { allMessages } from "./initLingui";
const locales = ["en", "zh_CN", "zh_TW", /* ... */] as const;
const instances = new Map<string, ReturnType<typeof setupI18n>>();
// Tüm diller için i18n örneklerini önceden oluşturun
locales.forEach((locale) => {
const i18n = setupI18n({
locale,
messages: { [locale]: allMessages[locale] },
});
instances.set(locale, i18n);
});
export function getI18nInstance(locale: string) {
return instances.get(locale) ?? instances.get("en")!;
}
Neden? Server Component'lerin React Context'i yoktur. Bu size sunucu tarafı çevirileri sağlar.
İstemci Tarafı (Client-Side) Provider
src/providers/LinguiClientProvider.tsx dosyasını oluşturun:
"use client";
import { I18nProvider } from "@lingui/react";
import { setupI18n } from "@lingui/core";
import { useEffect, useState } from "react";
export function LinguiClientProvider({
children,
locale,
messages
}: {
children: React.ReactNode;
locale: string;
messages: any;
}) {
const [i18n] = useState(() =>
setupI18n({
locale,
messages: { [locale]: messages },
})
);
useEffect(() => {
i18n.load(locale, messages);
i18n.activate(locale);
}, [locale, messages, i18n]);
return <I18nProvider i18n={i18n}>{children}</I18nProvider>;
}
Uygulamanızı layout.tsx içinde sarmalayın:
import { LinguiClientProvider } from "@/providers/LinguiClientProvider";
import { getLocale } from "@/utils/i18n/localeDetection";
import { allMessages } from "@/utils/i18n/initLingui";
export default function RootLayout({ children }: { children: React.ReactNode }) {
const locale = getLocale();
return (
<html lang={locale}>
<body>
<LinguiClientProvider locale={locale} messages={allMessages[locale]}>
{children}
</LinguiClientProvider>
</body>
</html>
);
}
Kodunuzda Çevirileri Kullanmak
Server Component'lerde:
import { msg } from "@lingui/core/macro";
import { getI18nInstance } from "@/utils/i18n/appRouterI18n";
export async function generateMetadata({ params }) {
const locale = getLocale();
const i18n = getI18nInstance(locale);
return {
title: i18n._(msg`Pricing Plans | acme`),
description: i18n._(msg`Choose the perfect plan for you`),
};
}
Client Component'lerde:
"use client";
import { Trans, useLingui } from "@lingui/react/macro";
export function PricingCard() {
const { t } = useLingui();
return (
<div>
<h1><Trans>Pricing Plans</Trans></h1>
<p>{t`Ultimate entertainment experience`}</p>
{/* Değişkenlerle */}
<p>{t`${credits} credits remaining`}</p>
</div>
);
}
Makro sözdizimi ANAHTAR noktadır. Lingui bunları build zamanında (build time) ayıklar.
Bölüm 2: AI Destekli Çeviri Paketi
İşin en civcivli kısmı burası.
Paket Yapısı
packages/i18n/ oluşturun:
packages/i18n/
├── package.json
├── src/
│ ├── translateWithLLM.ts # Çekirdek LLM çevirisi
│ ├── enhanceTranslations.ts # Toplu işlemci
│ └── utils.ts # Yardımcılar
package.json
{
"name": "@acme/i18n",
"version": "0.1.0",
"dependencies": {
"@acme/ai": "workspace:*",
"openai": "^4.77.3",
"pofile": "^1.1.4",
"zod": "^3.23.8"
}
}
LLM Çeviri Motoru
İşte gizli sosumuz - translateWithLLM.ts:
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { z } from "zod";
const translationSchema = z.object({
translations: z.array(
z.object({
msgid: z.string(),
msgstr: z.string(),
})
),
});
export async function translateWithLLM(
messages: Array<{ msgid: string; msgstr: string }>,
targetLocale: string,
options?: { model?: string }
) {
const prompt = `You are a professional translator for acme, an AI-powered creative platform.
Translate the following strings from English to ${getLanguageName(targetLocale)}.
CONTEXT:
- acme is a platform for AI chat, image generation, and creative content
- Keep brand names unchanged (acme, Claude, etc.)
- Preserve HTML tags, variables like {count}, and placeholders
- Adapt culturally where appropriate
- Maintain tone: friendly, creative, engaging
STRINGS TO TRANSLATE:
${JSON.stringify(messages, null, 2)}
Return a JSON object with this structure:
{
"translations": [
{ "msgid": "original", "msgstr": "translation" },
...
]
}`;
const result = await generateText({
model: openai(options?.model ?? "gpt-4o"),
prompt,
temperature: 0.3, // Düşük = daha tutarlı
});
const parsed = translationSchema.parse(JSON.parse(result.text));
return parsed.translations;
}
function getLanguageName(locale: string): string {
const names: Record<string, string> = {
zh_CN: "Simplified Chinese",
zh_TW: "Traditional Chinese",
ja: "Japanese",
ko: "Korean",
de: "German",
fr: "French",
es: "Spanish",
pt: "Portuguese",
ar: "Arabic",
// ... vb
};
return names[locale] ?? locale;
}
Bu neden çalışıyor:
- Bağlam duyarlı (Context-aware): LLM, acme'nin ne olduğunu biliyor.
- Yapılandırılmış çıktı: Zod şeması geçerli JSON olmasını garanti eder.
- Düşük sıcaklık (temperature): Tutarlı çeviriler.
- Formatı korur: HTML ve değişkenler bozulmadan kalır.
Toplu Çeviri İşlemcisi
enhanceTranslations.ts dosyasını oluşturun:
import fs from "fs";
import path from "path";
import pofile from "pofile";
import { translateWithLLM } from "./translateWithLLM";
const BATCH_SIZE = 30; // Her seferinde 30 metin çevir
const DELAY_MS = 1000; // Hız sınırlaması (Rate limiting)
export async function enhanceTranslations(
locale: string,
catalogPath: string
) {
const poPath = path.join(catalogPath, locale, "messages.po");
const po = pofile.parse(fs.readFileSync(poPath, "utf-8"));
// Çevrilmemiş öğeleri bul
const untranslated = po.items.filter(
(item) => item.msgid && (!item.msgstr || item.msgstr[0] === "")
);
if (untranslated.length === 0) {
console.log(`✓ ${locale}: All strings translated`);
return;
}
console.log(`Translating ${untranslated.length} strings for ${locale}...`);
// Gruplar (batch) halinde işle
for (let i = 0; i < untranslated.length; i += BATCH_SIZE) {
const batch = untranslated.slice(i, i + BATCH_SIZE);
const messages = batch.map((item) => ({
msgid: item.msgid,
msgstr: item.msgstr?.[0] ?? "",
}));
try {
const translations = await translateWithLLM(messages, locale);
// PO dosyasını güncelle
translations.forEach((translation, index) => {
const item = batch[index];
if (item) {
item.msgstr = [translation.msgstr];
}
});
console.log(` ${i + batch.length}/${untranslated.length} translated`);
// İlerlemeyi kaydet
fs.writeFileSync(poPath, po.toString());
// Hız sınırlaması
if (i + BATCH_SIZE < untranslated.length) {
await new Promise((resolve) => setTimeout(resolve, DELAY_MS));
}
} catch (error) {
console.error(` Error translating batch: ${error}`);
// Sonraki grupla devam et
}
}
console.log(`✓ ${locale}: Translation complete!`);
}
Toplu işleme (Batch processing) token limitlerini önler ve maliyetten tasarruf sağlar.
Çeviri Script'i
apps/nextjs/script/i18n.ts dosyasını oluşturun:
import { enhanceTranslations } from "@acme/i18n";
import { exec } from "child_process";
import { promisify } from "util";
const execAsync = promisify(exec);
const LOCALES = [
"zh_CN", "zh_TW", "ja", "ko", "de",
"fr", "es", "pt", "ar", "it", "ru"
];
async function main() {
// Adım 1: Koddan metinleri çıkar
console.log("📝 Extracting strings...");
await execAsync("pnpm run lingui:extract --clean");
// Adım 2: Eksik metinleri otomatik çevir
console.log("\n🤖 Translating with AI...");
const catalogPath = "./src/locales";
for (const locale of LOCALES) {
await enhanceTranslations(locale, catalogPath);
}
// Adım 3: TypeScript'e derle
console.log("\n⚡ Compiling catalogs...");
await execAsync("npx lingui compile --typescript");
console.log("\n✅ Done! All translations updated.");
}
main().catch(console.error);
package.json dosyasına ekleyin:
{
"scripts": {
"i18n": "tsx script/i18n.ts",
"lingui:extract": "lingui extract",
"lingui:compile": "lingui compile --typescript"
}
}
i18n Pipeline'ınızı Çalıştırma
# Hepsine hükmedecek tek bir komut
$ pnpm run i18n
📝 Extracting strings...
Catalog statistics for src/locales/{locale}/messages:
┌──────────┬─────────────┬─────────┐
│ Language │ Total count │ Missing │
├──────────┼─────────────┼─────────┤
│ en │ 847 │ 0 │
│ zh_CN │ 847 │ 123 │
│ ja │ 847 │ 89 │
└──────────┴─────────────┴─────────┘
🤖 Translating with AI...
Translating 123 strings for zh_CN...
30/123 translated
60/123 translated
90/123 translated
123/123 translated
✓ zh_CN: Translation complete!
⚡ Compiling catalogs...
✅ Done! All translations updated.
İşte bu kadar. Kodunuza yeni bir metin ekleyin, pnpm i18n çalıştırın, bum - 17 dile çevrildi.

Dil Değiştirme (Locale Switching)
UX kısmını unutmayın. İşte bir dil değiştirici:
"use client";
import { useLocaleSwitcher } from "@/hooks/useLocaleSwitcher";
import { useLocale } from "@/hooks/useLocale";
const LOCALES = {
en: "English",
zh_CN: "简体中文",
zh_TW: "繁體中文",
ja: "日本語",
ko: "한국어",
// ... vb
};
export function LocaleSelector() {
const currentLocale = useLocale();
const { switchLocale } = useLocaleSwitcher();
return (
<select
value={currentLocale}
onChange={(e) => switchLocale(e.target.value)}
>
{Object.entries(LOCALES).map(([code, name]) => (
<option key={code} value={code}>
{name}
</option>
))}
</select>
);
}
Hook implementasyonu:
// hooks/useLocaleSwitcher.tsx
"use client";
import { setUserLocale } from "@/utils/i18n/localeDetection";
export function useLocaleSwitcher() {
const switchLocale = (locale: string) => {
setUserLocale(locale);
window.location.reload(); // Dili uygulamak için zorla yenile
};
return { switchLocale };
}
Tercihi bir çerezde (cookie) saklayın:
// utils/i18n/localeDetection.ts
import { cookies } from "next/headers";
export function setUserLocale(locale: string) {
cookies().set("NEXT_LOCALE", locale, {
maxAge: 365 * 24 * 60 * 60, // 1 yıl
});
}
export function getLocale(): string {
const cookieStore = cookies();
return cookieStore.get("NEXT_LOCALE")?.value ?? "en";
}
İleri Seviye: Tip Güvenli (Type-Safe) Çeviriler
Tip güvenliği mi istiyorsunuz? Lingui arkanızda:
// Bunun yerine:
t`Hello ${name}`
// msg tanımlayıcısını kullanın:
import { msg } from "@lingui/core/macro";
const greeting = msg`Hello ${name}`;
const translated = i18n._(greeting);
IDE'niz çeviri anahtarlarını otomatik tamamlayacak. Muazzam.
Performans Değerlendirmeleri
1. Build Zamanında Derleme
Lingui çevirileri küçültülmüş (minified) JSON'a derler. Runtime'da ayrıştırma (parsing) yükü yoktur.
// Derlenmiş çıktı (minified):
export const messages = JSON.parse('{"ICt8/V":["视频"],"..."}');
2. Sunucu Kataloglarını Önceden Yükleme
Başlangıçta tüm katalogları bir kez yükleyin (yukarıdaki appRouterI18n.ts'e bakın). Her istekte dosya I/O işlemi olmaz.
3. İstemci Bundle Boyutu
İstemciye sadece aktif dili gönderin:
<LinguiClientProvider
locale={locale}
messages={allMessages[locale]} // Sadece tek bir dil
>
4. LLM Maliyet Optimizasyonu
- Toplu çeviriler: API çağrısı başına 30 metin
- Çevirileri önbelleğe alma: Değişmeyen metinleri tekrar çevirmeyin
- Daha ucuz modeller kullanma: Kritik olmayan diller için GPT-4o-mini
Bizim maliyetimiz? 800+ metin × 16 dil için ~$2-3. İnsan çevirmenlere kıyasla çerez parası.
Tam Teknoloji Yığını Entegrasyonu
Bunun T3 Turbo'nun geri kalanıyla nasıl çalıştığına bakalım:
i18n ile tRPC
// server/api/routers/user.ts
import { createTRPCRouter, publicProcedure } from "../trpc";
import { msg } from "@lingui/core/macro";
export const userRouter = createTRPCRouter({
subscribe: publicProcedure
.mutation(async ({ ctx }) => {
// Hatalar da çevrilebilir!
if (!ctx.session?.user) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: ctx.i18n._(msg`You must be logged in`),
});
}
// ... abonelik mantığı
}),
});
i18n örneğini context üzerinden geçirin:
// server/api/trpc.ts
import { getI18nInstance } from "@/utils/i18n/appRouterI18n";
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
const locale = getLocale();
const i18n = getI18nInstance(locale);
return {
session: await getServerAuthSession(),
i18n,
locale,
};
};
Drizzle ile Veritabanı
Kullanıcı dil tercihini saklayın:
// packages/db/schema/user.ts
import { pgTable, text, varchar } from "drizzle-orm/pg-core";
export const users = pgTable("user", {
id: varchar("id", { length: 255 }).primaryKey(),
locale: varchar("locale", { length: 10 }).default("en"),
// ... diğer alanlar
});
AI SDK Entegrasyonu
AI yanıtlarını anında çevirin:
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { useLingui } from "@lingui/react/macro";
export function useAIChat() {
const { i18n } = useLingui();
const chat = async (prompt: string) => {
const systemPrompt = i18n._(msg`You are a helpful AI assistant for acme.`);
return generateText({
model: openai("gpt-4"),
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: prompt },
],
});
};
return { chat };
}
Öğrendiğimiz En İyi Uygulamalar (Best Practices)
1. Her Zaman Makro Kullanın
// ❌ Kötü: Runtime çevirisi (çıkarılmaz/extract edilmez)
const text = t("Hello world");
// ✅ İyi: Makro (build zamanında çıkarılır)
const text = t`Hello world`;
2. Bağlam Her Şeydir
Çevirmenler (veya AI) için yorumlar ekleyin:
// i18n: This appears in the pricing table header
<Trans>Monthly</Trans>
// i18n: Button to submit payment form
<button>{t`Subscribe Now`}</button>
Lingui bunları çevirmen notları olarak ayıklar.
3. Çoğulları Düzgün Yönetin
import { Plural } from "@lingui/react/macro";
<Plural
value={count}
one="# credit remaining"
other="# credits remaining"
/>
Farklı dillerin farklı çoğul kuralları vardır. Lingui bunu halleder.
4. Tarih/Sayı Formatlama
Intl API'larını kullanın:
const date = new Intl.DateTimeFormat(locale, {
dateStyle: "long",
}).format(new Date());
const price = new Intl.NumberFormat(locale, {
style: "currency",
currency: "USD",
}).format(29.99);
5. RTL Desteği
Arapça için yönü (direction) yönetin:
export default function RootLayout({ children }) {
const locale = getLocale();
const direction = locale === "ar" ? "rtl" : "ltr";
return (
<html lang={locale} dir={direction}>
<body>{children}</body>
</html>
);
}
Tailwind konfigürasyonuna ekleyin:
module.exports = {
plugins: [
require('tailwindcss-rtl'),
],
};
Yönsel sınıfları kullanın:
<div className="ms-4"> {/* margin-start, hem LTR hem RTL için çalışır */}
Deployment Kontrol Listesi
Ship etmeden önce:
- Tüm çevirilerin güncel olduğundan emin olmak için
pnpm i18nçalıştırın - Production modunda her dili test edin
- Dil çerezinin (cookie) kalıcılığını doğrulayın
- Arapça için RTL düzenini kontrol edin
- Dil değiştirici UX'ini test edin
- SEO için hreflang etiketlerini ekleyin
- Gerekirse dile dayalı yönlendirmeyi (routing) ayarlayın
- LLM çeviri maliyetlerini izleyin
Sonuçlar
Bu sistemi uyguladıktan sonra:
- 17 dil desteği kutudan çıktığı gibi
- ~850 metin otomatik olarak çevrildi
- Tam çeviri için $2-3 toplam maliyet
- Yeni metinler eklendiğinde 2 dakikalık güncelleme döngüsü
- Sıfır manuel çeviri işi
- Bağlam duyarlı, yüksek kaliteli çeviriler
Şununla karşılaştırın:
- İnsan çevirmenler: Kelime başına $0.10-0.30 = $1,000+
- Geleneksel servisler: Hala pahalı, hala yavaş
- Manuel iş: Ölçeklenemez
Bu Neden 2026'da Önemli?
Bakın, web global bir yer. Eğer 2026'da sadece İngilizce ship ediyorsanız, dünyanın %90'ını geride bırakıyorsunuz demektir.
Ama geleneksel i18n tam bir çile. Bu yaklaşım işi çocuk oyuncağına çeviriyor:
- Trans/t makrolarıyla kod yazın (2 saniye sürer)
pnpm i18nçalıştırın (otomatik)- Dünyaya ship edin (kazanç)
Lingui'nin geliştirici deneyimi + LLM destekli çevirilerin kombinasyonu oyunun kurallarını değiştiriyor. Şunlara sahip oluyorsunuz:
- Tip güvenli çeviriler
- Sıfır runtime yükü
- Otomatik çıkarma (extraction)
- Bağlam duyarlı AI çevirileri
- Dil başına kuruş maliyet
- Sonsuz ölçeklenebilirlik
Daha İleri Gitmek
Seviye atlamak mı istiyorsunuz? Şunları deneyin:
Dinamik İçerik Çevirisi
Çevirileri veritabanınızda saklayın:
// packages/db/schema/content.ts
export const blogPosts = pgTable("blog_post", {
id: varchar("id", { length: 255 }).primaryKey(),
titleEn: text("title_en"),
titleZhCn: text("title_zh_cn"),
titleJa: text("title_ja"),
// ... vb
});
Kaydederken otomatik çevirin:
import { translateWithLLM } from "@acme/i18n";
export const blogRouter = createTRPCRouter({
create: protectedProcedure
.input(z.object({ title: z.string() }))
.mutation(async ({ input }) => {
// Tüm dillere çevir
const translations = await Promise.all(
LOCALES.map(async (locale) => {
const result = await translateWithLLM(
[{ msgid: input.title, msgstr: "" }],
locale
);
return [locale, result[0].msgstr];
})
);
await db.insert(blogPosts).values({
id: generateId(),
titleEn: input.title,
...Object.fromEntries(translations),
});
}),
});
Kullanıcı Tarafından Sağlanan Çeviriler
Kullanıcıların daha iyi çeviriler önermesine izin verin:
export const i18nRouter = createTRPCRouter({
suggestTranslation: publicProcedure
.input(z.object({
msgid: z.string(),
locale: z.string(),
suggestion: z.string(),
}))
.mutation(async ({ input }) => {
await db.insert(translationSuggestions).values(input);
// Bakım yapanları (maintainers) bilgilendir
await sendEmail({
to: "i18n@acme.com",
subject: `New translation suggestion for ${input.locale}`,
body: `"${input.msgid}" → "${input.suggestion}"`,
});
}),
});
Çevirileri A/B Testi Yapmak
Hangi çevirilerin daha iyi dönüşüm sağladığını test edin:
const variant = await abTest.getVariant("pricing-cta", locale);
const ctaText = variant === "A"
? t`Start Your Free Trial`
: t`Try acme Free`;
Kod
Bunların hepsi gerçek bir uygulamadan alınan production kodlarıdır. Tam implementasyon monorepo'muzda:
t3-acme-app/
├── apps/nextjs/
│ ├── lingui.config.ts
│ ├── src/
│ │ ├── locales/ # Derlenmiş kataloglar
│ │ ├── utils/i18n/ # i18n araçları
│ │ └── providers/ # LinguiClientProvider
│ └── script/i18n.ts # Çeviri script'i
└── packages/i18n/
└── src/
├── translateWithLLM.ts
├── enhanceTranslations.ts
└── utils.ts
Son Düşünceler
2026'da çok dilli bir AI uygulaması geliştirmek artık zor değil. Araçlar burada:
- Çıkarma ve runtime için Lingui
- Bağlam duyarlı çeviri için Claude/GPT
- Piyasadaki en iyi DX için T3 Turbo
Çeviriler için binlerce dolar ödemeyi bırakın. Uygulamanızı İngilizce ile sınırlamayı bırakın.
Global inşa edin. Hızlı ship edin. AI kullanın.
2026'da işleri böyle hallediyoruz.
Sorular? Sorunlar? Beni Twitter'da bulun veya Lingui dokümanlarına ve AI SDK dokümanlarına göz atın.
Şimdi gidin ve o çok dilli uygulamayı ship edin. Dünya sizi bekliyor.
Bunu paylaş

Feng Liu
shenjian8628@gmail.com