Skip to content

useLocale ​

Switching the active language. It lazy-loads the messages, points vue-i18n at them, and lets direction fall back to the new language's own.

Open in demo

Import ​

ts
import { useLocale } from '@core/i18n/useLocale'

Signature ​

ts
function useLocale(): {
  setLocale: (code: AvailableLocale) => Promise<void>
  currentLocale: ComputedRef<AvailableLocale>
  weekStartsOn: ComputedRef<Day>
  availableLocales: readonly AvailableLocale[]
  localeLabel: (code: AvailableLocale) => string
}

Returns ​

MemberTypeDescription
setLocale(code) => Promise<void>Loads the messages, switches, and resets direction to 'auto'.
currentLocaleComputedRef<AvailableLocale>The active code.
weekStartsOnComputedRef<Day>First day of the week for that locale (0 Sunday to 6 Saturday), for the calendar and every date picker.
availableLocalesreadonly AvailableLocale[]Every shipped locale, derived from the registry.
localeLabel(code) => stringThe native name, for a switcher. Falls back to the code in upper case.

The nine locales ​

en, ar, es, it, fr, de, pt, tr, id. ar is right-to-left.

Example ​

vue
<script setup lang="ts">
import { flagFor } from '@core/i18n/localeMeta'
import { useLocale } from '@core/i18n/useLocale'
import SaFlag from '@shared/components/common/SaFlag.vue'

const { setLocale, currentLocale, availableLocales, localeLabel } = useLocale()
</script>

<template>
  <div class="flex flex-wrap gap-2">
    <button
      v-for="code in availableLocales"
      :key="code"
      type="button"
      :aria-pressed="currentLocale === code"
      class="flex items-center gap-2"
      @click="setLocale(code)"
    >
      <SaFlag :src="flagFor(code)" size="size-5" />
      {{ localeLabel(code) }}
    </button>
  </div>
</template>

Notes ​

  • availableLocales is derived from localeMeta, not hand-listed. Adding a locale to the registry is the whole job; the switcher cannot go stale.
  • setLocale awaits loadLocale(code), which fetches that language's JSON chunk. Only the active language is in the bundle you ship to a reader.
  • It resets direction to 'auto'. A manual setDirection('rtl') is released by the next language switch, which is what makes the RTL preview a preview rather than a mode you get stuck in. Lock it again afterwards if you need to.
  • Page body text stays English across the nine languages. The chrome, the forms and the messages are translated; the demo content is not.