i18n

Alixan UI использует официальный модуль Nuxt i18n. Проект хранит message keys типизированными, а переключение языка и persistence выполняет модуль.

Для более подробной информации перейдите в документацию Nuxt i18n.

Установка

Установите модуль Nuxt i18n, затем зарегистрируйте его в nuxt.config.ts.

npx nuxt module add i18n

Конфигурация

Используйте strategy: 'prefix_except_default' чтобы язык по умолчанию оставался без prefix, а остальные locales получали prefix.

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    vueI18n: './configs/i18n.config.ts',
    defaultLocale: 'en',
    strategy: 'prefix_except_default',
    detectBrowserLanguage: false,
    locales: [
      { code: 'en', name: 'English', file: 'en.json' },
      { code: 'ru', name: 'Русский', file: 'ru.json' },
      { code: 'kk', name: 'Қазақша', file: 'kk.json' },
    ],
  },
})

Укажите внешний vueI18n config и отключите i18n warnings в i18n/configs/i18n.config.ts.

i18n/configs/i18n.config.ts
export default {
  // Disable warnings because some UI props intentionally pass plain strings through $t.
  missingWarn: false,
  fallbackWarn: false,
}

Translations

Храните JSON файлы переводов в i18n/locales. Опция file связывает каждую locale с ее файлом переводов.

i18n/locales/en.json
{
  "app": {
    "settings": "Open settings"
  },
  "settings": {
    "language": "Language"
  },
  "component": {
    "button": "Button"
  }
}
i18n/locales/ru.json
{
  "app": {
    "settings": "Открыть настройки"
  },
  "settings": {
    "language": "Язык"
  },
  "component": {
    "button": "Кнопка"
  }
}
i18n/locales/kk.json
{
  "app": {
    "settings": "Баптауларды ашу"
  },
  "settings": {
    "language": "Тіл"
  },
  "component": {
    "button": "Батырма"
  }
}

Использование

Язык

<script setup lang="ts">
type Locale = 'en' | 'ru' | 'kk'

const { locale, setLocale } = useI18n()

const languageOptions: Array<{ label: string; value: Locale }> = [
  { label: 'English', value: 'en' },
  { label: 'Русский', value: 'ru' },
  { label: 'Қазақша', value: 'kk' },
]

const changeLocale = async (value: Locale): Promise<void> => {
  useHead({
    htmlAttrs: { lang: value },
  })
  await setLocale(value)
}
</script>

<template>
  <div class="space-y-2">
    <p class="px-1 text-sm font-medium text-muted-foreground">
      {{ $t('settings.language') }}
    </p>
    <Select
      :model-value="locale"
      :options="languageOptions"
      @change="changeLocale($event.value as Locale)"
    />
  </div>
</template>

Page Meta

Передавайте ключи переводов для page-level SEO в usePageMeta . Composable сам разрешает их через useI18n().t внутри.

pages/button.vue
<script setup lang="ts">
usePageMeta({
  title: 'seo.metaTitle',
  description: 'seo.metaDescription',
})
</script>