---
title: Locale - Scoped Locale Provider for Vue 3
meta:
- name: description
  content: A headless component that scopes a locale context to a subtree. Descendant useLocale() calls resolve to the specified locale for translations and number formatting.
- name: keywords
  content: locale, i18n, internationalization, scoped locale, translation, provider, context, Vue 3, headless
features:
  category: Component
  label: 'C: Locale'
  github: /components/Locale/
  renderless: true
  level: 2
related:
  - /composables/plugins/use-locale
---

# Locale

Scopes a locale to a component subtree for localized sections of your app.

<DocsPageFeatures :frontmatter />

## Installation

Install the Locale plugin in your app’s entry point:

```ts main.ts collapse
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.

```vue
<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

```vue Anatomy no-filename
<script setup lang="ts">
  import { Locale } from '@vuetify/v0'
</script>

<template>
  <Locale />
</template>
```

## Examples

::: gn-example
/components/locale/LocaleCard.vue 1
/components/locale/LocaleSection.vue 2
/components/locale/scoped-override.vue 3

### Scoped Override

Nest `<Locale>` components to create layered locale contexts. Each card reads its scoped locale independently via `useLocale()`.

| File | Role |
|------|------|
| `LocaleCard.vue` | Consumer — reads `useLocale()` to display translated content |
| `LocaleSection.vue` | Wrapper — uses `<Locale>` to scope a locale to a section |
| `scoped-override.vue` | Entry — sets up locales and nests scoped overrides |
:::

> [!TIP] 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:

```vue
<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](https://www.w3.org/WAI/WCAG22/Understanding/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

::: faq

??? Does `<Locale>` change my whole app's locale?

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`.

??? Do nested `<Locale>` overrides stack or resolve independently?

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.

??? How do I scope a locale without adding a wrapper element?

Set `renderless` and bind the `attrs` slot prop (which includes `data-locale` and `lang`) to your own element.

:::

<DocsApi />
