كيف تبني تطبيق ويب حديث مدعوم بالذكاء الاصطناعي ومتعدد اللغات لعام 2026
دليل شامل لبناء تطبيقات ويب متعددة اللغات باستخدام Lingui والترجمة بالذكاء الاصطناعي. ادعم 17 لغة تلقائياً باستخدام Next.js و Claude و T3 Turbo.

اسمعوني جيداً، علينا الحديث عن التدويل (i18n) في عام 2026.
معظم الشروحات والدروس ستخبرك أن تقوم بترجمة النصوص يدوياً، أو توظيف مترجمين، أو استخدام واجهة برمجة تطبيقات (API) ركيكة من ترجمة Google. ولكن إليك الحقيقة: أنت تعيش في عصر Claude Sonnet 4.5. لماذا لا تزال تترجم وكأننا في عام 2019؟
سأريكم كيف قمنا ببناء تطبيق ويب جاهز للإنتاج يتحدث 17 لغة بطلاقة، باستخدام معمارية تدويل (i18n) مكونة من جزأين منطقيين للغاية:
- Lingui للاستخراج، التجميع (compilation)، وسحر وقت التشغيل (runtime).
- حزمة i18n مخصصة مدعومة بالنماذج اللغوية الكبيرة (LLMs) لترجمات آلية واعية بالسياق.
ما هي حزمتنا التقنية (Stack)؟ Create T3 Turbo مع Next.js، وtRPC، وDrizzle، وPostgres، وTailwind، وAI SDK. إذا لم تكن تستخدم هذه الأدوات في 2026، فنحن بحاجة لإجراء محادثة مختلفة تماماً.
لنبدأ البناء.
المشكلة مع التدويل (i18n) التقليدي
سير العمل التقليدي للتدويل يبدو هكذا:
# استخراج النصوص
$ lingui extract
# ؟؟؟ الحصول على الترجمات بطريقة ما ؟؟؟
# (توظيف مترجمين، استخدام خدمات مشبوهة، البكاء في الزاوية)
# التجميع (Compile)
$ lingui compile
تلك الخطوة في المنتصف؟ إنها كابوس حقيقي. أنت إما:
- تدفع مبالغ طائلة للمترجمين البشر (بطيء ومكلف).
- تستخدم واجهات ترجمة بدائية (عمياء عن السياق، وتبدو آلية).
- تترجم يدوياً (غير قابل للتوسع).
نحن نقوم بذلك بشكل أفضل.
المعمارية المكونة من جزأين
إليك إعدادنا:
┌─────────────────────────────────────────────┐
│ Next.js App (Lingui Integration) │
│ ├─ Extract strings with macros │
│ ├─ Trans/t components in your code │
│ └─ Runtime i18n with compiled catalogs │
└─────────────────────────────────────────────┘
↓ generates .po files
┌─────────────────────────────────────────────┐
│ @acme/i18n Package (LLM Translation) │
│ ├─ Reads .po files │
│ ├─ Batch translates with Claude/GPT-5 │
│ ├─ Context-aware, product-specific │
│ └─ Writes translated .po files │
└─────────────────────────────────────────────┘
↓ compiles to TypeScript
┌─────────────────────────────────────────────┐
│ Compiled Message Catalogs │
│ └─ Fast, type-safe runtime translations │
└─────────────────────────────────────────────┘
الجزء 1 (Lingui) يتولى تجربة المطور. الجزء 2 (حزمة i18n المخصصة) يتولى سحر الترجمة.
دعونا نتعمق في كل جزء.

