Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту
Вміст цієї сторінки перекладено за допомогою штучного інтелекту.
Переглянути останню версію оригінального вмісту англійськоюЯкщо у вас є ідея щодо покращення цієї документації, будь ласка, долучіться, надіславши pull request на GitHub.
Посилання на документацію на GitHubСкопіювати документацію у форматі Markdown в буфер обміну
i18next проти @intlayer/i18next: Однаковий API, інший bundle

@intlayer/i18next, @intlayer/react-i18next та @intlayer/next-i18next - це адаптери сумісності. Вони надають API i18next, який ваш код уже використовує (useTranslation, t(), <Trans>, i18n.changeLanguage(), getFixedT, serverSideTranslations...) і постачають його зі словників, скомпільованих Intlayer. Компоненти не змінюються. Змінюється середовище виконання (runtime) під ними.
У цій статті вимірюється така заміна на одному й тому ж додатку Next.js, зібраному один раз із next-i18next і один раз із @intlayer/next-i18next. Показники отримані з Benchmark Bloom. Для порівняння i18next та Intlayer як бібліотек прочитайте i18next проти Intlayer. Ця стаття присвячена тому, що саме змінює адаптер, якщо ви зберігаєте свій код без змін.
tl;dr: На тому ж додатку Next.js замінаnext-i18nextна@intlayer/next-i18nextзменшила обсяг JavaScript на сторінку з 218.5 KB до 150.7 KB gzip (базова конфігурація) і перевершила повністю оптимізовану конфігураціюnext-i18next(163.4 KB) на 12.7 KB. Середній компонент зменшився з 78.5 KB до 9.7 KB, витік рядків з інших сторінок скоротився з ~90% до 0%, гідратація прискорилася з 15.6 ms до 11.3 ms, а runtime зменшився з 19.7 KB до 9.4 KB. Жоден компонент не редагувався; змінено лише один файл провайдера. Плагіниi18next(бекенди, детектори мови) приймаються, але нічого не роблять: під час виконання більше нічого завантажувати або визначати.
Що таке @intlayer/i18next
i18next - це середовище виконання (runtime). i18n.init({ resources }) або плагін бекенда завантажує locales/{lng}/{ns}.json у глобальний екземпляр; useTranslation("about") підписує компонент на нього; t("title") шукає ключ під час рендерингу. Простори імен (namespaces), ліниве завантаження (lazy loading), списки просторів імен для кожної сторінки та типобезпека залишаються вашою турботою щодо налаштування та підтримки.
Адаптери зберігають API і замінюють екземпляр:
- Аліаси імпорту.
createNextI18nPlugin()з@intlayer/next-i18next/plugin(абоwithI18next) огортаєwithIntlayerта додає аліаси Webpack / Turbopack, завдяки чомуnext-i18next,react-i18nextтаi18nextрезолвляться до відповідників@intlayer/*. У VitereactI18nextVitePlugin()з@intlayer/react-i18next/pluginробить те саме. Жоден імпорт не перейменовується. - JSON як єдине джерело правди. Плагін
syncJSONзчитує наявні файлиlocales/{lng}/{ns}.jsonзformat: "i18next"(завдяки чому{{name}}, вкладеність$t(), суфікси_one/_otherі контексти парсяться коректно) і записує переклади назад, коли CLI або CMS оновлюють їх. - Зв'язування у місці виклику (call-site binding). Етап оптимізації Intlayer переписує
useTranslation("about")у виклик, який отримує словникaboutнапряму, в активній локалі. Компонент більше не звертається до глобального сховища.
Скопіюйте код у буфер обміну
Скопіюйте код у буфер обміну
Саме це переписування визначає показники у стовпчиках розміру компонентів та витоку сторінок нижче.
Що адаптери зберігають, ігнорують і не замінюють
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
API 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 ігнорується з попередженням dev; видаліть імпорти JSON, щоб отримати оптимізацію bundle |
I18nextProvider i18n={i18n} | ⚠️ Рендерить IntlayerProvider; проп i18n ігнорується. В App Router передавайте locale (див. нижче) |
serverSideTranslations(locale, ["common"]) (next-i18next) | ⚠️ Повертає очікувану структуру і нічого не завантажує. Безпечно залишити або видалити |
appWithTranslation(App) (next-i18next) | ✅ Збережено |
next-i18next.config.js | ⚠️ Не зчитується. Локалі надходять з intlayer.config.ts |
Простий useTranslation() без простору імен | ✅ Працює зі словником translation для всього файлу (splitKeys: false) |
Бенчмарк
Що вимірювалося
Набір тестів Benchmark Bloom збирає один і той самий додаток з кожною конфігурацією: 10 сторінок (головна, про нас, блог, кар'єра, контакти, FAQ, ціни, продукти, налаштування, команда), 10 локалей (en, fr, es, de, it, pt, zh, ja, ko, ru), однакові компоненти й однаковий вміст. Сторінки вимірюються в en та fr.
next-i18next було зібрано за чотирма стратегіями завантаження: від імпорту JSON кожної локалі в resources (static) до одного простору імен на маршрут з лінивим завантаженням через бекенд (scoped-dynamic). Адаптер зібрано на тих самих компонентах, що й базову конфігурацію, зі зміненими next.config.ts, intlayer.config.ts та файлом провайдера. Він не має варіанту "scoped": компілятор самостійно обмежує контент для кожного компонента.
Для кожної збірки фіксуються такі показники:
- Lib size: розмір gzip порожнього компонента, який імпортує лише бібліотеку i18n.
- Page JS: обсяг JavaScript gzip, завантажений на сторінку, усереднений для всіх сторінок і локалей.
- Locale leak %: частка перекладених рядків у завантаженому JS, що належать локалі, яку користувач не переглядає.
- Page leak %: частка перекладених рядків у завантаженому JS, що належать сторінці, на якій користувач не перебуває.
- Component avg: середній розмір gzip кожного компонента, скомпільованого окремо.
- E2E reactivity: реальний час між вибором нової локалі та оновленням
html[lang]у DOM (Playwright, 5 ітерацій). - Hydration: тривалість фази гідратації React.
Наведені нижче дані отримані під час тестування від 2026-09-12 зnext-i18next16.3.0 (react-i18next17.0.13,i18next26.4.2) та@intlayer/next-i18next9.5.1. Тестовий додаток навмисно невеликий (кілька десятків рядків на локаль), тому відсотки витоку показують закономірність: вони зростають разом із вашим контентом, тоді як накладні витрати runtime залишаються фіксованими.
Результати на Next.js
Виберіть метрики та бібліотеки, які вас цікавлять:
Метрика
Динамічне завантаження JSON
Ледаче завантаження перекладів під час виконання
Обмежений JSON (простори імен)
Простори імен перекладу для кожної сторінки
Що це за метрика?
Загальний стиснений у gzip розмір пакета бібліотеки інтернаціоналізації. Він включає лише провайдер та логіку отримання контенту після tree-shaking та мініфікації.
Чому це важливо?
Менший розмір бібліотеки зменшує початкове завантаження JavaScript, що призводить до швидшого завантаження та виконання на клієнті.
Перегляд як
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Конфігурація | Стратегія | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (без i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
next-i18next | static | 19.7 KB | 218.5 KB | 0.0% | 89.8% | 78.5 KB | 16.4 ms | 15.6 ms |
next-i18next | dynamic | 19.7 KB | 169.5 KB | 50.0% | 89.8% | 26.1 KB | 15.4 ms | 27.7 ms |
next-i18next | scoped-static | 19.7 KB | 220.1 KB | 0.0% | 89.8% | 78.9 KB | 16.4 ms | 14.7 ms |
next-i18next | scoped-dynamic | 19.7 KB | 163.4 KB | 0.0% | 0.0% | 27.1 KB | 15.9 ms | 15.1 ms |
@intlayer/next-i18next | static | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 10.7 ms | 11.3 ms |
@intlayer/next-i18next | dynamic | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 11.9 ms | 10.6 ms |
next-intlayer (native) | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
next-intlayer (native) | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
Як інтерпретувати результати
- На 68 KB менше на сторінку порівняно з базовою конфігурацією.
resources: { en, fr, ... }передає кожну локаль і кожен простір імен на кожній сторінці: 218.5 KB. Збірка адаптера для тих самих компонентів становить 150.7 KB. Вона також перевершує найкращу конфігураціюnext-i18next(163.4 KB, один простір імен на маршрут, ліниве завантаження) на 12.7 KB, оскільки лише runtimei18nextважить 19.7 KB проти 9.4 KB. - Витік знижується до 0% без жодних змін у компонентах. Кожна конфігурація
next-i18next, крім повністю ізольованої (scoped), передає ~90% рядків сторонніх сторінок. Рядокdynamicвиглядає гірше, ніж здається: він не зменшує витік сторінок і додає 50% витоку локалей, оскільки бекенд для кожної локалі все одно підтягує весь простір іменtranslation. Адаптер досягає 0% / 0% безпосередньо з вихідного коду. - Компоненти: у 8 разів менші. Компонент з
useTranslation(), скомпільований ізольовано, важить у середньому 78.5 KB із вбудованимиresourcesта 26-27 KB з бекендом, оскількиtприв'язаний до глобального сховища. З адаптером він важить у середньому 9.7 KB. - Гідратація та перемикання відбуваються швидше. Гідратація скорочується з 15.6 ms до 11.3 ms (та з 27.7 ms у конфігурації
dynamic, де запит до бекенда перебуває на критичному шляху). Перемикання локалі прискорюється з 15-16 ms до 11-12 ms. - Адаптер - це не нативний runtime.
next-intlayerзаймає 141.3 KB, лише +0.3 KB над базовим додатком. Адаптер несе поверхню APIi18next(діалект інтерполяції, суфікси множини та контексту, парсинг тегів<Trans>) поверх ядра Intlayer: 9.4 KB та +9.4 KB на сторінку проти нативного варіанту. Це міст для переходу, а не кінцева точка.
Повна таблиця, кожна бібліотека та кожна стратегія, у звіті про бенчмарк Next.js.
Результати на TanStack Start (react-i18next)
Для Vite і TanStack Start бенчмарк порівнює чистий react-i18next з intlayer:
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Бібліотека | Стратегія | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (без i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms | 21.6 ms |
react-i18next | dynamic | 18.4 KB | 136.4 KB | 23.1% | 89.8% | 24.8 KB | 123.1 ms | 32.9 ms |
intlayer | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms | 14.1 ms |
Повна таблиця у звіті про бенчмарк TanStack Start.
Адаптерreact-i18nextна Vite / TanStack Start не брав участі у цьому тестуванні. Базові показникиreact-i18nextна TanStack Start наведено у статті i18next проти Intlayer: 127-184 KB на сторінку та перемикання локалі за 123-185 ms за наявності лінивого бекенда.
Чому змінюються цифри

У каталозі components/ нічого не змінилося, тож оптимізація пов'язана з тим, до чого саме прив'язаний useTranslation.
З i18next прив'язка здійснюється до глобального екземпляра. Усе, що було в нього завантажено (усі локалі в static, увесь простір імен активної локалі в dynamic), доступне кожному компоненту, що викликає useTranslation(). Бандлер не може розбити бандл нижче за вміст екземпляра, а runtime не може знати наперед, які ключі знадобляться компоненту.
Скопіюйте код у буфер обміну
Все, що містить екземпляр, надсилається на кожну сторінку, і витрати зростають за двома осями, сторінки та локалі:

З @intlayer/next-i18next прив'язка здійснюється до словника. syncJSON перетворює кожен файл простору імен на словник; оптимізаційний етап передає компоненту саме той словник, який йому потрібен, у вигляді імпорту, що бандлер може відстежити й розділити за сторінками та локалями.
Скопіюйте код у буфер обміну
Файл i18n/i18n.ts та його імпорт resources стають мертвим кодом. Звідси й беруться ті самі 68 KB.
Міграція у три кроки
Встановлення
bashКопіювати кодСкопіюйте код у буфер обміну
Команда виявляє
i18next/react-i18next/next-i18next, встановлюєintlayer, пакет відповідного фреймворку (next-intlayerабоreact-intlayer), сумісний адаптер@intlayer/*та@intlayer/sync-json-plugin, а також формує базовийintlayer.config.ts. Залиште оригінальні пакети встановленими: вони є peer dependencies та постачають типи TypeScript.Вкажіть Intlayer на файли локалей
intlayer.config.tsКопіювати кодСкопіюйте код у буфер обміну
Якщо у вас є один файл
translation.jsonна локаль (простір імен за замовчуванням в i18next), установітьsplitKeys: false, щоб увесь файл залишався єдиним словником і звичайний викликuseTranslation()продовжував коректно працювати.Додайте плагін
next.config.tsКопіювати кодСкопіюйте код у буфер обміну
В App Router клієнтські компоненти отримують свою локаль із сегмента
[locale]. КомпонентI18nextProviderадаптера не приймає проп locale, тому замініть його один раз у файлі провайдера:components/AppProviders.tsxКопіювати кодСкопіюйте код у буфер обміну
Кожен компонент нижче в дереві продовжує викликати
useTranslation().vite.config.tsКопіювати кодСкопіюйте код у буфер обміну
reactI18nextVitePlugin()огортаєvite-intlayerта створює аліаси дляreact-i18nextіi18next. Для проєктів без React плагінi18nextVitePlugin()з@intlayer/i18next/pluginстворює аліас тільки дляi18next.
Що можна видалити після цього
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Файл / патерн | Причина |
|---|---|
resources: { en, fr, ... } та імпорти JSON | Ігноруються адаптером. Саме тут крилися зайві 68 KB |
i18next-http-backend, i18next-resources-to-backend | Більше нічого не потрібно завантажувати під час виконання |
i18next-browser-languagedetector | Визначення локалі виконується маршрутизацією Intlayer (префікс URL, cookie, заголовок) |
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перекладає відсутні ключі за допомогою вашого API-ключа постачальника (OpenAI, Anthropic, Mistral, Gemini...) та зберігає їх назад уlocales/{lng}/{ns}.json.- Візуальний редактор і CMS працюють із тими самими файлами JSON, тому перекладачі можуть редагувати контент через інтерфейс користувача, а файли оновлюються автоматично.
- Поступовий перехід на
.content.ts. Будь-який компонент можна перевести зuseTranslation("about")наuseIntlayer("about")із супутнім файлом контенту. Словники JSON та.content.tsможуть мирно співіснувати.
Обмеження, які слід врахувати перед початком
i18n.use(HttpBackend) викликає init плагіна і більше нічого. Якщо ваш додаток покладався на отримання перекладів з CMS під час виконання, цей процес більше не працює; використовуйте Intlayer CMS або команди intlayer pull / push. Визначення локалі стає конфігурацією маршрутизації Intlayer (префікс URL, cookie, заголовок).
На відміну від деяких інших адаптерів, @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 |
| Розмір runtime (gzip, Next.js) | 19.7 KB | 9.4 KB | 5.5 KB |
| Витік інших сторінок без ручних namespaces | ~90% | 0% | 0% |
| Типізовані ключі | ⚠️ Ручне оголошення | ✅ Зі скомпільованих словників | ✅ Генеруються автоматично |
| Runtime-бекенди та плагіни | ✅ Повна екосистема плагінів | ❌ Неактивні | ❌ Не застосовується, використовуйте CMS |
| Контент поруч із компонентами | ❌ Централізований JSON | ⚠️ JSON, .content.ts може співіснувати | ✅ .content.ts поруч із кожним компонентом |
| Відсутні переклади в CI | ⚠️ Немає вбудованої підтримки | ✅ npx intlayer test | ✅ npx intlayer test |
| AI-переклад | ❌ Ні | ✅ npx intlayer fill | ✅ npx intlayer fill |
| Візуальний редактор / CMS | ❌ Через зовнішні платформи | ✅ На тому самому JSON | ✅ Так |
| Екосистема / спільнота | ✅ Дуже велика | ⚠️ Менша, швидко зростає | ⚠️ Менша, швидко зростає |
Розміри runtime взято з описаного вище прогону на 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() продовжує розпізнаватися відносно нього.
Ні, це міст. Адаптер зберігає API 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 - найважчий runtime у цьому бенчмарку, і адаптери усувають більшу частину цього тягаря, не вимагаючи відмовлятися від знайомого API. На одному й тому ж додатку Next.js ви отримуєте на 68 KB менше на кожну сторінку, ніж у базовому налаштуванні, на 12.7 KB менше, ніж у найкращій оптимізованій вручну версії, у 8 разів менші компоненти, 0% витоків та на 4 ms швидшу гідратацію - ціною одного конфігураційного файлу, одного рядка плагіна та налаштування одного провайдера. Бекенди та детектори стають безпечними no-op, resources ігнорується замість об'єднання, а нативний runtime next-intlayer залишається ще на 9 KB легшим.
Усі необроблені дані, тестові додатки та скрипти доступні у репозиторії Benchmark Bloom. Запустіть і перевірте самі.
Докладніше дивіться в розділі 'Чому Intlayer?'.
Коментарі
Поки що немає коментарів. Будьте першим, хто поділиться своїми думками.
