tutoriales.com

Construyendo Aplicaciones Multilingües Escalables en Vue 3 con vue-i18n y Lazy Loading

Descubre cómo escalar tu aplicación Vue 3 a múltiples idiomas de forma eficiente. Este tutorial cubre la configuración de vue-i18n con Composition API, la carga dinámica de archivos de idioma para mejorar el rendimiento y el manejo de formatos complejos.

Intermedio8 min de lectura10 views
Reportar error

Introducción a la Internacionalización (i18n) en Vue 3

La internacionalización, abreviada comúnmente como i18n (debido a que hay 18 letras entre la 'i' y la 'n'), es un proceso fundamental cuando desarrollamos aplicaciones web con ambición global. Permitir que los usuarios interactúen con nuestra interfaz en su lengua materna mejora significativamente la experiencia de usuario (UX), la tasa de conversión y el alcance de nuestro producto.

En el ecosistema de Vue 3, la herramienta estándar y más robusta para lograr esto es la librería oficial vue-i18n. Diseñada desde cero para integrarse perfectamente con la Composition API, nos ofrece un rendimiento excepcional, soporte para TypeScript y un sistema de traducciones sumamente flexible.

💡 Consejo: Planifica la internacionalización desde el inicio de tu proyecto. Extraer textos estáticos más tarde en aplicaciones grandes puede convertirse en una tarea titánica y propensa a errores humanos.

Prerrequisitos y Configuración Inicial

Antes de sumergirnos en el código, asegúrate de tener una aplicación Vue 3 funcional creada con Vite. Necesitaremos instalar el paquete correspondiente a la versión compatible con Vue 3.

Para instalar vue-i18n (asegurándonos de usar la versión v9 o superior para compatibilidad completa con Vue 3), ejecuta el siguiente comando en tu terminal:

npm install vue-i18n@9

Una vez instalado, estructuraremos nuestro proyecto separando los archivos de traducción por idiomas. Esto facilita el mantenimiento a medida que la aplicación crece.

Estructura de Directorios Recomendada

Organiza tus archivos de traducción dentro de la carpeta src de la siguiente manera:

src/locales/es.json: Archivo que contiene todas las traducciones en español.
src/locales/en.json: Archivo que contiene todas las traducciones en inglés.
src/i18n.js: Archivo central de configuración de la instancia de vue-i18n.

Crea el primer archivo de traducción en español src/locales/es.json:

{
  "welcome": "Bienvenido a nuestra plataforma",
  "greeting": "Hola, {name}",
  "items_count": "No tienes elementos | Tienes un elemento | Tienes {count} elementos"
}

Y su contraparte en inglés src/locales/en.json:

{
  "welcome": "Welcome to our platform",
  "greeting": "Hello, {name}",
  "items_count": "You have no items | You have 1 item | You have {count} items"
}

Configurando la Instancia Básica con vue-i18n

Ahora crearemos el archivo src/i18n.js donde inicializaremos la librería utilizando la Composition API y configuraremos las opciones por defecto.

import { createI18n } from 'vue-i18n'
import es from './locales/es.json'
import en from './locales/en.json'

const messages = {
  es,
  en
}

const i18n = createI18n({
  legacy: false, // IMPORTANTE: Desactiva el modo legacy para usar Composition API
  locale: 'es', // Idioma por defecto
  fallbackLocale: 'en', // Idioma de respaldo si falta alguna clave
  messages
})

export default i18n

Para integrar esta instancia en tu aplicación principal, modifícala en tu archivo src/main.js:

import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'

const app = createApp(App)

app.use(i18n)
app.mount('#app')

Uso de Traducciones en Componentes con la Composition API

Una vez configurado el plugin globalmente, podemos consumir las traducciones dentro de cualquier componente SFC de Vue 3 utilizando el composable useI18n.

Componente Vue {{ t('saludo') }} Solicita traducción composable useI18n() Gestor de estado I18n Busca en idioma activo (es/en) Diccionario Activo { "saludo": "Hola Mundo" } Devuelve string "Hola Mundo"

Veamos un ejemplo práctico en un componente UserProfile.vue:

<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n()
const username = ref('Carlos')
const itemCount = ref(5)

const changeLanguage = (lang) => {
  locale.value = lang
}
</script>

<template>
  <div class="profile-container">
    <h1>{{ t('welcome') }}</h1>
    <p>{{ t('greeting', { name: username }) }}</p>
    <p>{{ t('items_count', { count: itemCount }, itemCount) }}</p>
    
    <div class="controls">
      <button @click="changeLanguage('es')">Español</button>
      <button @click="changeLanguage('en')">English</button>
    </div>
  </div>
</template>
📌 Nota: Observa cómo pasamos un objeto como segundo argumento a la función `t()` para interpolar variables dinámicas como `{ name }`.

Implementando Carga perezosa (Lazy Loading) de Traducciones

Pro A medida que una aplicación crece, empaquetar todos los idiomas en un solo archivo principal incrementa innecesariamente el tamaño del bundle inicial. La solución óptima es cargar los archivos de traducción dinámicamente bajo demanda utilizando importaciones dinámicas (import()).

Modifiquemos nuestra configuración de src/i18n.js para soportar la carga perezosa de idiomas:

import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  legacy: false,
  locale: 'es',
  fallbackLocale: 'en',
  messages: {}
})

// Lista de idiomas soportados
export const SUPPORTED_LOCALES = ['es', 'en']

// Función para cargar los mensajes de forma asíncrona
export async function loadLocaleMessages(locale) {
  if (!i18n.global.availableLocales.includes(locale)) {
    try {
      const messages = await import(`./locales/${locale}.json`)
      i18n.global.setLocaleMessage(locale, messages.default)
    } catch (error) {
      console.error(`Error al cargar el idioma ${locale}:`, error)
      return
    }
  }
  
  i18n.global.locale.value = locale
  document.querySelector('html').setAttribute('lang', locale)
}

export default i18n

Ahora, al cambiar de idioma en la interfaz, llamaremos a nuestra función asíncrona loadLocaleMessages en lugar de cambiar directamente la propiedad locale.

import { loadLocaleMessages } from './i18n'

const switchLanguage = async (newLocale) => {
  await loadLocaleMessages(newLocale)
}

Buenas Prácticas y Consejos de Rendimiento

Para concluir, ten en cuenta las siguientes recomendaciones al estructurar proyectos multilingües complejos:

Práctica RecomendadaDescripciónBeneficio
---------
Estructura AnidadaAgrupa las claves por vistas o componentes en el JSON.Facilita la localización rápida de textos.
Lazy LoadingCarga solo el idioma por defecto al iniciar y los demás bajo demanda.Reduce drásticamente el peso inicial del bundle.
---------
Claves SemánticasUsa nombres descriptivos en lugar de repetir el texto como clave.Permite modificar textos originales sin romper referencias.
⚠️ Advertencia: Evita concatenar cadenas traducidas directamente en tus plantillas (ej: `t('Hello') + ' ' + name`), ya que el orden de las palabras varía radicalmente según la estructura gramatical de cada idioma. Utiliza siempre la interpolación nativa de vue-i18n.
Preguntas frecuentes sobre vue-i18n en Vue 3 ¿Cómo puedo formatear fechas y monedas según la región? vue-i18n incluye APIs integradas de formateo numérico y de fechas (`d()` y `n()`) basadas en la API nativa de internacionalización del navegador (Intl), permitiendo adaptar formatos monetarios y temporales de manera automática.

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!