الجزء 1: إعداد Lingui في Next.js
التثبيت (Installation)
في الـ monorepo الخاص بـ T3 Turbo:
# In apps/nextjs
pnpm add @lingui/core @lingui/react @lingui/macro
pnpm add -D @lingui/cli @lingui/swc-plugin
إعداد Lingui
أنشئ ملف apps/nextjs/lingui.config.ts:
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;
17 لغة جاهزة للاستخدام فوراً. ولمَ لا؟
التكامل مع Next.js
قم بتحديث next.config.js لاستخدام إضافة SWC الخاصة بـ Lingui:
const linguiConfig = require("./lingui.config");
module.exports = {
experimental: {
swcPlugins: [
[
"@lingui/swc-plugin",
{
// This makes your builds faster
// هذا يجعل عمليات البناء أسرع
},
],
],
},
// ... rest of your config
};
الإعداد من جانب الخادم (Server-Side Setup)
أنشئ src/utils/i18n/appRouterI18n.ts:
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>>();
// Pre-create i18n instances for all locales
// إنشاء مثيلات i18n مسبقاً لجميع اللغات
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")!;
}
لماذا؟ مكونات الخادم (Server Components) لا تدعم React Context. هذا يمنحك ترجمات من جانب الخادم.
المزود من جانب العميل (Client-Side Provider)
أنشئ src/providers/LinguiClientProvider.tsx:
"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>;
}
قم بتغليف تطبيقك في layout.tsx:
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>
);
}
استخدام الترجمات في الكود الخاص بك
في مكونات الخادم (Server Components):
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 Components):
"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>
{/* With variables */}
{/* مع متغيرات */}
<p>{t`${credits} credits remaining`}</p>
</div>
);
}
صيغة الماكرو (macro syntax) هي المفتاح. يقوم Lingui باستخراج هذه النصوص في وقت البناء (build time).
الجزء 2: حزمة الترجمة المدعومة بالذكاء الاصطناعي
هنا تبدأ الإثارة الحقيقية.
هيكل الحزمة (Package Structure)
أنشئ packages/i18n/:
packages/i18n/
├── package.json
├── src/
│ ├── translateWithLLM.ts # Core LLM translation
│ ├── enhanceTranslations.ts # Batch processor
│ └── utils.ts # Helpers
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
إليكم الخلطة السرية - 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, // Lower = more consistent
});
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",
// ... etc
};
return names[locale] ?? locale;
}
لماذا ينجح هذا:
- واعٍ بالسياق (Context-aware): النموذج يعرف ما هو "acme".
- مخرجات منظمة (Structured output): يضمن مخطط Zod أن يكون الـ JSON صالحاً.
- حرارة منخفضة (Low temperature): ترجمات متسقة.
- يحافظ على التنسيق: تبقى وسوم HTML والمتغيرات كما هي.
معالج الترجمة بالدفعات (Batch Processor)
أنشئ enhanceTranslations.ts:
import fs from "fs";
import path from "path";
import pofile from "pofile";
import { translateWithLLM } from "./translateWithLLM";
const BATCH_SIZE = 30; // Translate 30 strings at a time
const DELAY_MS = 1000; // 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"));
// Find untranslated items
// العثور على العناصر غير المترجمة
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}...`);
// Process in batches
// المعالجة على دفعات
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);
// Update PO file
// تحديث ملف PO
translations.forEach((translation, index) => {
const item = batch[index];
if (item) {
item.msgstr = [translation.msgstr];
}
});
console.log(` ${i + batch.length}/${untranslated.length} translated`);
// Save progress
// حفظ التقدم
fs.writeFileSync(poPath, po.toString());
// Rate limiting
// تحديد المعدل
if (i + BATCH_SIZE < untranslated.length) {
await new Promise((resolve) => setTimeout(resolve, DELAY_MS));
}
} catch (error) {
console.error(` Error translating batch: ${error}`);
// Continue with next batch
}
}
console.log(`✓ ${locale}: Translation complete!`);
}
المعالجة بالدفعات تمنع تجاوز حدود التوكن (token limits) وتوفر التكاليف.
سكربت الترجمة
أنشئ apps/nextjs/script/i18n.ts:
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() {
// Step 1: Extract strings from code
// الخطوة 1: استخراج النصوص من الكود
console.log("📝 Extracting strings...");
await execAsync("pnpm run lingui:extract --clean");
// Step 2: Auto-translate missing strings
// الخطوة 2: الترجمة التلقائية للنصوص المفقودة
console.log("\n🤖 Translating with AI...");
const catalogPath = "./src/locales";
for (const locale of LOCALES) {
await enhanceTranslations(locale, catalogPath);
}
// Step 3: Compile to TypeScript
// الخطوة 3: التجميع إلى TypeScript
console.log("\n⚡ Compiling catalogs...");
await execAsync("npx lingui compile --typescript");
console.log("\n✅ Done! All translations updated.");
}
main().catch(console.error);
أضف إلى package.json:
{
"scripts": {
"i18n": "tsx script/i18n.ts",
"lingui:extract": "lingui extract",
"lingui:compile": "lingui compile --typescript"
}
}
تشغيل خط أنابيب التدويل (i18n Pipeline)
# One command to rule them all
# أمر واحد للتحكم في كل شيء
$ 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.
هذا كل شيء. أضف نصاً جديداً في الكود، شغّل pnpm i18n، وبوم - تمت الترجمة إلى 17 لغة.

تبديل اللغة (Locale Switching)
لا تنسَ تجربة المستخدم (UX). إليك مبدل اللغة:
"use client";
import { useLocaleSwitcher } from "@/hooks/useLocaleSwitcher";
import { useLocale } from "@/hooks/useLocale";
const LOCALES = {
en: "English",
zh_CN: "简体中文",
zh_TW: "繁體中文",
ja: "日本語",
ko: "한국어",
// ... etc
};
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:
// hooks/useLocaleSwitcher.tsx
"use client";
import { setUserLocale } from "@/utils/i18n/localeDetection";
export function useLocaleSwitcher() {
const switchLocale = (locale: string) => {
setUserLocale(locale);
window.location.reload(); // Force reload to apply locale
};
return { switchLocale };
}
تخزين التفضيل في ملف تعريف الارتباط (cookie):
// 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 year
});
}
export function getLocale(): string {
const cookieStore = cookies();
return cookieStore.get("NEXT_LOCALE")?.value ?? "en";
}
متقدم: ترجمات آمنة النوع (Type-Safe)
هل تريد أماناً في الأنواع (Type safety)؟ Lingui يوفر لك ذلك:
// Instead of this:
// بدلاً من هذا:
t`Hello ${name}`
// Use msg descriptor:
// استخدم واصف msg:
import { msg } from "@lingui/core/macro";
const greeting = msg`Hello ${name}`;
const translated = i18n._(greeting);
سيقوم محررك البرمجي (IDE) بالإكمال التلقائي لمفاتيح الترجمة. شيء جميل.
اعتبارات الأداء
1. التجميع في وقت البناء (Compile at Build Time)
يقوم Lingui بتجميع الترجمات إلى JSON مصغر. لا يوجد عبء تحليل (parsing) في وقت التشغيل.
// Compiled output (minified):
export const messages = JSON.parse('{"ICt8/V":["视频"],"..."}');
2. التحميل المسبق لكتالوجات الخادم
قم بتحميل جميع الكتالوجات مرة واحدة عند بدء التشغيل (انظر appRouterI18n.ts أعلاه). لا توجد عمليات إدخال/إخراج للملفات (File I/O) مع كل طلب.
3. حجم حزمة العميل (Client Bundle Size)
أرسل فقط اللغة النشطة إلى العميل:
<LinguiClientProvider
locale={locale}
messages={allMessages[locale]} // Only one locale
>
4. تحسين تكلفة LLM
- ترجمات بالدفعات: 30 نصاً لكل استدعاء API.
- تخزين الترجمات مؤقتاً: لا تقم بإعادة ترجمة النصوص غير المتغيرة.
- استخدام نماذج أرخص: GPT-4o-mini للغات غير الحرجة.
تكلفتنا؟ حوالي 2-3 دولار لأكثر من 800 نص × 16 لغة. تكلفة زهيدة جداً مقارنة بالمترجمين البشر.
التكامل الكامل مع الحزمة التقنية
لنرى كيف يعمل هذا مع بقية T3 Turbo:
tRPC مع i18n
// 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 }) => {
// Errors can be translated too!
// يمكن ترجمة الأخطاء أيضاً!
if (!ctx.session?.user) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: ctx.i18n._(msg`You must be logged in`),
});
}
// ... subscription logic
}),
});
تمرير مثيل i18n عبر السياق (context):
// 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
تخزين تفضيل لغة المستخدم:
// 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"),
// ... other fields
});
تكامل AI SDK
ترجمة ردود الذكاء الاصطناعي فورياً:
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 };
}
أفضل الممارسات التي تعلمناها
1. استخدم الماكرو (Macros) دائماً
// ❌ Bad: Runtime translation (not extracted)
// ❌ سيء: ترجمة وقت التشغيل (لا يتم استخراجها)
const text = t("Hello world");
// ✅ Good: Macro (extracted at build time)
// ✅ جيد: ماكرو (يتم استخراجه في وقت البناء)
const text = t`Hello world`;
2. السياق هو كل شيء
أضف تعليقات للمترجمين (أو للذكاء الاصطناعي):
// i18n: This appears in the pricing table header
<Trans>Monthly</Trans>
// i18n: Button to submit payment form
<button>{t`Subscribe Now`}</button>
يقوم Lingui باستخراج هذه كملاحظات للمترجم.
3. التعامل مع صيغ الجمع بشكل صحيح
import { Plural } from "@lingui/react/macro";
<Plural
value={count}
one="# credit remaining"
other="# credits remaining"
/>
اللغات المختلفة لها قواعد جمع مختلفة. Lingui يتولى ذلك.
4. تنسيق التاريخ/الأرقام
استخدم واجهات برمجة تطبيقات Intl:
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 (من اليمين لليسار)
بالنسبة للغة العربية، يجب التعامل مع الاتجاه:
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:
module.exports = {
plugins: [
require('tailwindcss-rtl'),
],
};
استخدم فئات الاتجاه (directional classes):
<div className="ms-4"> {/* margin-start, works for both LTR/RTL */}
قائمة التحقق قبل النشر (Deployment Checklist)
قبل أن تطلق التطبيق:
- شغّل
pnpm i18nللتأكد من تحديث جميع الترجمات - اختبر كل لغة في وضع الإنتاج (production mode)
- تحقق من استمرار ملف تعريف الارتباط (cookie) الخاص باللغة
- تحقق من تخطيط RTL للغة العربية
- اختبر تجربة مستخدم مبدل اللغة
- أضف وسوم hreflang لتحسين محركات البحث (SEO)
- قم بإعداد التوجيه المستند إلى اللغة (locale-based routing) إذا لزم الأمر
- راقب تكاليف ترجمة LLM
النتائج
بعد تنفيذ هذا النظام:
- 17 لغة مدعومة بشكل جاهز
- ~850 نصاً تمت ترجمتها تلقائياً
- 2-3 دولار التكلفة الإجمالية للترجمة الكاملة
- دورة تحديث لمدة دقيقتين عند إضافة نصوص جديدة
- صفر عمل يدوي في الترجمة
- ترجمات عالية الجودة وواعية بالسياق
قارن ذلك بـ:
- المترجمين البشر: 0.10-0.30 دولار لكل كلمة = +1,000 دولار
- الخدمات التقليدية: لا تزال باهظة الثمن، ولا تزال بطيئة
- العمل اليدوي: لا يمكن توسيعه
لماذا يهم هذا في عام 2026
اسمع، الويب عالمي. إذا كنت تطلق تطبيقك باللغة الإنجليزية فقط في عام 2026، فأنت تتجاهل 90% من العالم.
لكن التدويل (i18n) التقليدي مؤلم. هذا النهج يجعله تافهاً:
- اكتب الكود باستخدام ماكرو Trans/t (يستغرق ثانيتين)
- شغّل
pnpm i18n(مؤتمت) - أطلق للعالم (واربح)
الجمع بين تجربة مطور Lingui + الترجمات المدعومة بـ LLM يغير قواعد اللعبة. ستحصل على:
- ترجمات آمنة النوع (Type-safe)
- وقت تشغيل بدون عبء إضافي (Zero-overhead)
- استخراج تلقائي
- ترجمات ذكاء اصطناعي واعية بالسياق
- تكلفة زهيدة لكل لغة
- قابلية للتوسع بلا حدود
الذهاب لأبعد من ذلك
هل تريد الارتقاء بالمستوى؟ جرب:
ترجمة المحتوى الديناميكي
قم بتخزين الترجمات في قاعدة البيانات الخاصة بك:
// 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"),
// ... etc
});
ترجمة تلقائية عند الحفظ:
import { translateWithLLM } from "@acme/i18n";
export const blogRouter = createTRPCRouter({
create: protectedProcedure
.input(z.object({ title: z.string() }))
.mutation(async ({ input }) => {
// Translate to all languages
// الترجمة لجميع اللغات
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),
});
}),
});
ترجمات مقدمة من المستخدمين
اسمح للمستخدمين بتقديم ترجمات أفضل:
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);
// Notify maintainers
// إشعار المشرفين
await sendEmail({
to: "i18n@acme.com",
subject: `New translation suggestion for ${input.locale}`,
body: `"${input.msgid}" → "${input.suggestion}"`,
});
}),
});
اختبار A/B للترجمات
اختبر أي الترجمات تحقق تحويلاً أفضل:
const variant = await abTest.getVariant("pricing-cta", locale);
const ctaText = variant === "A"
? t`Start Your Free Trial`
: t`Try acme Free`;
الكود
كل هذا كود إنتاج من تطبيق حقيقي. التنفيذ الكامل موجود في الـ monorepo الخاص بنا:
t3-acme-app/
├── apps/nextjs/
│ ├── lingui.config.ts
│ ├── src/
│ │ ├── locales/ # Compiled catalogs
│ │ ├── utils/i18n/ # i18n utilities
│ │ └── providers/ # LinguiClientProvider
│ └── script/i18n.ts # Translation script
└── packages/i18n/
└── src/
├── translateWithLLM.ts
├── enhanceTranslations.ts
└── utils.ts
أفكار أخيرة
بناء تطبيق ذكاء اصطناعي متعدد اللغات في عام 2026 لم يعد صعباً. الأدوات موجودة:
- Lingui للاستخراج ووقت التشغيل.
- Claude/GPT للترجمة الواعية بالسياق.
- T3 Turbo لأفضل تجربة مطور (DX) في الساحة.
توقف عن دفع الآلاف للترجمات. توقف عن حصر تطبيقك في اللغة الإنجليزية.
ابنِ عالمياً. أطلق بسرعة. استخدم الذكاء الاصطناعي.
هكذا نفعلها في 2026.
أسئلة؟ مشاكل؟ تجدني على Twitter أو تفقد وثائق Lingui و وثائق AI SDK.
الآن انطلق وأطلق ذلك التطبيق متعدد اللغات. العالم في الانتظار.
شارك هذا

Feng Liu
shenjian8628@gmail.com