Локалізація 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-додаток коректно відображається на всіх цільових мовах і не втрачає в продуктивності.







