Locale Provider
Locale Provider
The XAFLocaleProvider component sets up multi-language support for the whole app. Wrap your app's root layout with it, then use useXafLocale() from any descendant to read or change the locale.
Components
<XAFLocaleProvider />
<!-- app.vue -->
<template>
<XAFLocaleProvider v-model="locale" :locales="supportedLocales">
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</XAFLocaleProvider>
</template>
<script setup lang="ts">
const locale = ref("en")
const supportedLocales = [
{ code: "en", label: "English", flag: "🇺🇸" },
{ code: "es", label: "Español", flag: "🇪🇸" },
{ code: "fr", label: "Français", flag: "🇫🇷" },
{ code: "ja", label: "日本語", flag: "🇯🇵" },
]
</script>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | required | Two-way bound current locale code |
locales | XafLocaleOption[] | 9 common locales (en, es, fr, de, pt, it, ja, zh, ar) | Available locales |
defaultLocale | string | first locale's code | Locale to use when no cookie or browser match exists |
persist | boolean | true | Persist choice in a cookie |
cookieName | string | 'xaf_locale' | Cookie name for persistence |
cookieDays | number | 365 | Cookie lifetime in days |
detectFromBrowser | boolean | true | Auto-detect from navigator.language on first visit (no cookie set) |
broadcastChange | boolean | true | Dispatch xaf:locale:changed window event on switch |
switcherPosition | 'footer' | 'none' | 'footer' | Built-in switcher position (or hide it) |
Slots
| Slot | Description |
|---|---|
default | App content. Receives { locale, locales, setLocale } via slot props. |
switcher | Custom switcher UI. Receives { locale, locales, setLocale } via slot props. Use this when switcherPosition: 'none'. |
switcher-label | Override the label text shown next to the built-in footer switcher |
Locale option shape
interface XafLocaleOption {
code: string // BCP 47 / ISO 639-1 (e.g. "en", "es", "fr-CA")
label?: string // Display label (e.g. "English", "Español")
flag?: string // Flag emoji (e.g. "🇺🇸") or image URL
dir?: "ltr" | "rtl" // Text direction. Defaults to "ltr"
hreflangUrl?: string // Per-locale URL — emits <link rel="alternate" hreflang="...">
}
Behavior
On mount (client)
- Read
xaf_localecookie. If set and the code exists inlocales, use it. - Else, if
detectFromBrowser, trynavigator.languages[0]and match against thelocaleslist (with prefix fallback, e.g.fr-CA→fr). - Else, fall back to
defaultLocale(or the first locale's code). - Update
<html lang="...">and<html dir="...">to match the resolved locale.
On switch
- Update internal
localeref. - Emit
update:modelValue. - Write the cookie.
- Dispatch
xaf:locale:changedwindow event with{ code }. - Update
<html lang>+dir.
Listening to locale changes
window.addEventListener('xaf:locale:changed', (e) => {
const { code } = (e as CustomEvent<{ code: string }>).detail
// Refetch data with new locale, re-format prices, etc.
})
Reading locale state from a component
<script setup lang="ts">
const { locale, resolved, setLocale, t } = useXafLocale()
// `locale` is reactive — react to it in computed/effects:
const welcomeMessage = computed(() =>
t({ en: "Welcome", es: "Bienvenido", fr: "Bienvenue" }, "Welcome")
)
// Switch programmatically:
function switchToSpanish() {
setLocale("es")
}
</script>
For full i18n (translation files, pluralization, ICU message format), use vue-i18n on top. The t() helper in useXafLocale() is only for tiny strings the layer renders itself.
Tips
- The default locale list includes 9 common languages — extend it per site based on your audience. Don't ship locales you don't actually have content for.
- For RTL locales (Arabic, Hebrew), set
dir: "rtl". The provider will set<html dir="rtl">so your CSS can scope RTL-specific rules. - Pair with
<XAFSearchFilters>and<XAFPagination>— they don't need locale awareness, but if you swap query params per locale (/en/search?q=foovs/es/buscar?q=foo), pair with a route middleware.
AI Context
component: XAFLocaleProvider
package: "@xenterprises/nuxt-x-affiliate"
use-when: Multi-language site that needs locale state shared across the whole app
Author Archive
Author landing page with author bio, profile image, social links, and a grid of the author's reviews.
CookieConsent
Consent-aware cookie banner + preferences modal that auto-fires configured tracking scripts (GTM / GA4 / Clarity / Meta Pixel / Hotjar / etc.) only after the visitor grants consent. Drop tracking IDs into app.config.xAffiliate.tracking and the banner handles the rest.
