Сервис плагина
createVueI18nPlugin возвращает объект I18nPlugin — он удовлетворяет интерфейсу Plugin из Vue (поэтому app.use(plugin) работает без изменений) и предоставляет свойство .service, доступное в любом месте приложения, включая места вне setup() компонента Vue. Об опциях, передаваемых в сам createVueI18nPlugin, см. Настройка плагина.
import { createVueI18nPlugin } from 'vue-i18n-kit'
export const i18nPlugin = createVueI18nPlugin({
defaultLocale: 'en',
locales: {
en: { messages: () => import('./locales/en.json'), meta: { display: 'English' } },
ru: { messages: () => import('./locales/ru.json'), meta: { display: 'Русский' } },
},
})// router/index.ts — вне setup()
import { i18nPlugin } from '@/i18n'
router.beforeEach(async (to) => {
const lang = to.params.lang as string
if (lang) await i18nPlugin.service.setLocale(lang)
})API service
locale
Ref<string> — текущая активная локаль — тот же экземпляр ref, что и useLocale().locale.
isLoading
Ref<boolean> — true, пока идёт загрузка файла локали.
setLocale
(lang: string) => Promise<void> — переключить локаль. Ленивая загрузка при необходимости. Бросает исключение, если lang не зарегистрирован.
availableLocales
ComputedRef<LocaleInfo[]> — все зарегистрированные локали с их метаданными. Один и тот же computed-экземпляр при каждом обращении.
onLocaleChange
(cb: (lang: string) => void) => () => void — подписаться на переключения локали из любого места — полезно для синхронизации внешнего состояния, которое не может управляться реактивностью Vue. Возвращает функцию отписки.
// Обновить <html lang> при каждом переключении
i18nPlugin.service.onLocaleChange((lang) => {
document.documentElement.lang = lang
})
// Отписаться, когда больше не нужно
const unsubscribe = i18nPlugin.service.onLocaleChange((lang) => {
analytics.track('locale_changed', { lang })
})
unsubscribe()loadNamespace
(ns: string) => Promise<void> — загружает один namespace для активной локали. См. Загрузка namespace — эквивалент в виде composable и общее описание концепции namespace.
isNamespaceLoaded
(ns: string) => boolean — проверяет, загружен ли уже namespace, не запуская загрузку.
service против composables — что когда использовать
setup()компонента Vue —useLocale(),useT(),useAvailableLocales()— реактивные, удобные для шаблонов.- Route guards, хранилища Pinia, служебные модули —
plugin.service— не нуженgetCurrentInstance(). - Точки входа SSR, серверный middleware —
plugin.service— внедрите инстанс плагина из вашего файла плагина.
Замечание об SSR
service хранит состояние в замыкании, создаваемом при вызове createVueI18nPlugin. В SSR плагин должен создаваться на каждый запрос, а не на уровне модуля:
// ✅ Правильно — один инстанс плагина на каждый запрос Nuxt
export default defineNuxtPlugin((nuxtApp) => {
const plugin = createVueI18nPlugin({ ... })
nuxtApp.vueApp.use(plugin)
})// ❌ Неправильно — общий для всех SSR-запросов
const plugin = createVueI18nPlugin({ ... }) // уровень модуля
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(plugin) // plugin.service.locale общий — запросы заражают друг друга
})Обработка ошибок
Неизвестная локаль
setLocale бросает описательную ошибку, если запрошенная локаль не зарегистрирована:
try {
await setLocale('de')
} catch (err) {
// [vue-i18n-kit] Locale "de" is not registered. Available locales: en, ru
console.error(err.message)
}Неудачный сетевой запрос
Если функция-загрузчик отклоняется, setLocale сбрасывает isLoading в false и повторно бросает исходную ошибку. isLoading.value гарантированно равен false после блока catch.
Плагин не установлен
Вызов любого composable до app.use(createVueI18nPlugin(...)) немедленно бросает исключение:
[vue-i18n-kit] Plugin not installed. Call app.use(createVueI18nPlugin(...)) before using composables.