استخدم مساعدك المفضل للملخص واستخدم هذه الصفحة والموفر AI الذي تريده
تاريخ الإصدارات
- "النسخة الأولية"v9.5.1026/9/2026
تمت ترجمة محتوى هذه الصفحة باستخدام الذكاء الاصطناعي.
اعرض آخر نسخة المحتوى الأصلي باللغة الإنكليزيةإذا كان لديك فكرة لتحسين هذه الوثيقة، فلا تتردد في المساهمة من خلال تقديم طلب سحب على GitHub.
رابط GitHub للتوثيقنسخ الـ Markdown من المستند إلى الحافظة
كيفية تدويل تطبيق TanStack Start الخاص بك باستخدام Paraglide JS في عام 2026
جدول المحتويات
ما هو Paraglide JS؟
Paraglide JS (من inlang) هي مكتبة تدويل (i18n) معتمدة على المترجم (compiler-based). بدلاً من شحن بيئة تشغيل runtime تبحث عن المفاتيح في كائن JSON، تقوم بترجمة كل رسالة إلى دالة JavaScript ذات أنواع محددة (m.about_title()). يمكن لجامع الحزم (bundler) حذف الرسائل غير المستخدمة، وأي خطأ إملائي في المفتاح يصبح خطأ في مرحلة الترجمة (compile error).
تعتبر Paraglide نهج التدويل المستخدم في أمثلة TanStack Router الرسمية، وتتكامل مع TanStack Start من خلال ثلاثة أجزاء:
- إضافة Vite تقوم بتجميع الرسائل وبيئة التشغيل في
src/paraglide؛ - برمجية وسيطة للخادم (server middleware) تحدد لغة (locale) كل طلب؛
- إعادة كتابة الموجه (router rewrite) التي تطابق عناوين URL المترجمة (
/fr/about) مع شجرة المسارات الخاصة بك (/about)، بحيث لا تحتاج إلى مقطع$locale.
يقوم هذا الدليل بإعداد هذه الأجزاء الثلاثة، ثم يغطي كل ما تتركه Paraglide لك: lang و dir، ومبدل اللغة، والبيانات الوصفية المترجمة، و canonical، و hreflang مع x-default، و Open Graph، و JSON-LD، وخريطة الموقع sitemap، و robots.txt، والعرض المسبق (pre-rendering) وصفحات 404 المترجمة.
هل تبحث عن حزمة تقنية أخرى؟ راجع دليل TanStack Start + use-intl، أو دليل TanStack Start + Lingui، أو دليل TanStack Start + Intlayer.
هل تقارن بين النهجين المعتمدين على المترجم؟ اقرأ هل Intlayer أخف من Paraglide؟.
ماذا تقول المقارنة المعيارية (Benchmark) عن Paraglide على TanStack Start
يقوم اختبار الأداء للتدويل بتشغيل نفس تطبيق TanStack Start المكون من 10 صفحات و 10 لغات مع كل مكتبة رئيسية ويقيس ما يقوم المتصفح بتنزيله بالفعل.
تحميل JSON الديناميكي
تحميل الترجمات ببطء في وقت التشغيل
JSON المحدد (أسماء المحيط)
مساحات أسماء الترجمة لكل صفحة
مقياس أداء I18n
ما هو هذا المقياس؟
الحجم الإجمالي المضغوط بتنسيق gzip لحزمة مكتبة التدويل. وهي تتضمن فقط المزود ومنطق استرداد المحتوى بعد تقليل الحجم (tree-shaking) والضغط (minification).
لماذا هو مهم؟
يقلل حجم المكتبة الأصغر من حمولة JavaScript الأولية، مما يؤدي إلى سرعة التنزيل وأوقات التنفيذ على العميل.
عرض كـ
الأرقام الرئيسية لـ @inlang/paraglide-js@2.15.1، تم قياسها في 2026-09-26 (gzip):
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
| الإعداد | حجم المكتبة | JS لكل صفحة | تسرب اللغات الأخرى | تسرب الصفحات الأخرى | تحميل الصفحة |
|---|---|---|---|---|---|
| بدون تدويل (التطبيق الأساسي) | - | 111.0 KB | 0% | 0% | 15.7 ms |
| Paraglide JS | 1.8 KB | 125.1 KB | 49.7% | 0% | 22.1 ms |
react-intlayer | 4.5 KB | 126.8 KB | 0% | 0% | 14.8 ms |
use-intl | 75.9 KB | 128.7 KB | 0% | 0% | 17.4 ms |
| Lingui | 56.7 KB | 120.2 KB | 8.6% | 0% | 21.9 ms |
النقاط المستفادة:
- بيئة التشغيل صغيرة للغاية، والصفحات لا تسرب بيانات. يتم إنشاء بيئة التشغيل وفقا لإعداداتك، ويتم استيراد الرسائل فقط عند استخدامها.
- تسرب اللغات الأخرى. تحتوي كل دالة رسالة على جميع اللغات، وبالتالي فإن حوالي نصف النصوص المترجمة المشحونة إلى الصفحة تكون بلغات لا يستخدمها الزائر. كلما أضفت المزيد من اللغات، زادت هذه النسبة.
- تحميل الصفحة هو الأبطأ في المجموعة، ويرجع ذلك جزئيا إلى أن تحديد اللغة يتم من خلال استراتيجيات عند كل استدعاء بدلا من قراءتها من سياق React context.
اطلع على البيانات الكاملة: تقرير مقارنة أداء TanStack Start، ومستودع المقارنة المعيارية.
مقارنة الميزات على TanStack Start
كيف تقارن Paraglide JS مع المكتبات الأخرى الشائعة الاستخدام في TanStack Start:
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
| الميزة | react-intlayer (Intlayer) | use-intl | Paraglide JS | Lingui |
|---|---|---|---|---|
| الترجمات بجانب المكونات | ✅ في نفس المكان (Co-located) | ❌ ملف JSON مركزي | ❌ ملف JSON واحد لكل لغة | ⚠️ النص المصدر داخل المكونات |
| تكامل TypeScript | ✅ أنواع منشأة تلقائيا | ✅ عبر AppConfig | ✅ دوال رسائل ذات أنواع محددة | ⚠️ ماكرو فقط |
| اكتشاف الترجمات المفقودة | ✅ أخطاء في الأنواع وتحذيرات بناء | ⚠️ بديل أثناء التشغيل | ⚠️ الرجوع للغة الأساسية | ⚠️ الرجوع للنص المصدر |
| المحتوى الغني (JSX، Markdown) | ✅ دعم مباشر | ⚠️ وسوم عبر t.rich | ⚠️ نصوص فقط | ✅ JSX داخل <Trans> |
| توجيه مترجم (Localized routing) | ✅ مدمج | ❌ يدوي {-$locale} | ✅ urlPatterns + إعادة كتابة الموجه | ❌ يدوي {-$locale} |
| تبديل اللغة بدون إعادة تحميل | ✅ نعم | ✅ نعم | ❌ إعادة تحميل كاملة للصفحة | ✅ نعم |
| صيغ الجمع (Pluralization) | ✅ معتمد على التعداد | ✅ ICU | ✅ متغيرات (Variants) | ✅ ICU |
| ICU MessageFormat | ✅ عبر format: "icu" | ✅ أصلي | ⚠️ عبر إضافة inlang | ✅ أصلي |
| صيغ المحتوى | ✅ .ts، .json، .md، .yaml... | ⚠️ .json | ⚠️ inlang JSON | ✅ PO، JSON، CSV |
| الترجمة بالذكاء الاصطناعي | ✅ المزود والمفتاح الخاص بك | ❌ لا | ❌ لا | ❌ لا |
| محرر مرئي / CMS | ✅ محرر محلي + CMS اختياري | ❌ منصات خارجية | ⚠️ تطبيقات منظومة inlang | ❌ منصات خارجية |
| مساعدات SEO (hreflang، sitemap) | ✅ مدمجة | ❌ يدوي | ⚠️ عناوين URL مترجمة، والباقي يدوي | ❌ يدوي |
| حجم وقت التشغيل (gzip، benchmark) | 4.5 KB | 75.9 KB | 1.8 KB | 56.7 KB |
| التسرب، أفضل إعداد (لغة / صفحة) | 0% / 0% | 0% / 0% | 49.7% / 0% | 8.6% / 0% |
| الترجمات المفقودة في CI | ✅ npx intlayer test | ⚠️ غير مدمج | ⚠️ غير مدمج | ✅ lingui compile --strict |
أرقام حجم وقت التشغيل والتسرب مأخوذة من مقارنة أداء TanStack Start. يتم قياس التسرب في أفضل إعداد لكل مكتبة.
أدلة TanStack Start الأخرى: Lingui، و use-intl، و Intlayer.
الممارسات التي يجب اتباعها
- تعيين
langوdirعلى<html>من اللغة المحددة على الخادم. - الحفاظ على عنوان URL واحد لكل لغة باستخدام استراتيجية البادئة (
/fr/about)، حتى تكون كل نسخة لغوية قابلة للفهرسة. - وضع
urlأولا في استراتيجية اللغة الخاصة بك، ليكون عنوان URL هو مصدر الحقيقة، وتحصل محركات البحث على الصفحة المطلوبة بدقة. - استخدام مفاتيح رسائل مسطحة وواضحة (
about_title) تطابق بوضوح أسماء الدوال. - تضمين ملفات
messages/*.jsonفي Git، وليس مجلدsrc/paraglideالمنشأ، لتجنب تعارضات الدمج (merge conflicts) في الملفات المنشأة تلقائيا. - ترجمة البيانات الوصفية الخاصة بك، والإعلان عن
canonicalوhreflangوx-defaultفي كل صفحة. - إنشاء خريطة موقع sitemap وملف robots.txt متعددي اللغات، والعرض المسبق (pre-rendering) لكل اللغات.
- استخدام روابط حقيقية لمبدل اللغة، حتى تكتشف محركات البحث جميع اللغات.
راجع دليلنا حول التدويل وتحسين محركات البحث (SEO) ودليل hreflang.
دليل خطوة بخطوة لإعداد Paraglide JS في تطبيق TanStack Start
إليك هيكل المشروع الذي سنقوم بإنشائه:
نسخ الكود إلى الحافظة
لاحظ أنه لا يوجد مجلد $locale: فعملية إعادة كتابة الموجه تزيل البادئة قبل مطابقة المسار.
تثبيت الاعتماديات
ابدأ من مشروع TanStack Start، ثم قم بتهيئة Paraglide. ينشئ أمر التهيئة ملف
project.inlang/settings.json، وأول ملفmessages/en.json، ويقوم بتثبيت الحزمة.bashنسخ الكودنسخ الكود إلى الحافظة
- @inlang/paraglide-js: المترجم وإضافة Vite الخاصة به. لا توجد حزمة بيئة تشغيل لتثبيتها: يتم إنشاء بيئة التشغيل مباشرة داخل مشروعك.
تكوين اللغات الخاصة بك
ملف
project.inlang/settings.jsonهو المصدر الوحيد للحقيقة بالنسبة للغات. تقرأ إضافة تنسيق الرسائل ملف JSON واحد لكل لغة.project.inlang/settings.jsonنسخ الكودنسخ الكود إلى الحافظة
تكوين إضافة Vite واستراتيجية عناوين URL
تقوم الإضافة بتجميع الرسائل عند كل تغيير. هناك ثلاثة خيارات مهمة لـ TanStack Start:
strategy: القائمة المرتبة للأماكن التي تتم قراءة اللغة منها. وضعurlأولا يجعل عنوان URL هو مصدر الحقيقة. تُستخدمcookieوpreferredLanguageبواسطة البرمجية الوسيطة عندما لا يحدد عنوان URL اللغة.urlPatterns: كيفية تعيين اللغة إلى عنوان URL. يتم إدراج اللغات غير الافتراضية أولا، لأن أول نمط مطابق يفوز. هنا تظل اللغة الافتراضية بدون بادئة (/about)، وتأتي اللغات الأخرى مسبوقة ببادئة (/fr/about).outputStructure: "message-modules": وحدة واحدة لكل رسالة، مما يتيح لجامع الحزم تجاهل الرسائل التي لا تستوردها الصفحة.
vite.config.tsنسخ الكودنسخ الكود إلى الحافظة
أضف المجلد المنشأ إلى
.gitignore. حيث يُعاد بناؤه عندdevوbuild:.gitignoreنسخ الكودنسخ الكود إلى الحافظة
إنشاء ملفات الترجمة الخاصة بك
يصبح كل مفتاح دالة يتم تصديرها من
src/paraglide/messages. المفاتيح المسطحة بنمط snake_case تعطي أنظف أسماء للدوال. تستخدم المتغيرات عناصر نائبة مثل{name}.messages/en.jsonنسخ الكودنسخ الكود إلى الحافظة
messages/fr.jsonنسخ الكودنسخ الكود إلى الحافظة
تستخدم صيغ الجمع بناء جملة المتغيرات (variants) لتنسيق رسائل inlang:
messages/en.jsonنسخ الكودنسخ الكود إلى الحافظة
إضافة البرمجية الوسيطة للخادم (Server Middleware)
تقوم البرمجية الوسيطة بتحديد لغة كل طلب وفقا لاستراتيجيتك، وتجعلها متاحة لـ
getLocale()طوال عملية العرض على الخادم، من خلال نطاقAsyncLocalStorage. هذا ما يجعل الطلبات المتزامنة بلغات مختلفة آمنة.في TanStack Start، قم بلف مدخل الخادم الافتراضي:
src/server.tsنسخ الكودنسخ الكود إلى الحافظة
إعادة كتابة عناوين URL المترجمة في الموجه (Router)
يقوم خيار
rewriteفي TanStack Router بترجمة عناوين URL عند حدود الموجه:- المدخل (input): يتم تجريد
/fr/aboutمن بادئة اللغة ليصبح/aboutقبل المطابقة، وبالتالي فإن مسارabout.tsxواحد يخدم كل اللغات؛ - المخرج (output): كل رابط
hrefيتم إنشاؤه (الروابط، عمليات إعادة التوجيه، التنقل) تتم ترجمته للغة النشطة، بحيث يقوم<Link to="/about">بعرض/fr/aboutفي صفحة فرنسية.
src/router.tsxنسخ الكودنسخ الكود إلى الحافظة
نظرا لأن الروابط تتم ترجمتها تلقائيا بواسطة إعادة الكتابة، فلن تحتاج إلى مكون
LocalizedLinkمخصص: استخدم مكونLinkالخاص بـ TanStack Router كالمعتاد.- المدخل (input): يتم تجريد
إنشاء المستند الجذري (Root Document)
ترجع
getLocale()اللغة المحددة بواسطة البرمجية الوسيطة على الخادم، واللغة من عنوان URL في المتصفح، بحيث تكونlangوdirمتطابقتين في HTML الخادم وبعد التفعيل في المتصفح (hydration).src/i18n/config.tsنسخ الكودنسخ الكود إلى الحافظة
src/routes/__root.tsxنسخ الكودنسخ الكود إلى الحافظة
استخدام الترجمات في صفحاتك
الرسائل هي دوال عادية: استورد
m، واستدعِ الدالة، ومرر المتغيرات ككائن. كل شيء محدد الأنواع، بما في ذلك المتغيرات.src/routes/index.tsxنسخ الكودنسخ الكود إلى الحافظة
src/routes/about.tsxنسخ الكودنسخ الكود إلى الحافظة
تقبل دالة الرسالة أيضا لغة صريحة:
m.about_title({}, { locale: "fr" }). هذا مفيد في شيفرة الخادم التي تعرض لغة مختلفة عن لغة الطلب، مثل رسائل البريد الإلكتروني.تغيير لغة المحتوى الخاص بك
اختياريقم بعرض المبدل كـ روابط باستخدام
localizeHref، حتى تكتشف محركات البحث كل اللغات. تقومsetLocaleبتخزين الاختيار في ملف تعريف الارتباط (cookie) وإعادة تحميل الصفحة باللغة الجديدة: إعادة التحميل الكاملة هي السلوك المتوقع لـ Paraglide، لأن دوال الرسائل تقرأ اللغة عند كل استدعاء بدلا من الاشتراك في حالة React.src/components/LocaleSwitcher.tsxنسخ الكودنسخ الكود إلى الحافظة
تدويل البيانات الوصفية (Metadata)
اختيارييمكن لكل نسخة لغوية أن تتصدر نتائج البحث بشكل مستقل، بشرط أن توفر كل صفحة:
<title>وdescriptionمترجمين؛- رابط canonical يشير إلى الصفحة نفسها؛
- رابط
hreflangبديل لكل لغة، بالإضافة إلىx-default؛ - وسوم Open Graph:
og:localeوog:locale:alternateوog:url؛ - JSON-LD مع تعيين
inLanguage.
تقوم دالة
localizeUrlالخاصة بـ Paraglide ببناء عناوين URL البديلة منurlPatternsالخاصة بك، بحيث لا تنحرف أبدا عن التوجيه الفعلي:src/i18n/seo.tsنسخ الكودنسخ الكود إلى الحافظة
تدويل خريطة الموقع (Sitemap)
اختياريتسرد خريطة الموقع متعددة اللغات كل عنوان URL لكل لغة، ويعلن كل إدخال عن جميع بدائله باستخدام
xhtml:link:src/routes/sitemap[.]xml.tsنسخ الكودنسخ الكود إلى الحافظة
تدويل ملف robots.txt
اختياريتوجد المسارات الخاصة في كل لغة، لذلك يجب أن تغطي قواعد
Disallowكل مسار مترجم. احذفpublic/robots.txtإذا كان المشروع المبدئي قد أنشأ واحدا، ثم قم بتقديمه من مسار:src/routes/robots[.]txt.tsنسخ الكودنسخ الكود إلى الحافظة
العرض المسبق (Pre-render) لكل لغة
اختياريقم بإدراج المسار المترجم لكل صفحة حتى يقوم TanStack Start بالعرض المسبق لجميع إصدارات اللغات. الدالة
localizeHrefهي شيفرة منشأة دون أي اعتماد على المتصفح، لذا يمكن تشغيلها فيvite.config.ts، ولكن الملف لا يوجد إلا بعد عملية التجميع الأولى. إدراج المسارات يدويا، كما هو موضح أدناه، يتجنب مشكلة ترتيب البناء هذه:vite.config.tsنسخ الكودنسخ الكود إلى الحافظة
نظرا لأن مبدل اللغة يعرض روابط حقيقية، فإن
crawlLinks: trueسيكتشف أيضا الصفحات التي نسيت إدراجها.معالجة صفحات 404 المترجمة
اختياريمع إعادة الكتابة، تتم مطابقة
/fr/does-not-existكـ/does-not-exist، وتظلgetLocale()ترجعfr، وبالتالي فإنnotFoundComponentالجذري من الخطوة 7 يتم عرضه بالفرنسية. يضمن المسار الشامل (catch-all route) وصول المسارات العميقة أيضا إليه. قم بتمييز الصفحة بـnoindex: يرفع React 19 الوسم<meta>إلى<head>.src/components/NotFound.tsxنسخ الكودنسخ الكود إلى الحافظة
src/routes/$.tsxنسخ الكودنسخ الكود إلى الحافظة
الوصول إلى اللغة في دوال الخادم (Server Functions)
اختياريتعمل دوال الخادم داخل نطاق برمجية Paraglide الوسيطة، لذا تعمل
getLocale()هناك أيضا:src/server/sendWelcomeEmail.tsنسخ الكودنسخ الكود إلى الحافظة
المقارنة مع Intlayer
اختياريلا يوجد محول مباشر من Paraglide إلى Intlayer، لأن كلاهما يتبع نفس الفكرة: تجميع المحتوى في وقت البناء وشحن أقل قدر ممكن من بيئة التشغيل. تكمن الاختلافات في ما يصل إلى المتصفح وكيفية تنظيم المحتوى:
- اللغات: يقوم Intlayer بتحميل قواميس ديناميكية لكل لغة (0% تسرب لغات في المقارنة المعيارية)، بينما تحمل كل دالة رسالة في Paraglide جميع اللغات (49.7%).
- تنظيم المحتوى: يمكن للمحتوى أن يتواجد في ملفات
.content.tsبجانب كل مكون، أو في ملفات مركزية. راجع التدويل لكل مكون مقابل التدويل المركزي. - تبديل اللغة: تتم قراءة المحتوى من سياق React context، لذا فإن تبديل اللغة يعيد العرض دون إعادة تحميل الصفحة.
- الشيفرة المنشأة: لا يتم إنشاء أي شيء داخل
src، لذا لا يوجد شيء لإعادة إنشائه قبل إجراء commit.
إذا كنت قادما من مكتبة أخرى بدلا من Paraglide، فإن محولات التوافق تحافظ على واجهة برمجة تطبيقات
use-intlأوnext-intlأوreact-i18nextأوreact-intlأو Lingui وتستبدل بيئة التشغيل.راجع هل Intlayer أخف من Paraglide؟ و دليل Intlayer مع TanStack Start.
أتمتة ترجماتك باستخدام Intlayer
اختياريتعرض Paraglide الترجمات، لكنها لا تساعدك في إنشائها. Intlayer مجاني و مفتوح المصدر، وتساعد أدواته حتى في مشروع يستخدم Paraglide:
- الترجمة بالذكاء الاصطناعي باستخدام مفتاح API والمزود الخاصين بك. راجع الملء التلقائي و واجهة سطر الأوامر (CLI).
- الحفاظ على ملفات JSON الخاصة بك كمصدر للحقيقة باستخدام إضافة مزامنة JSON.
- اختبار الترجمات المفقودة في CI. راجع اختبار ترجماتك.
- فحص موقعك المنشور للبحث عن وسوم
hreflangالمفقودة والروابط الأساسية الخاطئة وتسرب اللغات باستخدام أمر scan.
الأسئلة الشائعة
إنه خيار قوي: فهو مستخدم في أمثلة TanStack Router الرسمية، ويحتوي على أصغر بيئة تشغيل في المقارنة المعيارية (~1.8 KB gzip)، والرسائل محددة الأنواع بالكامل. التنازلات تكمن في أن كل دالة رسالة تحتوي على جميع اللغات، مما يسرب ما يقرب من نصف النصوص المترجمة لزوار اللغات الأخرى، وأن تبديل اللغة يعيد تحميل الصفحة.
لا. تقوم عملية rewrite في الموجه بإزالة بادئة اللغة قبل مطابقة المسار وإضافتها مرة أخرى إلى الروابط المنشأة، بحيث يخدم ملف about.tsx واحد كلا من /about و /fr/about و /es/about.
تقرأ دوال الرسائل اللغة عند استدعائها، وهي غير مشتركة في حالة React state. لذلك، تقوم setLocale بإعادة تحميل الصفحة افتراضيا، بحيث تتم إعادة عرض كل رسالة باللغة الجديدة. يمكنك تمرير { reload: false }، ولكن سيتعين عليك إعادة عرض شجرة المكونات بنفسك.
من الأفضل ألا تفعل ذلك. يُعاد إنشاء المجلد عند كل dev و build، وتضمينه يسبب تعارضات دمج (merge conflicts) في الملفات المنشأة تلقائيا. قم بتضمين messages/*.json و project.inlang/settings.json بدلا من ذلك.
استخدم localizeUrl لإنشاء عنوان URL مطلق واحد لكل لغة في head() الخاص بالمسار، وأضف x-default يشير إلى اللغة الأساسية. توفر الخطوة 10 دالة مساعدة قابلة لإعادة الاستخدام، وتضيف الخطوة 11 نفس البدائل إلى خريطة الموقع sitemap.
يتم التخلص من الرسائل غير المستخدمة عند استخدام outputStructure: "message-modules"، بحيث لا يتسرب محتوى الصفحات الأخرى. لكن لا يتم التخلص من اللغات غير المستخدمة: فكل دالة رسالة تحتوي على جميع الترجمات، وهذا هو سبب تسجيل المقارنة المعيارية لتسرب لغات بنسبة 49.7%.
التعليقات
لا توجد تعليقات بعد. كن أول من يشارك أفكاره.
