useLocale
i18n plugin with message translation, number formatting, and locale switching.
Installation
Install the Locale plugin in your app’s entry point:
import { createApp } from 'vue'
import { createLocalePlugin } from '@vuetify/v0'
import App from './App.vue'
const app = createApp(App)
app.use(
createLocalePlugin({
default: 'en',
messages: {
en: {
hello: 'Hello',
welcome: 'Welcome, {name}!',
},
es: {
hello: 'Hola',
welcome: '¡Bienvenido, {name}!',
},
},
})
)
app.mount('#app')Usage
Once the plugin is installed, use the useLocale composable in any component:
<script setup lang="ts">
import { useLocale } from '@vuetify/v0'
const locale = useLocale()
function changeLocale(id: string) {
locale.select(id)
}
</script>
<template>
<div>
<h1>{{ locale.t('hello') }}</h1>
<p>{{ locale.t('welcome', { name: 'John' }) }}</p>
<button @click="changeLocale('en')">English</button>
<button @click="changeLocale('es')">Español</button>
<button @click="changeLocale('fr')">Français</button>
</div>
</template>Architecture
useLocale extends createSingle for locale selection with message interpolation:
Reactivity
Locale selection is reactive via createSingle. Translation methods return static strings.
| Property | Reactive | Notes |
|---|---|---|
selectedId | Current locale ID | |
selectedItem | Current locale ticket | |
selectedValue | Current locale value | |
selectedIndex | Index in registry |
Examples
Locale Switcher
Switch between English, Spanish, and Japanese — translated strings, navigation items, and formatted numbers all update reactively.
welcome
greeting
items
status
Number format: 1234567.89
Adapters
Adapters let you swap the underlying i18n implementation without changing your application code.
| Adapter | Import | Description |
|---|---|---|
Vuetify0LocaleAdapter | @vuetify/v0 | Token-based translation with fallback chain (default) |
VueI18nLocaleAdapter | @vuetify/v0/locale/adapters/vue-i18n | vue-i18n↗︎ v10+ integration |
v0 (default)
The built-in Vuetify0LocaleAdapter is used when no adapter option is provided. It handles the full translation pipeline using the token registry:
Key lookup — resolves
locale.t('key')againstcreateTokensusing the selected localeFallback chain — falls back to the
fallbacklocale when a key is missingMessage linking — resolves token references like
{nav.home}within messages, with circular reference protectionPlaceholder interpolation — named (
{name}) and positional ({0}) replacementNumber formatting —
locale.n(value)delegates toIntl.NumberFormatwith the selected locale
This is the adapter powering the Installation and Usage examples above — no extra configuration needed.
vue-i18n
Requires vue-i18n↗︎ v10+ (Composition API mode).
pnpm add vue-i18nnpm install vue-i18nyarn add vue-i18nbun add vue-i18nimport { createI18n } from 'vue-i18n'
import { VueI18nLocaleAdapter } from '@vuetify/v0/locale/adapters/vue-i18n'
import { createLocalePlugin } from '@vuetify/v0'
const i18n = createI18n({
locale: 'en',
messages: {
en: { hello: 'Hello', welcome: 'Welcome, {name}!' },
es: { hello: 'Hola', welcome: '¡Bienvenido, {name}!' },
},
})
app.use(i18n)
app.use(
createLocalePlugin({
adapter: new VueI18nLocaleAdapter(i18n),
})
) When using the vue-i18n adapter, message storage and resolution are handled entirely by vue-i18n. The messages option on createLocalePlugin is not needed — all translations live in your vue-i18n instance.
Custom Adapters
Create custom adapters by implementing the LocaleAdapter interface:
import type { LocaleAdapter } from '@vuetify/v0'
class MyLocaleAdapter implements LocaleAdapter {
t (key: string, ...params: unknown[]): string {
// Delegate to your i18n provider
return myProvider.translate(key, params)
}
n (value: number): string {
return new Intl.NumberFormat('en-US').format(value)
}
}
// Use with plugin
app.use(
createLocalePlugin({
adapter: new MyLocaleAdapter(),
})
)Adapter Interface
The adapter pattern decouples translation from the underlying i18n library. When you call locale.t(), the request flows through the provided adapter:
interface LocaleAdapter {
t: (key: string, ...params: unknown[]) => string
n: (value: number) => string
}Functions
createLocale
(_options?: LocaleOptions<TokenCollection>) => LocaleContext<LocaleTicketInput, LocaleTicket<LocaleTicketInput>>Creates a new locale instance.
createLocaleFallback
() => LocaleContext<LocaleTicketInput, LocaleTicket<LocaleTicketInput>>createLocaleContext
<_E>(_options?: LocalePluginOptions | undefined) => ContextTrinity<_E>createLocalePlugin
(_options?: LocalePluginOptions | undefined) => PluginuseLocale
<_E>(namespace?: string) => _EOptions
disabled
MaybeRefOrGetter<boolean> | undefinedDisabled state for the entire model instance
Default: false
multiple
MaybeRefOrGetter<boolean> | undefinedAllow multiple tickets to be selected simultaneously
Default: false
mandatory
MaybeRefOrGetter<boolean | "force"> | undefinedControls mandatory selection behavior: - `false` (default): No mandatory selection enforcement - `true`: Prevents deselecting the last selected item - `'force'`: Automatically selects the first non-disabled item on registration
adapter
LocaleAdapter | undefineddefault
ID | undefinedfallback
ID | undefinedmessages
Record<ID, Z> | undefinedProperties
selectedValues
ComputedRef<Set<E["value"] extends Ref<infer U, infer U> ? U : E["value"]>>Computed Set of selected ticket values
selectedId
ComputedRef<ID | undefined>selectedIndex
ComputedRef<number>selectedItem
ComputedRef<E | undefined>selectedValue
ComputedRef<E["value"] | undefined>Methods
move
(id: ID, toIndex: number) => E | undefinedSeek for a ticket based on direction and optional predicate
seek
(direction?: "first" | "last", from?: number, predicate?: (ticket) => boolean) => E | undefinedon
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => voidListen for registry events
off
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => voidStop listening for registry events
emit
<K extends Extensible<RegistryEventName>>(event: K, data: EventPayload<E, K>) => voidEmit an event with data
batch
<R>(fn: () => R) => RExecute operations in a batch, deferring cache invalidation and event emission until complete
n
(value: number) => stringregister
(registration?: Partial<Z>) => ERegister a locale with optional messages. When `messages` is provided, flattens them to dot-notation tokens and onboards them into the token registry before registering the locale for selection.