Переиспользуемый плагин локализации для Vue 3, оборачивающий vue-i18n и предоставляющий готовый слой интеграции — настройте один раз, используйте в каждом проекте.

Пропущенный ключ перевода не ломает сборку и не бросает ошибку — он просто показывает пользователю голый идентификатор вместо текста, и первым это обычно замечает не разработчик, а сам пользователь. vue-i18n-kit проверяет полноту всех локалей прямо при сборке, до того как до этого дойдёт дело.
В английском одна форма множественного числа, в русском — три, в арабском — шесть — для каждого языка автоматически выбирается грамматически верная форма вместо одной строки с подставленным числом.
Опечатку в тексте кнопки можно исправить, даже никогда не открывав редактор кода, — прямо в браузере, с таблицей ключей и живым превью, без доступа к репозиторию.
Пользователь из Германии не должен загружать японский перевод только потому, что сайт поддерживает 12 языков — каждая локаль подгружается отдельно и только тогда, когда она реально нужна.
Сообщение об ошибке в HTTP-перехватчике, текст в хранилище состояния, проверка в функции-страже роутера — перевод остаётся доступным и в тех местах кода, где обычный способ получить текст внутри компонента не сработает.
У каждого клиента — свой набор текстов поверх одной общей базы: часть строк совпадает у всех, часть переопределена под конкретный бренд. Общий словарь можно безопасно слить в клиентские файлы — недостающие строки добавляются, а то, что уже переопределено под бренд, остаётся нетронутым и не затирается по ошибке.
Один разработчик добавил новый экран и забыл перевести его на три из пяти языков — это ловится одной командой, которая сравнивает все локали с эталонной и показывает, каких ключей не хватает, а какие вообще больше не используются.

Подключайте локали через динамический импорт — загружается только активный язык, остальные подтягиваются по требованию. Два метода перевода: t() для простых строк с интерполяцией и tm() для ICU-плюрализации с правильными формами для любого языка (включая арабский).

useLocale даёт доступ к текущему языку, его метаданным (флаг, название) и управлению переключением с индикатором загрузки. useAvailableLocales возвращает список всех зарегистрированных локалей. useFormat оборачивает Intl для форматирования дат, чисел и валют с учётом активной локали.

Плагин проверки сверяет все локали с эталонной на наличие пропущенных или лишних ключей при сборке и в HMR. Плагин инлайна встраивает JSON в бандл, а плагин неймспейсов автоматически разбивает локали на чанки с ленивой загрузкой. Dev-плагин добавляет инспектор перевода с редактированием прямо в интерфейсе.

Интерактивная инициализация, добавление новых локалей, проверка полноты, удаление неиспользуемых ключей, слияние с общей базой, экспорт/импорт XLIFF/PO и отслеживание устаревших переводов. Генерация типа TranslationKey даёт автодополнение и проверку ключей на этапе компиляции во всех composables.

Встроенный браузерный редактор с таблицей ключей, фильтрами, групповыми операциями и живым превью. Автоматический перевод пропущенных строк через LibreTranslate или DeepL. Поддержка базового словаря, блокировки ключей, правил валидации и игнор-листов для точной настройки под проект.

Обращайтесь к переводам из кода вне компонентов — в сторах, guard-функциях роутера, HTTP-интерсепторах — через сервис плагина, доступный без setup(). Подписывайтесь на смену языка через onLocaleChange. Выбранная локаль сохраняется между визитами, а при отсутствии перевода подставляется резервный язык.
messages() — динамический импорт, поэтому в бандл попадает только активный язык. persistLocale: true запоминает выбор пользователя между визитами — ничего вручную сохранять в localStorage не нужно.
import { createApp } from 'vue'
import { createVueI18nPlugin } from 'vue-i18n-kit'
import App from './App.vue'
const app = createApp(App)
app.use(
createVueI18nPlugin({
defaultLocale: 'en',
fallbackLocale: 'en',
locales: {
en: {
messages: () => import('./locales/en.json'),
meta: { display: 'English', flag: '🇬🇧' },
},
ru: {
messages: () => import('./locales/ru.json'),
meta: { display: 'Русский', flag: '🇷🇺' },
},
},
persistLocale: true,
}),
)
app.mount('#app')formatDate/formatNumber/formatCurrency используют нативный Intl, привязаны к текущей локали и сами пересчитываются при её смене — никакого ручного дублирования форматов на каждый язык.
import { useFormat } from 'vue-i18n-kit'
const { formatDate, formatNumber, formatCurrency } = useFormat()
formatDate(new Date(), { dateStyle: 'long' }) // '28 марта 2026 г.' (ru)
formatNumber(1_234_567.89) // '1 234 567,89' (ru)
formatCurrency(1999.99, 'EUR') // '1 999,99 €' (ru)
// Switch the active locale and every formatter re-renders itself — no
// manual re-formatting, no separate en/ru number-formatting code paths. Один ICU-шаблон, а Intl.PluralRules сам выбирает форму — one/few/many/other, а не самодельная цепочка if/else на каждое число.
import { useT } from 'vue-i18n-kit'
const { tm } = useT()
// locale: "{points} {points, plural, one {рубль} few {рубля} many {рублей} other {рублей}}"
tm('balance', { points: 1 }) // → '1 рубль'
tm('balance', { points: 3 }) // → '3 рубля'
tm('balance', { points: 21 }) // → '21 рубль'
tm('balance', { points: 25 }) // → '25 рублей'
// Same template, four different real Russian plural forms — driven by
// Intl.PluralRules under the hood, not a hand-rolled if/else chain.Vite-плагин сверяет все локали с эталонной при каждом сохранении файла и на сборке — пропущенный ключ находится за секунды, а не после жалобы пользователя.
import { vueI18nCheckPlugin } from 'vue-i18n-kit/vite'
export default defineConfig({
plugins: [
vue(),
vueI18nCheckPlugin({
localesDir: 'src/locales',
defaultLocale: 'en',
failOnMissing: true,
}),
],
})
// Runs on every locale-file save (HMR) and again at build start:
//
// [vue-i18n-kit] Incomplete translations detected (reference: "en"):
// Locale "ru":
// Missing keys (2):
// - buttons.cancel
// - profile.title