Skip to main content

Descripción

useLanguage es un composable de Vue que gestiona el sistema multiidioma de la aplicación. Integra vue-i18n para cambiar el idioma de la interfaz y persiste la preferencia del usuario en localStorage. Soporta Español, Inglés y Kichwa.

Importación

import { useLanguage } from '@/composables/useLanguage'

Uso Básico

import { useLanguage } from '@/composables/useLanguage'

const { changeLanguage, currentLanguage } = useLanguage()

// Cambiar a español
changeLanguage('es')

// Cambiar a inglés
changeLanguage('en')

// Cambiar a kichwa
changeLanguage('qu')

console.log('Idioma actual:', currentLanguage.value) // 'ES', 'EN', o 'QU'

API

Valores Retornados

currentLanguage
Ref<string>
Referencia reactiva al código del idioma actual en mayúsculas (‘ES’, ‘EN’, ‘QU’). Es un estado global compartido entre todos los componentes.
languages
Array<{ code: string, name: string, flag: string }>
Array con los idiomas disponibles en la aplicación.Cada objeto contiene:
  • code (string) - Código ISO del idioma (‘es’, ‘en’, ‘qu’)
  • name (string) - Nombre del idioma (‘Español’, ‘English’, ‘Kichwa’)
  • flag (string) - Emoji de la bandera (’🇪🇸’, ’🇺🇸’, ’🇪🇨’)
changeLanguage
(langCode: string) => void
Cambia el idioma de la aplicación y lo persiste en localStorage.Parámetros:
  • langCode (string) - Código del idioma (‘es’, ‘en’, ‘qu’). Acepta mayúsculas o minúsculas.
Efectos secundarios:
  • Actualiza currentLanguage (en mayúsculas)
  • Actualiza el locale de vue-i18n (en minúsculas)
  • Guarda la preferencia en localStorage.userLanguage
  • Registra el cambio en consola
loadSavedLanguage
() => void
Carga el idioma guardado en localStorage o usa español como predeterminado.Comportamiento:
  • Si existe localStorage.userLanguage, lo carga
  • Si no existe, usa español (‘es’) como idioma predeterminado
  • Actualiza tanto currentLanguage como el locale de vue-i18n
Uso recomendado: Llamar en App.vue o en el punto de entrada de la aplicación.

Estado Global

El composable mantiene un estado global compartido:
const currentLanguage = ref<string>('ES')
Esto garantiza que el idioma sea consistente en toda la aplicación, incluso si múltiples componentes usan useLanguage().

Idiomas Disponibles

CódigoNombreBanderaLocale
esEspañol🇪🇸es
enEnglish🇺🇸en
quKichwa🇪🇨qu

Persistencia

El idioma se guarda en localStorage bajo la clave:
localStorage.userLanguage // Formato: código en minúsculas ('es', 'en', 'qu')
Esto permite que la preferencia del usuario persista entre sesiones.

Integración con vue-i18n

El composable utiliza useI18n() de vue-i18n para acceder al locale:
const { locale } = useI18n()
Cuando se cambia el idioma:
  1. Se actualiza currentLanguage (mayúsculas para UI)
  2. Se actualiza locale.value (minúsculas para i18n)
  3. vue-i18n actualiza automáticamente todas las traducciones

Ejemplo Completo

<script setup lang="ts">
import { useLanguage } from '@/composables/useLanguage'
import { onMounted, computed } from 'vue'

const { 
  currentLanguage, 
  languages, 
  changeLanguage, 
  loadSavedLanguage 
} = useLanguage()

// Cargar idioma guardado al montar
onMounted(() => {
  loadSavedLanguage()
})

// Idioma actual como objeto completo
const currentLang = computed(() => {
  return languages.find(
    lang => lang.code.toUpperCase() === currentLanguage.value
  )
})

// Verificar si un idioma está activo
const isActiveLanguage = (code: string) => {
  return currentLanguage.value.toUpperCase() === code.toUpperCase()
}
</script>

<template>
  <div class="language-selector">
    <!-- Indicador de idioma actual -->
    <div class="current-language">
      <span class="text-2xl">{{ currentLang?.flag }}</span>
      <span class="font-medium">{{ currentLang?.name }}</span>
    </div>

    <!-- Lista de idiomas disponibles -->
    <div class="language-menu">
      <button
        v-for="lang in languages"
        :key="lang.code"
        @click="changeLanguage(lang.code)"
        class="language-option"
        :class="{
          'active': isActiveLanguage(lang.code),
          'bg-blue-50 text-blue-600': isActiveLanguage(lang.code),
          'hover:bg-gray-50': !isActiveLanguage(lang.code)
        }"
      >
        <span class="text-xl">{{ lang.flag }}</span>
        <span>{{ lang.name }}</span>
        
        <!-- Indicador de selección -->
        <svg 
          v-if="isActiveLanguage(lang.code)"
          class="w-5 h-5 text-blue-600"
          fill="currentColor"
          viewBox="0 0 20 20"
        >
          <path
            fill-rule="evenodd"
            d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
            clip-rule="evenodd"
          />
        </svg>
      </button>
    </div>

    <!-- Información del sistema -->
    <div class="text-xs text-gray-500 mt-4">
      Idioma actual: {{ currentLanguage }}
    </div>
  </div>
</template>

<style scoped>
.language-selector {
  @apply p-4 bg-white rounded-lg shadow;
}

.current-language {
  @apply flex items-center space-x-2 pb-3 border-b;
}

.language-menu {
  @apply mt-3 space-y-1;
}

.language-option {
  @apply w-full px-4 py-2 text-sm text-left rounded-lg;
  @apply flex items-center space-x-2 transition-colors;
}

.language-option.active {
  @apply font-medium;
}
</style>

Sincronización Automática

El composable incluye un watch que sincroniza cambios del locale de vue-i18n con currentLanguage:
watch(
  () => locale.value,
  (newLocale) => {
    currentLanguage.value = newLocale.toUpperCase()
  }
)
Esto garantiza que cualquier cambio manual al locale de i18n se refleje en currentLanguage.

Notas

  • El idioma predeterminado es español (‘es’) si no hay preferencia guardada
  • Los códigos de idioma aceptan mayúsculas o minúsculas, pero se normalizan internamente
  • currentLanguage siempre se almacena en mayúsculas para consistencia en la UI
  • El locale de vue-i18n siempre se almacena en minúsculas según el estándar ISO
  • Es recomendable llamar loadSavedLanguage() en App.vue al iniciar la aplicación
  • El estado es global y compartido entre todas las instancias del composable
  • Los cambios de idioma se reflejan inmediatamente en toda la aplicación gracias a la reactividad de Vue

Build docs developers (and LLMs) love