Autor:
    Creación:2026-08-23Última actualización:2026-08-30

    Traduce tu sitio web backend de Elysia usando Intlayer | Internacionalización (i18n)

    elysia-intlayer es un potente plugin de internacionalización (i18n) para aplicaciones Elysia, diseñado para hacer que tus servicios backend sean globalmente accesibles proporcionando respuestas localizadas basadas en las preferencias del cliente.

    Ver la implementación del package en GitHub.

    Casos de Uso Prácticos

    • Mostrar Errores del Backend en el Idioma del Usuario: Cuando ocurre un error, mostrar mensajes en el idioma nativo del usuario mejora la comprensión y reduce la frustración. Esto es especialmente útil para mensajes de error dinámicos que podrían mostrarse en componentes front-end como toasts o modals.
    • Recuperar Contenido Multilingüe: Para aplicaciones que obtienen contenido de una base de datos, la internacionalización asegura que puedas servir este contenido en múltiples idiomas. Esto es crucial para plataformas como sitios de e-commerce o sistemas de gestión de contenidos que necesitan mostrar descripciones de productos, artículos y otro contenido en el idioma preferido por el usuario.
    • Enviar Correos Electrónicos Multilingües: Ya sea para correos transaccionales, campañas de marketing o notificaciones, enviar correos electrónicos en el idioma del destinatario puede aumentar significativamente el engagement y la efectividad.
    • Notificaciones Push Multilingües: Para aplicaciones móviles, enviar notificaciones push en el idioma preferido del usuario puede mejorar la interacción y retención. Este toque personal puede hacer que las notificaciones se sientan más relevantes y accionables.
    • Otras Comunicaciones: Cualquier forma de comunicación desde el backend, como mensajes SMS, alertas del sistema o actualizaciones de interfaz de usuario, se beneficia de estar en el idioma del usuario, asegurando claridad y mejorando la experiencia general del usuario.

    Al internacionalizar el backend, tu aplicación no solo respeta las diferencias culturales sino que también se alinea mejor con las necesidades del mercado global, lo que la convierte en un paso clave para escalar tus servicios en todo el mundo.

    Primeros pasos

    ide.intlayer.org

    Ver Plantilla de Aplicación en GitHub.

    Instalación

    Para comenzar a usar elysia-intlayer, instala el paquete usando npm:

    bash
    npx intlayer init --interactive
    
    la bandera --interactive es opcional. Usa intlayer-cli init si eres un agente de IA.
    Este comando detectará tu entorno e instalará los paquetes requeridos. Por ejemplo:
    bash
    npm install intlayer elysia-intlayer
    
    Elysia está pensado para el runtime Bun. elysia-intlayer se apoya en AsyncLocalStorage (en lugar de la librería cls-hooked que usan los plugins de Intlayer basados en Node) precisamente porque Bun no implementa async_hooks.createHook.

    Configuración

    Configura los ajustes de internacionalización creando un archivo intlayer.config.ts en la raíz de tu proyecto:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        /**
         * Locale por defecto usada como fallback si no se encuentra la locale solicitada.
         */
        defaultLocale: Locales.ENGLISH,
      },
    };
    
    export default config;
    

    Declara tu contenido

    Crea y gestiona tus declaraciones de contenido para almacenar traducciones:

    src/index.content.ts
    import { t, type Dictionary } from "intlayer";
    
    const indexContent = {
      key: "index",
      content: {
        exampleOfContent: t({
          en: "Example of returned content in English",
          fr: "Exemple de contenu renvoyé en français",
          es: "Ejemplo de contenido devuelto en español",
        }),
      },
    } satisfies Dictionary;
    
    export default indexContent;
    
    Tus declaraciones de contenido pueden definirse en cualquier lugar de tu aplicación siempre que estén incluidas en el directorio contentDir (por defecto, ./src). Y que coincidan con la extensión del archivo de declaración de contenido (por defecto, .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
    Para más detalles, consulta la documentación de declaración de contenido.

    Configuración de la Aplicación Elysia

    Configura tu aplicación Elysia para usar elysia-intlayer:

    src/index.ts
    import { Elysia } from "elysia";
    import { intlayer } from "elysia-intlayer";
    
    const app = new Elysia()
      // Cargar el plugin de internacionalización
      .use(intlayer())
      // Rutas
      .get("/", ({ intlayer }) => ({
        // Locale utilizada para esta solicitud, negociada por `Accept-Language` o leída del almacenamiento
        locale: intlayer!.locale,
        greeting: intlayer!.t({
          en: "Hello",
          fr: "Bonjour",
          es: "Hola",
        }),
        content: intlayer!.getIntlayer("index").exampleOfContent,
      }))
      .listen(3000);
    
    console.log(
      `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
    );
    
    El plugin registra su contexto mediante un derive global, que Elysia tipa como Partial<{ intlayer: IntlayerContext }>. El valor siempre está presente en tiempo de ejecución para las rutas registradas después de .use(intlayer()), así que usa la aserción non-null (intlayer!.locale) — u optional chaining — para satisfacer a TypeScript en modo strict.

    El contexto de la ruta expone:

    PropiedadDescripción
    localeEl locale a usar para esta request; locale_storage tiene prioridad sobre locale_detected.
    locale_storageEl locale solicitado explícitamente por el cliente mediante una cookie o un header.
    locale_detectedEl locale negociado a partir de los headers de la request.
    defaultLocaleEl locale configurado como fallback en intlayer.config.ts.
    tUna función de traducción.
    getIntlayerUna función para recuperar diccionarios por clave.
    getDictionaryUna función para procesar objetos de diccionario.

    Los mismos helpers también se exportan de forma standalone. Resuelven la petición actual a través de AsyncLocalStorage, por lo que puedes llamarlos sin desestructurar el contexto:

    src/index.ts
    import { Elysia } from "elysia";
    import { intlayer, t, getDictionary, getIntlayer } from "elysia-intlayer";
    import dictionaryExample from "./index.content";
    
    const app = new Elysia()
      .use(intlayer())
      .get("/t_example", () =>
        t({
          en: "Example of returned content in English",
          fr: "Exemple de contenu renvoyé en français",
          es: "Ejemplo de contenido devuelto en español",
        })
      )
      .get("/getIntlayer_example", () => getIntlayer("index").exampleOfContent)
      .get(
        "/getDictionary_example",
        () => getDictionary(dictionaryExample).exampleOfContent
      )
      .listen(3000);
    
    El contexto de la request se libera una vez que la respuesta se ha mapeado, de modo que los helpers independientes nunca se resuelven contra una request ya finalizada. Cuando se llaman fuera de una request gestionada por el plugin, recurren al locale por defecto configurado.

    Ejecutar tu aplicación

    Añade los scripts de Intlayer a tu package.json. intlayer build compila tus declaraciones de contenido en el directorio .intlayer y genera los tipos de TypeScript:

    package.json
    {
      "scripts": {
        "dev": "intlayer build && bun run --watch src/index.ts",
        "build": "intlayer build",
        "start": "bun run src/index.ts",
        "i18n:fill": "intlayer fill",
        "i18n:test": "intlayer test"
      }
    }
    

    Luego arranca el servidor:

    bash
    bun run dev
    

    Prueba la negociación de locale con Accept-Language:

    bash
    curl -H "Accept-Language: fr" http://localhost:3000/
    # {"locale":"fr","greeting":"Bonjour","content":"Exemple de contenu renvoyé en français"}
    
    curl -H "Accept-Language: es" http://localhost:3000/
    # {"locale":"es","greeting":"Hola","content":"Ejemplo de contenido devuelto en español"}
    
    intlayer build no es estrictamente necesario antes de bun run src/index.ts: el plugin también prepara los diccionarios cuando arranca la aplicación Elysia. Ejecutarlo por adelantado mantiene los tipos generados sincronizados para tu editor y evita el coste del build en la primera petición.

    Compatibilidad

    elysia-intlayer es totalmente compatible con:

    También funciona sin problemas con cualquier solución de internacionalización en diversos entornos, incluidos navegadores y solicitudes de API.

    Por defecto, el plugin resuelve la locale en este orden:

    1. La cookie INTLAYER_LOCALE.
    2. El header x-intlayer-locale.
    3. La negociación del header Accept-Language.

    Puedes personalizar la cookie y el header usados para la detección de la locale:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      // ... Otras opciones de configuración
      routing: {
        storage: [
          { type: "header", name: "my-locale-header" },
          { type: "cookie", name: "my-locale-cookie" },
        ],
      },
    };
    
    export default config;
    
    Para más información sobre configuración y temas avanzados, visita nuestra documentación.

    Configura TypeScript

    elysia-intlayer aprovecha las robustas capacidades de TypeScript para mejorar el proceso de internacionalización. El tipado estático de TypeScript garantiza que cada clave de traducción se contabilice, reduciendo el riesgo de traducciones faltantes y mejorando la mantenibilidad.

    Asegúrate de que los tipos autogenerados (por defecto en ./types/intlayer.d.ts) estén incluidos en tu archivo tsconfig.json.

    tsconfig.json
    {
      // ... Tus configuraciones TypeScript existentes
      "include": [
        // ... Tus configuraciones TypeScript existentes
        ".intlayer/**/*.ts", // Incluir los tipos autogenerados
      ],
    }
    

    Extensión de VS Code

    Para mejorar tu experiencia de desarrollo con Intlayer, puedes instalar la Extensión oficial de Intlayer para VS Code.

    Instalar desde VS Code Marketplace

    Esta extensión proporciona:

    • Autocompletado para claves de traducción.
    • Detección de errores en tiempo real para traducciones faltantes.
    • Vistas previas en línea del contenido traducido.
    • Acciones rápidas para crear y actualizar traducciones fácilmente.

    Para más detalles sobre cómo usar la extensión, consulta la documentación de la Extensión de Intlayer para VS Code.

    Configuración de Git

    Se recomienda ignorar los archivos generados por Intlayer. Esto te permite evitar confirmarlos en tu repositorio de Git.

    Para hacer esto, puedes añadir las siguientes instrucciones a tu archivo .gitignore:

    .gitignore
    # Ignorar los archivos generados por Intlayer
    .intlayer
    

    Preguntas frecuentes

    Elysia no tiene ninguna capa de i18n propia, así que las opciones son una biblioteca genérica como i18next conectada manualmente a un hook, o Intlayer mediante elysia-intlayer, que registra el plugin por ti, resuelve el idioma por solicitud y comparte el mismo contenido tipado que tu frontend.

    El motivo para internacionalizar el backend en primer lugar es que una gran parte del texto que lee un usuario nunca pasa por el frontend: mensajes de error de la API, correos transaccionales, notificaciones push, SMS y exportaciones a PDF. Estos necesitan el idioma del destinatario, resuelto por solicitud y no por sesión.

    Consulta por qué Intlayer.

    Muy poco. Los diccionarios se compilan con antelación y solo se incluyen los idiomas que declaras, así que no hay carga de catálogos al arrancar ni lecturas de archivos en la ruta de la solicitud. Eso importa sobre todo en despliegues serverless y edge, donde el tamaño del bundle determina el tiempo de arranque en frío. Consulta la optimización del bundle.

    Sí, y hay dos caminos. Puedes migrar el contenido de forma progresiva con la guía de migración de i18next. O puedes mantener tu API actual por completo: los adaptadores de compatibilidad exponen exactamente la misma API que i18next, pero servida por diccionarios de Intlayer, así que cambian los imports y el código de los manejadores no.

    Sí. El plugin de sincronización JSON mantiene tus archivos /messages/{locale}/{namespace}.json como fuente de verdad y genera diccionarios de Intlayer a partir de ellos, en ambas direcciones. Un plugin de sincronización PO hace lo mismo para los catálogos gettext, y los archivos por idioma te permiten dividir el contenido por idioma en lugar de agrupar los idiomas en un solo archivo.

    No. Ejecuta npx intlayer extract e Intlayer lee tus archivos fuente, extrae las cadenas visibles para el usuario y escribe un archivo .content junto a cada uno, así que revisas un diff en lugar de copiar cadenas a un catálogo una por una. Consulta el comando extract.

    En el lado del frontend del mismo proyecto, el compilador de Intlayer va más allá y genera los diccionarios en tiempo de compilación a partir de tu código JSX, TSX, Vue o Svelte, de modo que las dos mitades de la aplicación comparten una única capa de contenido sin claves mantenidas a mano.

    Cinco piezas, todas opcionales:

    • Extensión de VS Code: salta de una clave useIntlayer al archivo de contenido que la declara, extrae contenido de un componente y ejecuta build, fill, test, push y pull desde la paleta de comandos o desde una pestaña de Intlayer dedicada.
    • Servidor LSP: el mismo conocimiento en cualquier editor que hable LSP, con ir a la definición, buscar todas las referencias, vistas previas al pasar el cursor de un valor traducido, autocompletado de claves y campos, y un aviso cuando una clave no está declarada en ninguna parte. También resuelve las llamadas a i18next, react-i18next, next-intl y use-intl, lo que ayuda durante la migración.
    • Servidor MCP: expone la documentación y la CLI de Intlayer a Cursor, VS Code, Claude Desktop, Claude Code y ChatGPT, para que un asistente responda a partir de la documentación actual en lugar de adivinar, y pueda ejecutar comandos como intlayer fill por sí mismo.
    • Habilidades para agentes: habilidades específicas como intlayer-config, intlayer-cli e intlayer-content, además de una por framework, que enseñan a un agente tu configuración de enrutamiento y los tipos de nodo de contenido.
    • Plugin de ESLint: no-raw-text marca las cadenas codificadas de forma fija, con reglas adicionales para claves de diccionario estáticas y contenido sin usar.