المؤلف:
    إنشاء:2026-09-13آخر تحديث:2026-09-27

    مقارنة i18next مقابل @intlayer/i18next: نفس واجهة البرمجة (API)، وحزمة برمجية مختلفة تماماً

    i18next VS Intlayer

    تُعد @intlayer/i18next و @intlayer/react-i18next و @intlayer/next-i18next محولات توافقية. إنها توفر نفس واجهة برمجة التطبيقات (API) الخاصة بـ i18next التي تستخدمها بالفعل في شيفرتك البرمجية (useTranslation، t()، <Trans>، i18n.changeLanguage()، getFixedT، serverSideTranslations...) وتقدمها من خلال قواميس مبنية ومترجمة بواسطة Intlayer. المكونات لا تتغير إطلاقاً، بل إن بيئة التشغيل الأساسية تحتها هي التي تتغير.

    يقيس هذا المقال ذلك الاستبدال على نفس تطبيق Next.js، حيث تم بناؤه مرة باستخدام next-i18next ومرة أخرى باستخدام @intlayer/next-i18next. الأرقام مأخوذة من مشروع Benchmark Bloom. للمقارنة بين i18next و Intlayer كمكتبات مستقلة، يرجى قراءة مقارنة i18next مقابل Intlayer. أما هذا المقال، فيركز على ما يغيره المحول عندما تحتفظ بشيفرتك البرمجية كما هي.

    ملخص سريع (tl;dr): في نفس تطبيق Next.js، أدى استبدال next-i18next بـ @intlayer/next-i18next إلى خفض حجم JavaScript المضغوط (gzip) لكل صفحة من 218.5 كيلوبايت إلى 150.7 كيلوبايت (في التكوين الأولي البسيط) وتفوق على تكوين next-i18next المحسّن بالكامل (163.4 كيلوبايت) بفارق 12.7 كيلوبايت. وانخفض متوسط حجم المكون من 78.5 كيلوبايت إلى 9.7 كيلوبايت، وتراجع تسريب نصوص الصفحات غير المعروضة من ~90% إلى 0%، وانخفض وقت الترطيب (hydration) من 15.6 مللي ثانية إلى 11.3 مللي ثانية، وتراجع حجم بيئة التشغيل من 19.7 كيلوبايت إلى 9.4 كيلوبايت. لم يتم تعديل أي مكون؛ تم تعديل ملف مزود واحد فقط. يتم قبول إضافات i18next (مثل الخلفيات وكواشف اللغة) ولكنها لا تفعل شيئاً: لا يوجد شيء إضافي ليتم تحميله أو اكتشافه في وقت التشغيل.

    ما هو @intlayer/i18next

    i18next هي بيئة تشغيل runtime. تقوم الدالة i18n.init({ resources }) أو إضافة الواجهة الخلفية بتحميل ملفات locales/{lng}/{ns}.json في كائن عام (global instance)؛ وتقوم useTranslation("about") بربط المكون به؛ وتقوم t("title") بالبحث عن المفتاح أثناء التصيير. تقع على عاتقك مسؤولية ضبط وإدارة مساحات الأسماء والتحميل الكسول وقوائم مساحات الأسماء لكل صفحة وسلامة الأنواع.

    تحافظ المحولات على نفس واجهة البرمجة وتستبدل الكائن العام:

    1. الأسماء المستعارة للاستيراد (Import Aliasing). تقوم createNextI18nPlugin() من حزمة @intlayer/next-i18next/plugin (أو withI18next) بتغليف withIntlayer وإضافة أسماء مستعارة لـ Webpack / Turbopack بحيث يتم توجيه استيرادات next-i18next و react-i18next و i18next إلى نظيراتها في @intlayer/*. وفي Vite، تؤدي reactI18nextVitePlugin() من حزمة @intlayer/react-i18next/plugin نفس الغرض. لا حاجة لتغيير أي عبارة استيراد.
    2. اعتماد JSON كمصدر وحيد للحقيقة. يقرأ ملحق syncJSON ملفاتك الحالية locales/{lng}/{ns}.json مع إعداد format: "i18next" (بحيث يتم تحليل {{name}} وتداخل $t() وصيغ _one / _other وسياقات النصوص بدقة) ويكتب الترجمات مرة أخرى عندما تقوم واجهة الأوامر CLI أو نظام إدارة المحتوى CMS بتحديثها.
    3. الربط عند نقطة الاستدعاء. تقوم مرحلة التحسين في Intlayer بإعادة كتابة useTranslation("about") لتصبح استدعاءً يستلم مباشرة قاموس about في اللغة النشطة. يتوقف المكون تماماً عن الوصول إلى المخزن العام.
    components/About.tsx
    // الشيفرة البرمجية الخاصة بك، بدون أي تغيير
    import { useTranslation } from "react-i18next";
    
    const About = () => {
      const { t } = useTranslation("about");
      return <h1>{t("title")}</h1>;
    };
    
    ما يخرجه المترجم (صيغة مبسطة)
    import _dicHash_about from "../.intlayer/dictionaries/about.mjs";
    import { useDictionary as useTranslation } from "@intlayer/react-i18next";
    
    const About = () => {
      const { t } = useTranslation(_dicHash_about);
      return <h1>{t("title")}</h1>;
    };
    

    هذه الإعادة في الكتابة هي المسؤولة عن تقليص حجم المكونات والقضاء التام على تسريب نصوص الصفحات في النتائج التالية.

    ما تحتفظ به المحولات، وما تتجاهله، وما لا يمكنها استبداله

    واجهة برمجة i18nextمع حزم @intlayer/*
    useTranslation("ns"), useTranslation("ns", { keyPrefix })✅ تم الاحتفاظ بها. مرتبطة بقاموس ns وقت البناء؛ ومفحوصة الأنواع وفق محتواك
    t("key", { name }), {{interpolation}}, تداخل $t(key)✅ تم الاحتفاظ بها
    صيغ الجمع key_one / key_other, سياق key_male, returnObjects✅ تم الاحتفاظ بها. تُحسب صيغ الجمع باستخدام Intl.PluralRules
    <Trans> مع components، والوسوم المرقمة <1>...</1>، و values✅ تم الاحتفاظ بها
    withTranslation, Translation, I18nContext✅ تم الاحتفاظ بها
    i18n.changeLanguage(), i18n.language, i18n.dir(), on("languageChanged")✅ تم الاحتفاظ بها. تقود changeLanguage لغة Intlayer
    getFixedT(lng, ns, keyPrefix), i18n.exists(), hasLoadedNamespace()✅ تم الاحتفاظ بها
    i18n.use(Backend).use(LanguageDetector).init({...})⚠️ تقوم use() باستدعاء init للملحق ثم تنتهي؛ لا يوجد شيء لتحميله أو اكتشافه في الخلفيات
    init({ resources }), addResourceBundle()⚠️ يتم تجاهل resources مع إظهار تحذير في بيئة التطوير؛ احذف استيرادات JSON للحصول على فوائد تصغير الحزمة
    I18nextProvider i18n={i18n}⚠️ تقوم بتصيير IntlayerProvider؛ ويتم تجاهل خاصية i18n. في App Router، مرر اللغة مباشرة (انظر أدناه)
    serverSideTranslations(locale, ["common"]) (next-i18next)⚠️ تعيد الهيكل المتوقع ولا تقوم بتحميل أي شيء. آمنة للإبقاء، وآمنة للحذف
    appWithTranslation(App) (next-i18next)✅ تم الاحتفاظ بها
    next-i18next.config.js⚠️ لا يتم قراءتها. يتم ضبط اللغات في ملف intlayer.config.ts
    استدعاء useTranslation() البسيط بدون مساحة أسماء✅ يعمل بالاعتماد على قاموس translation الكامل للملف (splitKeys: false)

    اختبار الأداء المقارن

    ما تم قياسه

    تقوم حزمة Benchmark Bloom ببناء نفس التطبيق تماماً في كل إعداد: 10 صفحات (الرئيسية، من نحن، المدونة، الوظائف، اتصل بنا، الأسئلة الشائعة، الأسعار، المنتجات، الإعدادات، الفريق)، و 10 لغات (en, fr, es, de, it, pt, zh, ja, ko, ru)، ومكونات ومحتوى متطابق تماماً. تم قياس الصفحات في اللغتين الإنجليزية والفرنسية.

    تم اختبار next-i18next عبر أربع استراتيجيات تحميل، بدءاً من استيراد ملفات JSON لجميع اللغات مباشرة في resources (static) إلى تقسيم مساحات الأسماء لكل مسار مع التحميل الكسول عبر واجهة خلفية (scoped-dynamic). بينما تم بناء المحول على نفس مكونات الإعداد الأولي البسيط، مع تعديل ملفات next.config.ts و intlayer.config.ts وملف المزود فقط. لا يحتاج المحول إلى تقسيم يدوي: يتولى المترجم تخصيص نطاق المحتوى لكل مكون تلقائياً.

    سجل الاختبار لكل بناء:

    • حجم المكتبة: حجم gzip لمكون فارغ يستورد مكتبة i18n فقط.
    • حجم JS لكل صفحة: متوسط ملفات JavaScript المنزلة لكل صفحة عبر جميع اللغات والصفحات (gzip).
    • نسبة تسريب اللغات: نسبة السلاسل النصية المترجمة في ملف JS المنزّل والتي تنتمي إلى لغة لا يشاهدها المستخدم حالياً.
    • نسبة تسريب الصفحات: نسبة السلاسل النصية المترجمة في ملف JS المنزّل والتي تنتمي إلى صفحة لا يتواجد فيها المستخدم حالياً.
    • متوسط حجم المكون: متوسط حجم gzip لكل مكون تم تجميعه بشكل معزول.
    • تفاعلية E2E: الوقت الفعلي المستغرق بين اختيار لغة جديدة وتحديث سمة html[lang] في صفحة الويب (Playwright، عبر 5 تكرارات).
    • الترطيب (Hydration): المدة الزمنية لمرحلة ترطيب React.
    الأرقام أدناه مأخوذة من اختبار أُجري بتاريخ 12-09-2026 باستخدام next-i18next 16.3.0 (react-i18next 17.0.13, i18next 26.4.2) و @intlayer/next-i18next 9.5.1. تم تصميم تطبيق الاختبار عمداً ليكون صغيراً، لذا فإن نسب التسريب توضح نمطاً سلوكياً: تتسع هذه النسب مع نمو محتوى تطبيقك، في حين تبقى التكلفة الثابتة لبيئة التشغيل مستقرة.

    النتائج على Next.js

    اختر المقاييس والمكتبات التي تهمك:

    المقياس

    تحميل JSON الديناميكي

    تحميل الترجمات ببطء في وقت التشغيل

    JSON المحدد (أسماء المحيط)

    مساحات أسماء الترجمة لكل صفحة

    ما هو هذا المقياس؟

    الحجم الإجمالي المضغوط بتنسيق gzip لحزمة مكتبة التدويل. وهي تتضمن فقط المزود ومنطق استرداد المحتوى بعد تقليل الحجم (tree-shaking) والضغط (minification).

    لماذا هو مهم؟

    يقلل حجم المكتبة الأصغر من حمولة JavaScript الأولية، مما يؤدي إلى سرعة التنزيل وأوقات التنفيذ على العميل.

    عرض كـ

    الإعدادالاستراتيجيةحجم المكتبة (gz)متوسط JS للصفحة (gz)تسريب اللغاتتسريب الصفحاتمتوسط المكون (gz)تفاعلية E2Eالترطيب
    الأساس (بدون i18n)-0.0 KB141.0 KB0.0%0.0%0.9 KB13.4 ms11.8 ms
    next-i18nextstatic19.7 KB218.5 KB0.0%89.8%78.5 KB16.4 ms15.6 ms
    next-i18nextdynamic19.7 KB169.5 KB50.0%89.8%26.1 KB15.4 ms27.7 ms
    next-i18nextscoped-static19.7 KB220.1 KB0.0%89.8%78.9 KB16.4 ms14.7 ms
    next-i18nextscoped-dynamic19.7 KB163.4 KB0.0%0.0%27.1 KB15.9 ms15.1 ms
    @intlayer/next-i18nextstatic9.4 KB150.7 KB0.0%0.0%9.7 KB10.7 ms11.3 ms
    @intlayer/next-i18nextdynamic9.4 KB150.7 KB0.0%0.0%9.7 KB11.9 ms10.6 ms
    next-intlayer (الأصلي)static5.5 KB141.3 KB0.0%0.0%8.5 KB15.5 ms16.9 ms
    next-intlayer (الأصلي)dynamic5.5 KB141.3 KB0.0%0.0%6.9 KB15.3 ms15.9 ms

    قراءة البيانات وتحليلها

    • توفير 68 كيلوبايت لكل صفحة مقارنة بالإعداد البسيط. يقوم الإعداد البسيط resources: { en, fr, ... } بإرسال جميع اللغات وجميع مساحات الأسماء في كل صفحة ليصل إلى 218.5 كيلوبايت. أما بناء نفس المكونات باستخدام المحول فيصل إلى 150.7 كيلوبايت. كما يتفوق على أفضل تكوين مخصص لـ next-i18next (163.4 كيلوبايت) بفارق 12.7 كيلوبايت، لأن بيئة تشغيل i18next وحدها تزن 19.7 كيلوبايت مقابل 9.4 كيلوبايت للمحول.
    • تراجع التسريب إلى 0% دون لمس أي مكون. ترسل جميع إعدادات next-i18next (باستثناء الإعداد المقسم يدوياً بالكامل) ما يقارب 90% من نصوص الصفحات الأخرى غير المطلوبة. ونمط dynamic أسوأ مما يبدو: فهو لا يقضي على تسريب الصفحات ويضيف 50% تسريب لغات، لأن الواجهة الخلفية الخاصة باللغة ما زالت تسحب كامل مساحة الأسماء translation. يبلغ المحول نسبة 0% / 0% انطلاقاً من الشيفرة الأصلية مباشرة.
    • مكونات أصغر بمقدار 8 أضعاف. يزن المكون المعتمد على useTranslation() والمبني بمفرده متوسط 78.5 كيلوبايت عند تضمين resources، و 26-27 كيلوبايت مع الواجهة الخلفية، نظراً لارتباط t بالمخزن العام. ومع المحول، ينخفض متوسط الحجم إلى 9.7 كيلوبايت.
    • ترطيب أسرع وتبديل لغات أكثر سلاسة. انخفض وقت الترطيب من 15.6 مللي ثانية إلى 11.3 مللي ثانية (ومن 27.7 مللي ثانية في نمط dynamic حيث يعيق جلب البيانات المسار الحرج). وتحسن وقت تبديل اللغة من 15-16 مللي ثانية إلى 11-12 مللي ثانية.
    • المحول ليس هو بيئة التشغيل الأصلية. تبلغ حزمة next-intlayer الأصلية 141.3 كيلوبايت (+0.3 كيلوبايت فقط فوق التطبيق الأساسي الخالي من اللغات). بينما يحمل المحول طبقة توافق واجهة i18next فوق نواة Intlayer ليضيف 9.4 كيلوبايت لكل صفحة مقارنة بالنسخة الأصلية. المحول هو جسر عبور مريح، وليس المحطة النهائية.
    الجدول الكامل، كل مكتبة وكل استراتيجية، في تقرير قياس أداء Next.js.

    النتائج على TanStack Start (react-i18next)

    بالنسبة لـ Vite و TanStack Start، يقيس الاختبار react-i18next العادي مقابل intlayer:

    المكتبةالاستراتيجيةحجم المكتبة (gz)متوسط JS للصفحة (gz)تسريب اللغاتتسريب الصفحاتمتوسط المكون (gz)تفاعلية E2Eالترطيب
    الأساس (بدون i18n)-0.0 KB111.0 KB0.0%0.0%0.7 KB8.1 ms21.6 ms
    react-i18nextdynamic18.4 KB136.4 KB23.1%89.8%24.8 KB123.1 ms32.9 ms
    intlayerdynamic5.0 KB118.6 KB0.0%0.0%6.3 KB3.6 ms14.1 ms
    الجدول الكامل في تقرير قياس أداء TanStack Start.
    لم يكن محول react-i18next على Vite / TanStack Start جزءاً من هذا الاختبار. يمكن الاطلاع على القياسات الأساسية لـ react-i18next على TanStack Start في مقال i18next vs Intlayer: 127-184 KB لكل صفحة و 123-185 ms لتبديل اللغة عند تحميل الـ backend بشكل مؤجل.

    لماذا تتحسن هذه المؤشرات

    The Intlayer compiler extracts content from components

    لم تتغير أي شيفرة داخل مجلد components/، وبالتالي فإن كل هذه المكاسب ناتجة عن الكيان الذي ترتبط به الدالة useTranslation.

    مع i18next، يتم الربط مع الكائن العام. كل ما يتم تحميله فيه (جميع اللغات في static، ومساحة الأسماء الكاملة للغة في dynamic) يصبح في متناول أي مكون يستدعي useTranslation(). ولا يستطيع مجمع الحزم تقسيم الملفات إلى وحدات أصغر مما يحتفظ به الكائن، كما تعجز بيئة التشغيل عن التنبؤ بالمفاتيح المطلوبة أثناء التصيير.

    bash
    .
    ├── next-i18next.config.js
    ├── public/locales
    │   ├── en/translation.json           # نصوص كافة الصفحات مجتمعة
    │   └── fr/translation.json
    ├── i18n/i18n.ts                      # i18n.use(initReactI18next).init({ resources })
    └── components
        ├── AppProviders.tsx              # <I18nextProvider i18n={i18n}>
        └── About.tsx                     # useTranslation(); t("about.title")
    

    يتم إرسال كل ما تحتفظ به النسخة إلى كل صفحة، ويتزايد الهدر على محورين، الصفحات واللغات:

    Theoretical content leakage by architecture

    مع @intlayer/next-i18next، يتم الربط مباشرة بالقاموس. يقوم ملحق syncJSON بتحويل كل ملف مساحة أسماء إلى قاموس مخصص؛ وتمرر مرحلة التحسين للمكون القاموس المعني مباشرة في صورة استيراد يستطيع مجمع الحزم تتبعه وتقسيمه لكل صفحة ولكل لغة بدقة.

    bash
    .
    ├── intlayer.config.ts                # syncJSON({ format: "i18next", source: ... })
    ├── public/locales
    │   ├── en/translation.json           # بدون تغيير، يظل المصدر الحقيقي
    │   └── fr/translation.json
    ├── .intlayer/                        # مولد تلقائياً: قاموس لكل مساحة أسماء ولكل لغة
    └── components
        ├── AppProviders.tsx              # <IntlayerClientProvider locale={locale}>
        └── About.tsx                     # useTranslation(); t("about.title")  ← دون تغيير
    

    يتحول ملف i18n/i18n.ts واستيراد resources إلى شيفرة ميتة يتم التخلص منها تلقائياً. وهذا ما يوفر 68 كيلوبايت كاملة.

    الهجرة في ثلاث خطوات

    1. التثبيت

      bash
      npx intlayer init --interactive
      

      يكتشف الأمر وجود i18next / react-i18next / next-i18next، ويثبت intlayer وحزمة إطار العمل المعنية (next-intlayer أو react-intlayer) ومحول @intlayer/* المناسب مع ملحق @intlayer/sync-json-plugin، ويجهز إعدادات intlayer.config.ts. احتفظ بالحزم الأصلية مثبتة لديك، لأنها توفر تعريفات TypeScript وتعمل كاعتماديات نظيرة.

    2. توجيه Intlayer إلى ملفات الترجمة الحالية

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      import { syncJSON } from "@intlayer/sync-json-plugin";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
          defaultLocale: Locales.ENGLISH,
        },
        dictionary: {
          importMode: "dynamic",
          format: "i18next",
        },
        plugins: [
          syncJSON({
            // نمط i18next: يدعم {{name}} و $t(key) وصيغ الجمع _one / _other والسياق
            format: "i18next",
            // ملف لكل مساحة أسماء: `useTranslation("about")` ← about.json
            source: ({ locale, key }) => `./public/locales/${locale}/${key}.json`,
            location: "public/locales",
          }),
        ],
      };
      
      export default config;
      

      إذا كنت تمتلك ملفاً واحداً باسم translation.json لكل لغة (مساحة الأسماء الافتراضية في i18next)، فقم بتعيين splitKeys: false بحيث يظل الملف بأكمله قاموساً واحداً وتستمر استدعاءات useTranslation() المباشرة في العمل دون مشاكل.

    3. إضافة الملحق

      next.config.ts
      import type { NextConfig } from "next";
      import { withI18next } from "@intlayer/next-i18next/plugin";
      
      const nextConfig: NextConfig = {};
      
      export default withI18next(nextConfig);
      

      في بنية App Router، تستقبل مكونات العميل اللغة من جزء المسار [locale]. لا يستقبل I18nextProvider الخاص بالمحول خاصية اللغة، لذا قم باستبداله لمرة واحدة فقط في ملف المزود الرئيسي:

      components/AppProviders.tsx
      "use client";
      
      import { IntlayerClientProvider } from "next-intlayer";
      import type { LocalesValues } from "intlayer";
      
      export const AppProviders = ({
        locale,
        children,
      }: {
        locale: LocalesValues;
        children: React.ReactNode;
      }) => (
        <IntlayerClientProvider locale={locale}>{children}</IntlayerClientProvider>
      );
      

      جميع المكونات الموجودة تحته تستمر في استدعاء useTranslation() بشكل طبيعي وبدون أي تغيير.

      vite.config.ts
      import { defineConfig } from "vite";
      import react from "@vitejs/plugin-react";
      import { reactI18nextVitePlugin } from "@intlayer/react-i18next/plugin";
      
      export default defineConfig({
        plugins: [react(), reactI18nextVitePlugin()],
      });
      

      تغلف reactI18nextVitePlugin() ملحق vite-intlayer وتنشئ الأسماء المستعارة لـ react-i18next و i18next. للمشاريع غير المعتمدة على React، تقوم i18nextVitePlugin() من حزمة @intlayer/i18next/plugin بتعيين الاسم المستعار لـ i18next بمفردها.

    ما يمكنك حذفه بعد الانتهاء

    الملف / النمطالسبب
    resources: { en, fr, ... } واستيرادات JSONيتم تجاهلها بواسطة المحول؛ ومن هنا جاءت إزالة الـ 68 كيلوبايت الفائضة
    i18next-http-backend, i18next-resources-to-backendلم يعد هناك شيء لجلبه في وقت التشغيل عبر الشبكة
    i18next-browser-languagedetectorأصبح اكتشاف اللغة يدار عبر توجيه Intlayer (بادئة الرابط، ملفات تعريف الارتباط، الترويسة)
    استدعاء serverSideTranslations() في getStaticPropsيعيد كائناً فارغاً؛ وجوده غير ضار لكنه غير ضروري
    next-i18next.config.jsلا يتم قراءته؛ تُدار اللغات مركزياً في intlayer.config.ts
    قوائم ns: [...] المحددة لكل صفحةيحدد المترجم مساحات الأسماء المطلوبة لكل مكون تلقائياً

    ما تكسبه بجانب تقليص الحجم

    • مفاتيح محكمة الأنواع. يتم ربط useTranslation("about") بالأنواع البرمجية الخاصة بالقاموس about؛ واستخدام مفتاح غير موجود مثل t("does.not.exist") يولد خطأ TypeScript فوري أثناء التطوير بدلاً من إعادة نص المفتاح كخطأ صامت.
    • أوامر الفحص npx intlayer test التي توقف عمليات الـ CI عند وجود مفتاح مفقود في أي لغة. ويتولى أمر npx intlayer fill ترجمة المفاتيح الناقصة باستخدام مفتاح الذكاء الاصطناعي الخاص بك (OpenAI, Anthropic, Mistral, Gemini...) وكتابتها في ملفات locales/{lng}/{ns}.json.
    • محرر بصري ونظام CMS يعملان على نفس ملفات JSON، مما يتيح للمترجمين التعديل عبر واجهة مستخدم مباشرة مع تحديث ملفات Git تلقائياً.
    • هجرة تدريجية نحو ملفات .content.ts. يمكن لأي مكون أن ينتقل بمفرده من useTranslation("about") إلى useIntlayer("about") بملف محتوى مجاور له، مع تعايش ملفات JSON و .content.ts معاً بانسجام.

    قيود يجب معرفتها قبل البدء

    i18n.use(HttpBackend) يقوم فقط باستدعاء دالة init الخاصة بالملحق ولا يفعل أي شيء آخر. إذا كان تطبيقك يعتمد على جلب الترجمات من نظام إدارة المحتوى (CMS) في وقت التشغيل، فإن هذا التدفق قد اختفى؛ استخدم Intlayer CMS أو أوامر intlayer pull / push بدلاً من ذلك. يصبح اكتشاف اللغة جزءًا من إعدادات التوجيه الخاصة بـ Intlayer (بادئة URL، ملف تعريف الارتباط، الرأس).

    على عكس بعض المحولات الأخرى، لا يستخدم @intlayer/i18next كائن resources المضمن كحل بديل. يجب أن يكون كل مفتاح موجودًا في القواميس المتزامنة، وهو ما يتحقق منه أمر intlayer test.

    ملف واحد فقط، موضح أعلاه. لا يتطلب Pages Router مع appWithTranslation أي تعديلات.

    ليس لـ localePath و fallbackLng و reloadOnPrerender وما شابهها أي مكافئ؛ تأتي اللغات والبدائل الاحتياطية من intlayer.config.ts.

    9.4 كيلوبايت لوقت التشغيل و +9.4 كيلوبايت لكل صفحة مقارنة بـ next-intlayer. بمجرد انتقال كل مكون إلى useIntlayer، قم بإزالته.

    مقارنة الميزات

    بعيداً عن حجم البايتات، إليك ما يقدمه كل خيار:

    الميزةi18next / react-i18next / next-i18nextمحولات @intlayer/*Intlayer الأصلي
    استدعاءات t() و useTranslation و <Trans> الخاصة بك✅✅ دون تغيير❌ منقولة إلى useIntlayer
    حجم وقت التشغيل (gzip, Next.js)19.7 KB9.4 KB5.5 KB
    تسريب الصفحات الأخرى دون namespaces يدوية~90%0%0%
    مفاتيح مُنمّطة⚠️ تعريف يدوي✅ من القواميس المُجمّعة✅ مُولّدة تلقائياً
    الـ backends والإضافات وقت التشغيل✅ منظومة إضافات كاملة❌ غير فعّالة❌ غير مطبّق، استخدم الـ CMS
    المحتوى بجانب المكونات❌ JSON مركزي⚠️ JSON، ويمكن أن يتعايش مع .content.ts✅ .content.ts بجانب كل مكون
    الترجمات المفقودة في CI⚠️ غير مدمج✅ npx intlayer test✅ npx intlayer test
    الترجمة بالذكاء الاصطناعي❌ لا✅ npx intlayer fill✅ npx intlayer fill
    المحرر المرئي / CMS❌ عبر منصات خارجية✅ على نفس ملفات JSON✅ نعم
    المنظومة / المجتمع✅ كبير جداً⚠️ أصغر، وينمو بسرعة⚠️ أصغر، وينمو بسرعة
    أحجام وقت التشغيل مأخوذة من اختبار Next.js الموصوف أعلاه.

    متى تستخدم كل خيار؟

    يعتمد تطبيقك على واجهات خلفية في وقت التشغيل (ترجمات يقدمها CMS عند الطلب)، أو على نظام الملحقات البيئي، أو على هدف غير تابع لـ React لا تغطيه المحولات.

    أنت تستخدم react-i18next / next-i18next وتريد توفير 68 كيلوبايت، ومكونات أصغر بـ 8 مرات، وتسرب بنسبة 0%، ومفاتيح مطبوعة وفحوصات CI دون إعادة كتابة التعليمات البرمجية. هذه هي نقطة الدخول لقاعدة كود i18next الحالية.

    للمشاريع الجديدة، أو بمجرد أن يؤدي المحول وظيفته. يتميز بأخف وقت تشغيل (5.5 كيلوبايت، +0.3 كيلوبايت لكل صفحة) ويوفر Server Components متزامنة وملفات .content.ts لكل مكون. ابدأ مع Intlayer مع Next.js أو مع Vite و React.

    الأسئلة الشائعة

    من resources: { en, fr, ... }. يستورد الإعداد التقليدي لـ next-i18next ملف JSON الخاص بكل لغة في init()، بحيث تحمل كل صفحة كل مساحة اسم بكل لغة: 218.5 كيلوبايت لكل صفحة. لا يقوم المحول بتجميع تلك الكتلة أبدًا؛ بل يمنح كل مكون القاموس المحدد فقط، باللغة النشطة.

    نعم، مع components، والعلامات المرقمة <1>...</1> و values. وبالمثل بالنسبة لـ {{interpolation}}، وتداخل $t(key)، وصيغ الجمع key_one / key_other (يتم تقييمها باستخدام Intl.PluralRules)، ولواحق السياق و returnObjects.

    اضبط splitKeys: false في ملحق syncJSON. يظل الملف بأكمله قاموسًا واحدًا ويستمر استدعاء useTranslation() البسيط في التحليل عليه.

    لا، إنه الجسر. يحافظ المحول على واجهة برمجة تطبيقات i18next وتكلفة وقت التشغيل 9.4 كيلوبايت؛ وتبلغ تكلفة next-intlayer الأصلي 5.5 كيلوبايت ويضيف Server Components متزامنة وملفات .content.ts مجاورة. يمكنك الترحيل مكونًا تلو الآخر، نظرًا لتعايش قواميس JSON و .content.ts معًا.

    نعم. يظل locales/{lng}/{ns}.json هو المصدر الوحيد للحقيقة: يقرأه syncJSON بلهجة i18next ويكتب الترجمات مرة أخرى عندما يقوم CLI أو CMS بتحديثها.

    مقارنات ذات صلة

    نفس سلسلة المحولات:

    مقارنة المكتبات جنبًا إلى جنب:

    وثائق مرجعية:

    Compat adapters:

    Migration guides:

    لفهم أصل هذه المكتبات، اقرأ تاريخ i18n في JavaScript.

    الخاتمة

    يعد i18next أثقل بيئة تشغيل في اختبار الأداء هذا، وتقوم المحولات بالتخلص من معظم وزنه الزائد دون أن تطلب منك التخلي عن واجهة البرمجة التي اعتدت عليها. في نفس تطبيق Next.js، يعني ذلك توفير 68 كيلوبايت لكل صفحة مقارنة بالإعداد البسيط، و 12.7 كيلوبايت أقل من أفضل إعداد محسّن يدوياً، مع مكونات أصغر بـ 8 مرات، و 0% تسريب نصوص، و تحسن الترطيب بـ 4 مللي ثانية، مقابل ملف إعدادات وسطر ملحق وتعديل بسيط لملف المزود.

    جميع البيانات الأولية والتطبيقات الاختبارية والبرمجيات النصية متوفرة في مستودع Benchmark Bloom. يمكنك مراجعتها واختبارها بنفسك.

    راجع توثيق لماذا Intlayer؟ لمزيد من التفاصيل.

    التعليقات

    لا توجد تعليقات بعد. كن أول من يشارك أفكاره.

    مقالات ذات صلة

    آخر المقالات