Locale
Scopes a locale to a component subtree for localized sections of your app.
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
Wrap any section of your template in <Locale> to override the active locale for that subtree. Children calling useLocale() will see the scoped locale as the current selection, and t() / n() calls will resolve against the scoped locale — not the parent’s.
<script setup lang="ts">
import { Locale } from '@vuetify/v0'
</script>
<template>
<Locale locale="fr">
<!-- Everything here sees "fr" as the active locale -->
<slot />
</Locale>
</template>Anatomy
<script setup lang="ts">
import { Locale } from '@vuetify/v0'
</script>
<template>
<Locale />
</template>Examples
Root context (en)
Hello — Welcome to our app
3 items selected
Goodbye, World!
Bonjour — Bienvenue dans notre application
3 éléments sélectionnés
Au revoir, World !
Hola — Bienvenido a nuestra aplicación
3 elementos seleccionados
¡Adiós, World!
Hola — Bienvenido a nuestra aplicación
3 elementos seleccionados
¡Adiós, World!
Scoped translations t() and n() are fully scoped. A <Locale locale="fr"> subtree resolves all translations against the French messages, even when nested inside another <Locale> override. Each scope is independent.
Recipes
Renderless Mode
When renderless is set, the component does not render a wrapper element. Instead, it passes attrs (including data-locale and lang) via the slot scope for you to bind to your own element:
<script setup lang="ts">
import { Locale } from '@vuetify/v0'
</script>
<template>
<Locale locale="fr" renderless v-slot="{ attrs }">
<section v-bind="attrs">
No extra wrapper div
</section>
</Locale>
</template>Accessibility
Locale sets the lang attribute on its wrapper element — or exposes it via attrs in renderless mode — to match the scoped locale. This is a genuine accessibility affordance: assistive technology reads lang to select the correct pronunciation and voice, satisfying WCAG 3.1.2 Language of Parts↗︎. It also sets a data-locale attribute for styling and selection.
Beyond lang, Locale is a headless context provider — it adds no roles, keyboard behavior, or interactive elements. In renderless mode you are responsible for binding attrs (which includes lang) to your own element, so the language information reaches the accessibility tree.
FAQ
No. It only overrides the active locale for its subtree — descendant useLocale(), t(), and n() calls resolve to the scoped locale, and the rest of the app is unaffected. Set the app-wide default in createLocalePlugin.
Each scope is independent. A <Locale locale="fr"> subtree resolves all translations against the French messages even when nested inside another override, and each level sees only its nearest ancestor’s scope.
Set renderless and bind the attrs slot prop (which includes data-locale and lang) to your own element.