Локалізація Vue-додатку — це не просто переклад рядків. На одному з проєктів з 8 мовами ми отримали роздутий бандл на 2 мегабайти лише через статичне завантаження всіх перекладів. Клієнт скаржився на повільний TTFB та низький LCP. Довелося переписувати на ліниве завантаження — бандл зменшився в 5 разів, метрики Core Web Vitals прийшли в норму. Така історія повторюється часто: розробники недооцінюють вплив перекладів на продуктивність.
Правильне налаштування vue-i18n вирішує не лише проблеми з розміром бандла, а й типові помилки: неправильна плюралізація для української мови, конфлікти з SSR при гідратації, відсутність типізації ключів. Наш досвід — 5+ років роботи з Vue та понад 20 проєктів з локалізації — гарантує надійне рішення, яке працює з першого разу.
Офіційна документація vue-i18n рекомендує використовувати Composition API та ліниве завантаження для великих проєктів. Ми дотримуємося цього підходу та адаптуємо його під конкретні завдання.
Чому варто використовувати vue-i18n?
Vue I18n — офіційне розширення, повністю інтегроване з Vue 3. Воно підтримує Composition API, ліниве завантаження, форматування дат/чисел та SSR через Nuxt. Порівняно з саморобними рішеннями, vue-i18n дає готові механізми плюралізації та інтерполяції, що скорочує час розробки вдвічі. Крім того, це галузевий стандарт для екосистеми Vue.
Як вирішити проблему гідратації з SSR?
При SSR Vue I18n може викликати помилки гідратації через неспівпадіння локалей на сервері та клієнті. Рішення — синхронізувати локаль через cookie або заголовок запиту, а також використовувати sync: false у конфігурації. В Nuxt модуль @nuxtjs/i18n робить це автоматично, зчитуючи локаль з accept-language та зберігаючи в cookie.
Приклад конфігурації з cookie
// nuxt.config.ts export default defineNuxtConfig({ i18n: { detectBrowserLanguage: { useCookie: true, cookieKey: 'i18n_redirected', alwaysRedirect: true } } }) Коли потрібне ліниве завантаження перекладів?
Для додатків з десятками локалей завантажувати всі переклади одразу на старті — непозволима розкіш. Початковий бандл може вирости на мегабайти, що критично для LCP та TTI. Ліниве завантаження завантажує лише актуальну мову, а решту — на вимогу. Це зменшує розмір бандла в 4–10 разів залежно від кількості мов.
| Підхід | Розмір бандла (10 мов) | Час завантаження | UX |
|---|---|---|---|
| Статичне завантаження | ~1 MB | 2 секунди | - |
| Ліниве завантаження | ~100 KB | 0.3 секунди | + |
Як ми налаштовуємо vue-i18n?
Встановлення та базова конфігурація
npm install vue-i18n@9 // src/i18n/index.ts import { createI18n } from 'vue-i18n' import ru from './locales/ru.json' import en from './locales/en.json' export type MessageSchema = typeof ru const i18n = createI18n<[MessageSchema], 'ru' | 'en'>({ legacy: false, locale: 'ru', fallbackLocale: 'en', messages: { ru, en }, datetimeFormats: { ru: { short: { day: 'numeric', month: 'short', year: 'numeric' } }, en: { short: { month: 'short', day: 'numeric', year: 'numeric' } } }, numberFormats: { ru: { currency: { style: 'currency', currency: 'RUB' } }, en: { currency: { style: 'currency', currency: 'USD' } } } }) export default i18n Основні можливості
- Плюралізація: підтримує до 4 форм для української мови.
- Форматування дат та чисел: вбудовані форматери з прив'язкою до локалі.
- TypeScript: строга типізація ключів через MessageSchema.
- Ліниве завантаження: завантажуємо переклади лише для поточної мови.
Як організувати ліниве завантаження перекладів?
Для великих додатків критично не грузити всі переклади одразу. Реалізуємо через динамічний імпорт:
// src/i18n/index.ts const i18n = createI18n({ legacy: false, locale: 'ru', messages: { ru } }) const loaded = new Set(['ru']) export async function loadLocale(locale: string) { if (loaded.has(locale)) return const msgs = await import(`./locales/${locale}.json`) i18n.global.setLocaleMessage(locale, msgs.default) loaded.add(locale) } Використовуємо в роутері:
router.beforeEach(async (to) => { const locale = to.params.locale || 'ru' await loadLocale(locale) i18n.global.locale.value = locale }) Чим відрізняється налаштування для Nuxt?
Для Nuxt використовуємо офіційний модуль, який автоматично інтегрується з vue-i18n, підтримує SSR та SEO. Конфігурація мінімальна:
// nuxt.config.ts export default defineNuxtConfig({ modules: ['@nuxtjs/i18n'], i18n: { locales: [ { code: 'ru', language: 'ru-RU', file: 'ru.json', name: 'Русский' }, { code: 'en', language: 'en-US', file: 'en.json', name: 'English' } ], defaultLocale: 'ru', lazy: true, langDir: 'locales/', strategy: 'prefix_except_default' } }) Що входить у налаштування i18n?
| Етап | Тривалість | Результат |
|---|---|---|
| Аналіз вимог | 0.5 дня | Список мов, ключі, формат |
| Конфігурація плагіна | 0.5 дня | Працююча базова локалізація |
| Інтеграція з роутером | 1 день | Локалізовані маршрути |
| Налаштування лінивого завантаження | 1 день | Мінімальний бандл при старті |
| Тестування | 0.5 дня | Перевірка всіх мов та плюралізації |
Строки та вартість
Базова настройка vue-i18n для 2 мов займає 1 день. Повна інтеграція з Nuxt, лінивим завантаженням та локалізованими маршрутами — 2–3 дні. Вартість визначається після аналізу проєкту — ми оцінюємо обсяг робіт та складність.
Ми супроводжуємо впровадження: допомагаємо розібратися з нюансами плюралізації в українській мові (чотири форми проти двох в англійській), налаштовуємо строгу типізацію ключів через TypeScript та документуємо правила додавання перекладів для всієї команди. Це виключає дублюючі ключі та хардкод рядків у компонентах. У підсумку додавання нової мови займає 2–4 години замість кількох днів.
Отримайте консультацію — зв'яжіться з нами, щоб обговорити деталі. Ми гарантуємо, що після налаштування ваше Vue-додаток коректно відображається на всіх цільових мовах і не втрачає в продуктивності.







