מחבר:
    נוצר:2026-09-13עדכון אחרון:2026-11-03

    next-intl מול @intlayer/next-intl: אותו ה-API, חבילת קוד (Bundle) שונה

    next-intl מול Intlayer

    @intlayer/next-intl הוא מתאם תאימות (compat adapter): הוא חושף את ה-API המוכר של next-intl (כגון useTranslations, ‏getTranslations, ‏useLocale, ‏t.rich(), צורות רבים ב-ICU, ‏NextIntlClientProvider...) ומגיש אותו מתוך מילונים שקומפלו על ידי Intlayer. קוד האפליקציה אינו משתנה, אך ה-bundle משתנה באופן משמעותי.

    מאמר זה משווה בין השניים על אותו יישום Next.js, שנבנה פעם אחת עם next-intl ופעם שנייה עם המתאם. הנתונים מגיעים מ-Benchmark Bloom, חבילת בדיקות קוד פתוח המתעדת את מה שהדפדפן מוריד בפועל. אם ברצונכם לקרוא השוואה בין שתי הספריות כספריות עצמאיות, עיינו ב-next-intl מול Intlayer. מאמר זה עוסק בשינויים שמביא המתאם כאשר משאירים את הקומפוננטות ללא שינוי.

    תקציר (tl;dr): באותו יישום Next.js, החלפת next-intl ב-@intlayer/next-intl הפחיתה את ה-JavaScript הממוצע לדף מ-153.6 KB ל-147.5 KB ב-gzip, את גודל הקומפוננטה הממוצע מ-21.8 KB ל-8.1 KB, ביטלה דליפת מחרוזות מדפים זרים מ-~90% ל-0%, וקיצרה את משך ההידרציה מ-14.7 ms ל-12.8 ms, מבלי לערוך אף קומפוננטה. ב-TanStack Start, המקבילה עבור use-intl (המתאם @intlayer/use-intl) קיצצה את הקומפוננטות מ-76-87 KB ל-9-11 KB והאיצה את החלפת השפה מ-7-21 ms ל-4-9 ms. המתאם מוסיף 8.0 KB של זמן ריצה לעומת 14.7 KB ב-next-intl ו-5.5 KB ב-next-intlayer המקורית. הניתוב וה-middleware ממומשים מחדש על גבי תצורת הניתוב של Intlayer; נתיבים מתורגמים (pathnames) הם התכונה היחידה שאינה מועברת.

    מהו בעצם @intlayer/next-intl

    next-intl פועלת בזמן ריצה: getRequestConfig טוען קובץ messages/{locale}.json לכל בקשה, NextIntlClientProvider שולח אותו לצד הלקוח, ו-useTranslations("about") קורא מפתחות מאותו אובייקט בעת הרינדור. כל אופטימיזציה (פיצול ל-namespaces, סינון pick(messages, [...]) לכל דף, טעינה עצלה) היא באחריותכם הבלעדית.

    @intlayer/next-intl שומרת על החלק הראשון והאחרון בשרשרת זו ומחליפה את התווך. הקומפוננטות שלכם עדיין קוראות ל-useTranslations("about"); מה שהן מקבלות בפועל מגיע ממילון Intlayer שקומפל בזמן build, מתוחם בדיוק לאותה קומפוננטה, ובשפה הפעילה בלבד.

    שלושה מנגנונים גורמים לזה לעבוד:

    1. כינויי ייבוא (Import aliasing): הפונקציה createNextIntlPlugin() מתוך @intlayer/next-intl/plugin עוטפת את withIntlayer ומוסיפה כינויים ל-Webpack ול-Turbopack כך ש-next-intl, ‏next-intl/server, ‏next-intl/navigation ו-next-intl/middleware מנותבים אל @intlayer/next-intl. אין צורך לשנות אף שורת ייבוא בקוד שלכם.
    2. JSON כמקור האמת: תוסף syncJSON קורא את קובץ messages/{locale}.json הקיים שלכם, מפצל את המפתחות ברמה העליונה למילון נפרד לכל namespace, וכותב תרגומים בחזרה לאותם קבצים בדיוק כאשר ה-CLI או ה-CMS מעדכנים אותם. תהליך העבודה של המתרגמים נותר ללא שינוי.
    3. קישור ברמת מוקד הקריאה (Call-site binding): שלב האופטימיזציה של Intlayer (דרך Babel או SWC) משכתב את הקריאה useTranslations("about") לקריאה שמקבלת ישירות את מילון about. הקומפוננטה אינה ניגשת עוד לעץ הודעות גלובלי, אלא אך ורק לתוכן שלה.
    app/[locale]/about/page.tsx
    // הקוד שלכם, ללא שינוי
    import { useTranslations } from "next-intl";
    
    const AboutPage = () => {
      const t = useTranslations("about");
      return <h1>{t("title")}</h1>;
    };
    
    מה שהקומפיילר מפיק (בגרסה מופשטת)
    import _dicHash_about from "../.intlayer/dictionaries/about.mjs";
    import { useDictionary as useTranslations } from "@intlayer/next-intl";
    
    const AboutPage = () => {
      const t = useTranslations(_dicHash_about);
      return <h1>{t("title")}</h1>;
    };
    

    שכתוב זה הוא הסיבה לכך שגודל הקומפוננטה ודליפת הדפים מצטמצמים: דף מושך אך ורק את המילונים של הקומפוננטות שהוא מרנדר, ורק בשפה המוגשת באותו רגע.

    מה המתאם שומר, ממה הוא מתעלם ומה אינו מוחלף

    ה-API של next-intlעם @intlayer/next-intl
    useTranslations("ns") / getTranslations("ns")✅ נשמר. נקשר למילון ns בזמן build. המפתחות מוקלדים ומאומתים מול התוכן שלכם.
    getTranslations({ locale, namespace })✅ נשמר
    t("key", { name }), t.rich(), t.markup(), t.raw()✅ נשמר. צורות רבים ב-ICU, ‏select, ‏selectordinal, ‏#, ‏{ts, date, long} מעובדים דרך מפענח ה-ICU של Intlayer
    useLocale() / getLocale() / setRequestLocale() / setLocale✅ נשמר
    useFormatter()✅ נשמר. dateTime, number, relativeTime, list, dateTimeRange מגשרים ל-Intl המקורי
    NextIntlClientProvider✅ נשמר. הפרופס messages, timeZone ו-now מתקבלים אך מתעלמים מהם (אזהרת פיתוח תציין זאת)
    getMessages()✅ נשמר לצורכי תאימות; אינו נחוץ עוד
    getRequestConfig() ב-src/i18n.ts⚠️ אינו נחוץ. המילונים מתקמפלים בזמן build; אין טעינת הודעות לכל בקשה
    defineRouting()✅ נשמר. שדות שלא צוינו (locales, defaultLocale, localePrefix) נקראים מתוך intlayer.config.ts
    createNavigation(), Link, redirect, usePathname, useRouter✅ נשמר. ממומש מחדש על גבי תצורת הניתוב של Intlayer; הארגומנט routing מתקבל אך מתעלמים ממנו
    pathnames (שמות נתיבים מתורגמים)❌ מתקבל עבור בדיקת טיפוסים, אינו מפוענח. שמרו על נתיבים רגילים או העבירו מיפוי זה ל-rewrite של Intlayer
    createMiddleware()✅ נשמר. מחזיר את הפרוקסי של Intlayer; מגדיר את ה-cookie בשם NEXT_LOCALE כדי ש-useLocale() והמחליף ימשיכו לעבוד
    עוגיית NEXT_LOCALE✅ נקראת כברירת מחדל (אלא אם הגדרתם את routing.storage בעצמכם)
    שימוש ב-useTranslations() ללא ציון namespace⚠️ עובד, אך מוקד הקריאה אינו נקשר מראש: הוא מפוענח דרך רישום בזמן ריצה. ציינו namespace כדי ליהנות מהחיסכון ב-bundle

    מבחן הביצועים (Benchmark)

    מה נבדק

    חבילת Benchmark Bloom בונה את אותו יישום בדיוק בכל הגדרה: 10 דפים (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 שפות (en, fr, es, de, it, pt, zh, ja, ko, ru), קומפוננטות זהות ותוכן זהה. הדפים נמדדים ב-en וב-fr.

    next-intl נבנתה בארבע אסטרטגיות טעינה שונות, מהתצורה הנאיבית (קובץ messages/{locale}.json נטען במלואו) ועד לאופטימלית (namespace אחד לכל נתיב + pick() לכל דף). המתאם נבנה על אותן קומפוננטות של התצורה הנאיבית, כאשר שונו רק next.config.ts ו-intlayer.config.ts. אין צורך בגרסת "scoped" ייעודית: הקומפיילר תוחם תוכן לכל קומפוננטה, כך ששורות ה-static וה-dynamic כבר מבודדות וממוטבות מראש.

    לכל בנייה, חבילת הבדיקות מודדת:

    • גודל ספרייה (Lib size): משקל gzip של קומפוננטה ריקה שמייבאת רק את ספריית ה-i18n (העלות הקבועה של זמן הריצה).
    • ממוצע JS לדף (Page JS): משקל ה-JavaScript המורד ב-gzip לכל דף, בממוצע על פני כל הדפים והשפות.
    • אחוז דליפת שפה (Locale leak %): חלקן של מחרוזות מתורגמות ב-JS שהורד השייכות לשפה שהמשתמש אינו צופה בה.
    • אחוז דליפת דפים (Page leak %): חלקן של מחרוזות מתורגמות ב-JS שהורד השייכות לדף שהמשתמש אינו נמצא בו.
    • ממוצע לקומפוננטה (Component avg): משקל ממוצע ב-gzip של כל קומפוננטה כשהיא מקומפלת בבידוד.
    • תגובתיות מקצה לקצה (E2E reactivity): זמן שעון בין בחירת שפה חדשה לעדכון html[lang] ב-DOM (נבדק ב-Playwright, ממוצע של 5 חזרות).
    • הידרציה (Hydration): משך שלב ההידרציה של React.
    הנתונים להלן מגיעים מהרצה מיום 12 בספטמבר 2026 עם next-intl / use-intl 4.14.2 ו-@intlayer/* 9.5.1. יישום הבדיקה קטן במכוון (עשרות בודדות של מחרוזות לכל שפה), כך שאחוזי הדליפה מתארים דפוס עקרוני: הם צומחים ככל שנפח התוכן גדל, בעוד שעלות זמן הריצה נשארת קבועה.

    תוצאות ב-Next.js

    מדד

    טעינת JSON דינמית

    טעינה עצלה של תרגומים בזמן ריצה

    JSON תחום (namespacing)

    מרחבי שמות תרגום לכל דף

    מהו המדד הזה?

    הגודל הכולל לאחר דחיסת gzip של ה-bundle של ספריית הבינאום. הוא כולל רק את ה-provider ואת לוגיקת שליפת התוכן לאחר tree-shaking ומיזעור.

    למה זה חשוב?

    ספרייה קטנה יותר מקטינה את מטען ה-JavaScript ההתחלתי, מה שמוביל לזמני הורדה והרצה מהירים יותר בצד הלקוח.

    הצגה כ

    הגדרהאסטרטגיהגודל ספרייה (gz)ממוצע JS לדף (gz)דליפת שפהדליפת דפיםממוצע לקומפוננטה (gz)תגובתיות E2Eהידרציה
    בסיס (ללא i18n)-0.0 KB141.0 KB0.0%0.0%0.9 KB13.4 ms11.8 ms
    next-intlstatic14.7 KB153.6 KB4.2%89.8%21.8 KB16.0 ms14.7 ms
    next-intldynamic14.7 KB153.6 KB9.7%89.9%21.8 KB15.6 ms14.8 ms
    next-intlscoped-static14.7 KB153.6 KB0.0%0.0%80.1 KB17.9 ms17.4 ms
    next-intlscoped-dynamic14.7 KB153.6 KB0.0%0.0%22.9 KB17.8 ms16.8 ms
    @intlayer/next-intlstatic8.0 KB147.5 KB0.0%0.0%8.1 KB14.5 ms12.8 ms
    @intlayer/next-intldynamic8.0 KB148.7 KB0.0%0.0%8.1 KB11.7 ms12.8 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

    כיצד לקרוא את התוצאות

    • אותן קומפוננטות, 6 KB פחות לדף: בניית האפליקציה הנאיבית עם המתאם מגיעה ל-147.5 KB, פחות מכל תצורה של next-intl כולל התצורה הממוטבת ביותר (153.6 KB). ההבדל נובע ישירות ממשקל זמן הריצה: 8.0 KB לעומת 14.7 KB, המשולמים בכל דף.
    • הדליפה יורדת ל-0% מבלי לגעת בקומפוננטות: המערך הנאיבי ב-next-intl שולח כ-90% מחרוזות מדפים זרים בכל דף. הגעה ל-0% ב-next-intl מחייבת מעבר לתצורות scoped-*: יצירת namespace לכל נתיב והפעלת pick(messages, [...]) בכל דף. המתאם מגיע ל-0% ישירות מהקוד הנאיבי משום ששלב האופטימיזציה קושר כל קריאת useTranslations("ns") למילון הייעודי שלה.
    • קומפוננטות מתכווצות פי 2.7: קומפוננטה המקומפלת בבידוד שוקלת בממוצע 21.8 KB ב-next-intl (משום שהיא מקושרת ל-provider ולעץ ההודעות כולו) לעומת 8.1 KB עם המתאם. בתצורת scoped-static של next-intl מספר זה אף מזנק ל-80 KB.
    • הידרציה מהירה יותר ב-2 ms (12.8 לעומת 14.7 ms): אין צורך לבצע דה-סריאליזציה לאובייקט הודעות גדול מתוך נתוני ה-RSC לפני ש-React יכולה לבצע הידרציה.
    • המתאם אינו זמן הריצה הטבעי: next-intlayer מגיעה ל-141.3 KB, תוספת של 0.3 KB בלבד מעל אפליקציית הבסיס, עם זמן ריצה של 5.5 KB. המתאם נושא את מעטפת ה-API של next-intl (כגון useFormatter, t.rich, ומפענח ה-ICU) על גבי ליבת Intlayer, ומכאן 8.0 KB ותוספת של 6 KB לדף. הוא מהווה גשר מצוין, ולא היעד הסופי.
    הטבלה המלאה זמינה ב-דוח ה-benchmark של Next.js.

    תוצאות ב-TanStack Start (use-intl)

    use-intl היא ליבת הספרייה הבלתי-תלויה של next-intl. המתאם שלה, @intlayer/use-intl, פועל לפי אותו עקרון באמצעות תוסף Vite (@intlayer/use-intl/plugin).

    הגדרהאסטרטגיהגודל ספרייה (gz)ממוצע JS לדף (gz)דליפת שפהדליפת דפיםממוצע לקומפוננטה (gz)תגובתיות E2Eהידרציה
    בסיס (ללא i18n)-0.0 KB111.0 KB0.0%0.0%0.7 KB8.1 ms21.6 ms
    use-intlstatic14.1 KB179.8 KB50.0%89.8%76.0 KB6.7 ms15.3 ms
    use-intldynamic14.1 KB119.4 KB0.0%89.8%75.9 KB7.0 ms15.4 ms
    use-intlscoped-static14.1 KB128.7 KB0.0%0.0%87.1 KB20.9 ms24.8 ms
    use-intlscoped-dynamic14.1 KB128.7 KB0.0%0.0%87.1 KB13.3 ms25.9 ms
    @intlayer/use-intlstatic7.3 KB135.8 KB49.7%0.0%10.9 KB4.2 ms10.5 ms
    @intlayer/use-intldynamic7.3 KB129.7 KB0.0%0.0%9.3 KB8.7 ms16.1 ms
    intlayer (טבעי)static5.0 KB125.8 KB50.0%0.0%8.1 KB3.2 ms11.5 ms
    intlayer (טבעי)dynamic5.0 KB118.6 KB0.0%0.0%6.3 KB3.6 ms14.1 ms

    כיצד לקרוא את התוצאות

    • במשקל הבתים לדף התוצאה כמעט זהה מול use-intl הממוטבת. @intlayer/use-intl במצב dynamic ‏(129.7 KB) קרובה בטווח של 1 KB ל-use-intl ב-scoped-dynamic ‏(128.7 KB). שורת ה-dynamic הפשוטה של use-intl אמנם קלה יותר (119.4 KB), אך היא מדליפה 90% ממחרוזות הדפים הזרים. ה-0% דליפה של המתאם הוא מה ששומר על גודל קבוע ככל שהתוכן צומח.
    • קומפוננטות קטנות פי 7-9: קומפוננטות use-intl שוקלות בממוצע 76-87 KB בכל אסטרטגיה, משום ש-useTranslations קשורה לכל אובייקט ההודעות של ה-provider. המתאם מוריד זאת ל-9-11 KB.
    • החלפת שפה מהירה בהרבה: התצורות הממוטבות של use-intl דורשות 13-21 ms לעדכון html[lang]; המתאם דורש 4-9 ms בלבד.
    • שורת static שומרת על כל השפות: במצב static המתאם מציג 49.7% דליפת שפה, בדיוק כמו Intlayer הטבעית במצב זה. שורת הגדרה בודדת (importMode: 'dynamic') מסירה זאת לחלוטין.
    הטבלה המלאה זמינה ב-דוח ה-benchmark של TanStack Start.

    מדוע המספרים משתנים

    קומפיילר Intlayer מחלץ תוכן מקומפוננטות

    שום דבר בקומפוננטה עצמה לא השתנה, ולכן השיפורים נובעים במלואם מהגורם שאליו useTranslations קשורה.

    עם next-intl, הקישור נעשה דרך ה-provider. ‏NextIntlClientProvider מקבל את כל אובייקט ה-messages עבור השפה; כל קריאת useTranslations("about") קוראת ממנו. ה-bundler רואה קומפוננטה שמייבאת hook יחיד הקורא מ-context אחד, ואינו יכול לדעת שנעשה שימוש רק בענף של about. כל הנתיבים חולקים את אותו אובייקט הודעות, ולכן דליפת הדפים עומדת על כ-90% עד שמפצלים את הקבצים ידנית, והבזבוז גדל בשני הצירים במקביל:

    דליפת תוכן תיאורטית לפי ארכיטקטורה

    bash
    .
    ├── messages
    │   ├── en.json                       # כל ה-namespaces, כל הדפים
    │   └── fr.json
    └── src
        ├── i18n.ts                       # getRequestConfig({ messages: await import(...) })
        ├── middleware.ts                 # createMiddleware(routing)
        └── app/[locale]
            ├── layout.tsx                # <NextIntlClientProvider messages={messages}>
            └── about/page.tsx            # useTranslations("about")
    

    עם @intlayer/next-intl, הקישור נעשה ברמת המילון. תוסף syncJSON הופך את messages/en.json למילון נפרד לכל מפתח ראשי; הקומפיילר מזהה איזו קומפוננטה קוראת ל-useTranslations("about") ומעביר לה ישירות את מילון about, בשפה הפעילה, כייבוא שניתן למעקב ולפיצול ב-bundler.

    bash
    .
    ├── intlayer.config.ts                # syncJSON({ source: ({ locale }) => `./messages/${locale}.json` })
    ├── messages
    │   ├── en.json                       # ללא שינוי, עדיין מקור האמת
    │   └── fr.json
    ├── .intlayer/                        # נוצר אוטומטית: מילון אחד לכל namespace, לכל שפה
    └── src
        ├── middleware.ts                 # createMiddleware() מחזיר כעת את הפרוקסי של Intlayer
        └── app/[locale]
            ├── layout.tsx                # <NextIntlClientProvider> (ללא פרופ messages)
            └── about/page.tsx            # useTranslations("about")  ← ללא שינוי
    

    הקובץ src/i18n.ts והפרופ messages נעלמים. כל השאר נשאר זהה לחלוטין.

    הגירה בשלושה שלבים

    1. התקנה

      bash
      npx intlayer init --interactive
      

      הפקודה מזהה את next-intl ומתקינה את intlayer, ‏next-intlayer, ‏@intlayer/next-intl ואת @intlayer/sync-json-plugin. השאירו את next-intl מותקנת: היא peer dependency של המתאם ומספקת את הטיפוסים.

    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: {
          // "static" אורז את כל השפות; "dynamic" טוען את השפה הפעילה לפי דרישה
          importMode: "dynamic",
        },
        plugins: [
          syncJSON({
            // מחזיקי מקום ב-ICU: {name}, {count, plural, one {# item} other {# items}}
            format: "icu",
            source: ({ locale }) => `./messages/${locale}.json`,
            location: "messages",
          }),
        ],
      };
      
      export default config;
      

      הקבצים messages/{locale}.json נשארים במקומם. כל מפתח ראשי הופך למילון; useTranslations("about") ממופה למילון about.

    3. עטיפת next.config.ts

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

      הפונקציה createNextIntlPlugin() משלבת את withIntlayer (מעקב תוכן, קימפול מילונים, שלב האופטימיזציה) ואת הכינויים של next-intl ל-@intlayer/next-intl עבור Webpack ו-Turbopack. בצעו build, והתוצאות בטבלאות שלעיל שלכם.

    מה ניתן למחוק לאחר מכן

    קובץ / דפוססיבה
    getRequestConfig ב-src/i18n.tsאין צורך בטעינת הודעות לכל בקשה. השאירו את הקובץ רק אם הוא מייצא עזרי createNavigation
    messages={...} ב-NextIntlClientProviderהמתאם קורא פלט מקומפל; מתעלמים מהפרופ והוא מתריע באזהרה בסביבת פיתוח
    await getMessages() ב-layoutsמאותה סיבה בדיוק
    שימוש ב-pick(messages, [...]) לכל דףהקומפיילר מבצע את הסינון והבחירה באופן אוטומטי, ברמת הקומפוננטה

    מה מרוויחים מעבר לחיסכון בבתים

    • מפתחות בעלי טיפוסים קפדניים: הקריאה useTranslations("about") מוקלדת ומאומתת מול מילון about. קריאה ל-t("does.not.exist") הופכת לשגיאת TypeScript ברורה, ולא לנפילת ריצה שקטה.
    • npx intlayer test מכשיל את ה-CI כאשר בשפה מסוימת חסר מפתח. npx intlayer fill מתרגם מפתחות חסרים באמצעות הספק לבחירתכם (OpenAI, Anthropic, Mistral, Gemini...) באמצעות המפתח שלכם, וכותב את התוצאה בחזרה ל-messages/{locale}.json.
    • העורך החזותי וה-CMS פועלים על אותם מילונים, כך שמשתמשים ללא רקע טכני יכולים לערוך את messages/fr.json דרך ממשק גרפי והקובץ מתעדכן.
    • מעבר הדרגתי ל-.content.ts: כל קומפוננטה יכולה לעבור מ-useTranslations("about") ל-useIntlayer("about") עם קובץ תוכן צמוד, קומפוננטה אחר קומפוננטה. מילוני JSON ו-.content.ts מתקיימים במקביל ומתמזגים.

    מגבלות שיש להכיר לפני שמתחילים

    הפונקציות createNavigation(routing) ו-createMiddleware(routing) שומרות על החתימה שלהן אך מתעלמות מהארגומנט: השפות, שפת ברירת המחדל ואסטרטגיית הקידומת מגיעות מהגדרות ה-routing של Intlayer. אם אתם משתמשים ב-pathnames מתורגמים של next-intl (למשל מ-/about ל-/a-propos), המתאם אינו מפענח אותם ישירות; תכונת ה-routing.rewrite של Intlayer מכסה מקרה זה, אך מדובר בהגדרה נפרדת.

    שלב האופטימיזציה זקוק ל-namespace סטטי כדי לדעת איזה מילון לייבא. קריאה ריקה עדיין עובדת, אך דרך רישום בזמן ריצה שמפנה לכל המילונים, שזו בדיוק הדליפה שרציתם למנוע. הקפידו להעביר את ה-namespace.

    8.0 KB של זמן ריצה לעומת 5.5 KB עבור next-intlayer, ותוספת של כ-6-7 KB לדף לעומת הבנייה הטבעית. זהו המחיר של תמיכה במעטפת ה-API של next-intl. ברגע שכל הקומפוננטות הועברו ל-useIntlayer, ניתן להסיר את המתאם לחלוטין.

    מעבדי הפורמט מגובים ב-Intl המקורי ורק השפה משפיעה על הפלט שלהם. אם אתם מסתמכים על אזור זמן כפוי או על ערך now קבוע עבור תאריכים יציבים בהידרציה, טפלו בכך במוקד הקריאה. ראו עיצוב תאריכים, זמנים ומספרים.

    מתי להשתמש בכל אפשרות?

    האפליקציה שלכם קטנה, גודל ה-bundle אינו מהווה דאגה, והצוות שלכם מרגיש בנוח עם ניהול ידני של namespaces ו-pick() בכל דף.

    אתם עובדים כיום עם next-intl ורוצים את היתרונות של bundle קל, 0% דליפה, הידרציה מהירה, מפתחות מוקלדים וכלי CLI / CMS ללא צורך בשכתוב קוד. זוהי נקודת הכניסה המומלצת לכל בסיס קוד קיים של next-intl.

    עבור פרויקטים חדשים, או לאחר שהמתאם השלים את משימת ההגירה. זוהי האפשרות הקלה ביותר (5.5 KB, תוספת של 0.3 KB לדף מעל יישום בסיס) הפותחת תמיכה מלאה ב-Server Components סינכרוניים, קובצי .content.ts לכל קומפוננטה וארגז הכלים המלא. התחילו עם Intlayer עם Next.js.

    שאלות נפוצות (FAQ)

    ב-Next.js, כן לחלוטין עבור הקומפוננטות: הבנייה במבחן הביצועים שינתה אך ורק את next.config.ts ואת intlayer.config.ts. הפונקציה getRequestConfig ב-src/i18n.ts, הפרופ messages ב-provider וקריאות pick() בכל דף הופכים לקוד לא פעיל שתוכלו למחוק.

    הן ממשיכות לעבוד כרגיל. t("key", { count }), t.rich(), t.markup(), select, selectordinal, # ו-{ts, date, long} מפוענחים על ידי מפענח ה-ICU של Intlayer. ראו הסבר על פורמט הודעות ICU.

    הוא נושא את מעטפת ה-API של next-intl על גבי הליבה של Intlayer: useFormatter, t.rich, מפענח ה-ICU ועוזרי הניווט. מדובר ב-8.0 KB לעומת 5.5 KB, ותוספת של כ-6 KB לדף. הוא משמש כגשר מעבר ולא כיעד הסופי.

    כן. כל קומפוננטה יכולה לעבור מ-useTranslations("about") ל-useIntlayer("about") עם קובץ .content.ts צמוד. מילוני JSON ו-.content.ts מתקיימים זה לצד זה ומתמזגים באופן שקוף.

    לא דרך הגדרת ה-pathnames של next-intl: המתאם מקבל אותה עבור בדיקת טיפוסים בלבד, אך אינו מפענח אותה. השתמשו ב-routing.rewrite של Intlayer במקום זאת.

    השוואות קשורות

    סדרת מתאמי התאימות:

    השוואת הספריות ראש בראש:

    תיעוד ומדריכים:

    דוחות benchmark:

    כדי להבין את מקורן של ספריות אלו, קראו על ההיסטוריה של בינאום ב-JavaScript.

    סיכום

    @intlayer/next-intl עושה דבר אחד מרכזי: היא משנה את הגורם שאליו useTranslations קשורה, מ-provider המחזיק בכל ההודעות למילון שקומפל במיוחד עבור אותה קומפוננטה. באותו יישום Next.js הדבר מביא לחיסכון של 6 KB לדף, קומפוננטות קטנות פי 2.7, 0% דליפת תוכן וקיצור של 2 ms במשך ההידרציה, עוד לפני שפותחים קובץ קומפוננטה כלשהו. הניתוב וה-middleware שומרים על ה-API המוכר שלהם על גבי תצורת הניתוב של Intlayer, וזמן הריצה הטבעי של next-intlayer נשאר קל אף יותר.

    כל הנתונים הגולמיים, יישומי הבדיקה והסקריפטים זמינים במאגר Benchmark Bloom. הריצו אותם בעצמכם.

    עיינו במסמך 'למה Intlayer?' לפרטים נוספים.

    תגובות

    עדיין אין תגובות. היו הראשונים לשתף את מחשבותיכם.

    פוסטים קשורים

    פוסטים אחרונים