InicioEntorno de pruebasExhibiciónAppDocBlog
    • Englishinglés
      EN
    • русскийruso
      RU
    • 日本語japonés
      JA
    • françaisfrancés
      FR
    • 한국어coreano
      KO
    • 中文chino
      ZH
    • españolespañol
      ES
    • Deutschalemán
      DE
    • العربيةárabe
      AR
    • italianoitaliano
      IT
    • British Englishinglés británico
      EN-GB
    • portuguêsportugués
      PT
    • हिन्दीhindi
      HI
    • Türkçeturco
      TR
    • polskipolaco
      PL
    • Indonesiaindonesio
      ID
    • Tiếng Việtvietnamita
      VI
    • українськаucraniano
      UK
    /
    Filtrar documentación por framework
    Alt+←
    ¿Por qué Intlayer?
    Empezar
    Concepto
    • Cómo funciona Intlayer
    • Configuración
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • Editor visual
    • CMS
    • Integración CI/CD
    • TraducciónPluralEnumeraciónCondiciónGéneroInserciónArchivoAnidaciónMarkdownHTMLObtención de función
    • Archivo por locale
    • Compilador
    • Autocompletado
    • Pruebas
    • Optimización de bundle
    Entornos
    • Next.js 14 y App Router
      Next.js 15
      Next.js sin locale URL
      Next.js y Page Router
      Compiler
    • Tanstack Start Solid
    • Astro y React
      Astro y Svelte
      Astro y Vue
      Astro y Solid
      Astro y Preact
      Astro y Lit
      Astro y Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt y Vue
    • Vite y Solid
    • SvelteKit
    • Vite y Preact
    • Vite y Vanilla JS
    • Vite y Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native y Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx y React
    Plugins
    • JSON
    • gettext (.po)
    Extensión VS Code
    Agente
    • Servidor MCP
    • Habilidades del agente
    Versiones
    • v8
    • v7
    • v6
    Benchmark
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    Blog
    Preguntar una pregunta
    1. Documentation
    2. Entornos
    3. Vite y React
    4. Compiler
    Creación:2024-03-07Última actualización:2026-05-06
    Ver la plantilla de aplicación en GitHub

    Esta página tiene una plantilla de aplicación disponible.

    Ver la aplicación de demostración

    Esta página enlaza a una demo en vivo de la plantilla.

    Ver el video tutorial

    Esta página tiene un video tutorial disponible.

    Referencia esta doc a tu asistente AI favorito
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    Haz tu pregunta y obtén un resumen del documento referenciando esta página y el proveedor AI de tu elección

    Historial de versiones

    1. "Actualizar el uso de la API useIntlayer de Solid para el acceso directo a las propiedades"
      v8.9.04/5/2026
    2. "Update compiler options, add FilePathPattern support"
      v8.2.09/3/2026
    3. "Lanzamiento inicial"
      v8.1.623/2/2026

    El contenido de esta página ha sido traducido con una IA.

    Ver la última versión del contenido original en inglés
    Editar esta documentación

    Si tienes una idea para mejorar esta documentación, no dudes en contribuir enviando una pull request en GitHub.

    Enlace de GitHub a la documentación
    Copiar

    Copiar el Markdown del documento a la portapapeles

    Cómo hacer multilingüe (i18n) una aplicación Vite y React existente a posteriori (guía i18n 2026)

    www.youtube.com
    ide.intlayer.org
    intlayer-vite-react-template.vercel.app

    Ver Plantilla de Aplicación en GitHub.

    Tabla de Contenidos

    ¿Por qué es difícil internacionalizar una aplicación existente?

    Si alguna vez has intentado añadir varios idiomas a una aplicación que fue construida para uno solo, conoces el dolor. No es solo "difícil", es tedioso. Tienes que peinar cada archivo, cazar cada cadena de texto y moverlas a archivos de diccionario separados.

    Luego viene la parte arriesgada: reemplazar todo ese texto con ganchos de código sin romper tu diseño o lógica. Es el tipo de trabajo que detiene el desarrollo de nuevas funciones durante semanas y se siente como una refactorización interminable.

    ¿Qué es el Compilador de Intlayer?

    El Compilador de Intlayer fue construido para saltarse ese trabajo manual pesado. En lugar de extraer las cadenas manualmente, el compilador lo hace por ti. Escanea tu código, encuentra el texto y utiliza IA para generar los diccionarios en segundo plano. Luego, modifica tu código durante la construcción para inyectar los ganchos i18n necesarios. Básicamente, sigues escribiendo tu aplicación como si fuera de un solo idioma, y el compilador se encarga de la transformación multilingüe automáticamente.

    Documentación del Compilador: /es/doc/compiler

    Limitaciones

    Debido a que el compilador realiza el análisis y la transformación del código (insertando ganchos y generando diccionarios) en el momento de la compilación, puede ralentizar el proceso de construcción de tu aplicación.

    Para mitigar este impacto durante el desarrollo, puedes configurar el compilador para que se ejecute en modo 'build-only' o desactivarlo cuando no sea necesario.


    Guía paso a paso para configurar Intlayer en una aplicación Vite y React

    Paso 1: Instalar dependencias

    Instala los paquetes necesarios usando npm:

    bash
    Copiar código

    Copiar el código al portapapeles

    npm install intlayer react-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer El paquete principal que proporciona herramientas de internacionalización para la gestión de configuración, traducción, declaración de contenido, transpilación y comandos CLI.

    • react-intlayer El paquete que integra Intlayer con la aplicación React. Proporciona proveedores de contexto y ganchos para la internacionalización de React.

    • vite-intlayer Incluye el complemento de Vite para integrar Intlayer con el empaquetador Vite, así como el middleware para detectar el idioma preferido del usuario, gestionar cookies y manejar la redirección de URL.

    Paso 2: Configura tu proyecto

    Crea un archivo de configuración para configurar los idiomas de tu aplicación:

    intlayer.config.ts
    Copiar código

    Copiar el código al portapapeles

    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },  compiler: {    /**     * Indica si el compilador debe estar habilitado.     */    enabled: true,    /**     * Directorio de salida para los diccionarios optimizados.     */    output: ({ locale, key }) => `compiler/${locale}/${key}.json`,    /**     * Inserta solo el contenido en el archivo generado, sin clave.     */    noMetadata: false,    /**     * Prefijo de clave de diccionario     */    dictionaryKeyPrefix: "", // Eliminar el prefijo base    /**     * Indica si los componentes deben guardarse después de ser transformados.     * De esta manera, el compilador puede ejecutarse una sola vez para transformar la aplicación y luego puede eliminarse.     */    saveComponents: false,  },  ai: {    provider: "openai",    model: "gpt-5-mini",    apiKey: process.env.OPEN_AI_API_KEY,    applicationContext: "Esta aplicación es una aplicación de mapas", // Nota: puedes personalizar esta descripción de la aplicación  },};export default config;
    Nota: Asegúrate de tener tu OPEN_AI_API_KEY configurada en tus variables de entorno.
    A través de este archivo de configuración, puedes configurar URLs localizadas, redirección de middleware, nombres de cookies, la ubicación y extensión de tus declaraciones de contenido, desactivar los registros de Intlayer en la consola y más. Para obtener una lista completa de los parámetros disponibles, consulta la documentación de configuración.

    Paso 3: Integra Intlayer en tu configuración de Vite

    Añade el complemento de intlayer en tu configuración.

    vite.config.ts
    Copiar código

    Copiar el código al portapapeles

    import { defineConfig } from "vite";import react from "@vitejs/plugin-react-swc";import { intlayer, intlayerCompiler } from "vite-intlayer";// https://vitejs.dev/config/export default defineConfig({  plugins: [react(), intlayer(), intlayerCompiler()],});
    El complemento Vite intlayer() se utiliza para integrar Intlayer con Vite. Garantiza la construcción de archivos de declaración de contenido y los supervisa en modo de desarrollo. Define variables de entorno de Intlayer dentro de la aplicación Vite. Además, proporciona alias para optimizar el rendimiento.
    El complemento Vite intlayerCompiler() se utiliza para extraer contenido del componente y escribir archivos .content.

    Paso 4: Compila tu código

    Simplemente escribe tus componentes con cadenas codificadas en tu idioma predeterminado. El compilador se encarga del resto.

    Ejemplo de cómo podría verse tu página:

    src/App.tsx
    Copiar código

    Copiar el código al portapapeles

    import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt="Vite logo" />       </a>       <a href="https://react.dev" target="_blank">         <img src={reactLogo} className="logo react" alt="React logo" />       </a>     </div>     <h1>Vite + React</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         count is {count}       </button>       <p>         Edit <code>src/App.tsx</code> and save to test HMR       </p>     </div>     <p className="read-the-docs">       Click on the Vite and React logos to learn more     </p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
    i18n/app-content.content.json
    Copiar código

    Copiar el código al portapapeles

    { key: "app-content", content: {   nodeType: "translation",   translation: {     en: {       viteLogo: "Vite logo",       reactLogo: "React logo",       title: "Vite + React",       countButton: "count is",       editMessage: "Edit",       hmrMessage: "and save to test HMR",       readTheDocs: "Click on the Vite and React logos to learn more",     },     es: {       viteLogo: "Logotipo de Vite",       reactLogo: "Logotipo de React",       title: "Vite + React",       countButton: "la cuenta es",       editMessage: "Edita",       hmrMessage: "y guarda para probar HMR",       readTheDocs: "Haz clic en los logotipos de Vite y React para saber más",     },   } }}
    src/App.tsx
    Copiar código

    Copiar el código al portapapeles

    import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider, useIntlayer } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); const content = useIntlayer("app-content"); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt={content.viteLogo.value} />       </a>       <a href="https://react.dev" target="_blank">         <img           src={reactLogo}           className="logo react"           alt={content.reactLogo.value}         />       </a>     </div>     <h1>{content.title}</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         {content.countButton} {count}       </button>       <p>         {content.editMessage} <code>src/App.tsx</code> {content.hmrMessage}       </p>     </div>     <p className="read-the-docs">{content.readTheDocs}</p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
    • IntlayerProvider se utiliza para proporcionar el idioma a los componentes anidados.

    (Opcional) Paso 6: Cambiar el idioma de tu contenido

    Para cambiar el idioma de tu contenido, puedes usar la función setLocale proporcionada por el gancho useLocale. Esta función te permite establecer el idioma de la aplicación y actualizar el contenido en consecuencia.

    src/components/LocaleSwitcher.tsx
    Copiar código

    Copiar el código al portapapeles

    import type { FC } from "react";import { Locales } from "intlayer";import { useLocale } from "react-intlayer";const LocaleSwitcher: FC = () => {  const { setLocale } = useLocale();  return (    <button onClick={() => setLocale(Locales.SPANISH)}>      Cambiar idioma a español    </button>  );};
    Para obtener más información sobre el gancho useLocale, consulta la documentación.

    (Opcional) Paso 7: Rellenar traducciones faltantes

    Intlayer proporciona una herramienta CLI para ayudarte a rellenar las traducciones faltantes. Puedes usar el comando intlayer para probar y rellenar las traducciones faltantes de tu código.

    bash
    Copiar código

    Copiar el código al portapapeles

    npx intlayer test         # Probar si faltan traducciones
    bash
    Copiar código

    Copiar el código al portapapeles

    npx intlayer fill         # Rellenar traducciones faltantes
    Para más detalles, consulta la documentación de la CLI

    (Opcional) Sitemap y robots.txt (generación en el build)

    Intlayer ofrece utilidades - generateSitemap y getMultilingualUrls - para formatear un sitemap.xml multilingüe y un robots.txt listos para rastreadores y escribirlos automáticamente en public/. Lo habitual es ejecutar un script pequeño de Node antes de Vite (por ejemplo hooks npm predev / prebuild) para que esos archivos existan al compilar o al levantar el servidor de desarrollo.

    Sitemap

    El generador de sitemaps de Intlayer respeta tu configuración de idiomas y añade los metadatos habituales.

    El sitemap admite el espacio de nombres xhtml:link (hreflang). En lugar de listar solo URLs sueltas, Intlayer enlaza de forma bidireccional todas las versiones localizadas de cada página (p. ej. /about, /fr/about o /about?lang=fr según el modo de rutas).

    Robots.txt

    Usa getMultilingualUrls para que las reglas Disallow cubran todas las variantes localizadas de rutas sensibles.

    1. Crear generate-seo.mjs en la raíz del proyecto

    generate-seo.mjs
    Copiar código

    Copiar el código al portapapeles

    import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");

    Debe estar instalado intlayer para poder importarlo. Define SITE_URL en el entorno en producción (por ejemplo en CI).

    Prefiere generate-seo.mjs para ESM en Node. Si usas generate-seo.js, asegúrate de tener "type": "module" en package.json o ejecuta Node con ESM.

    2. Ejecutar el script antes de Vite

    package.json
    Copiar código

    Copiar el código al portapapeles

    {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}

    Ajusta los comandos si usas pnpm o yarn. También puedes llamar al script desde CI u otro paso del pipeline.

    Configuración de Git

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

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

    .gitignore
    Copiar código

    Copiar el código al portapapeles

    # Ignorar los archivos generados por Intlayer.intlayer

    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 el Marketplace de VS Code

    Esta extensión proporciona:

    • Autocompletado para las 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 VS Code de Intlayer.

    Ir más allá

    Para ir más allá, puedes implementar el editor visual o externalizar tu contenido utilizando el CMS.

    React Router v7 (fs-routes)
    Vite y Vue
    Alt+→

    En esta página

      Las conversaciones son anónimas y se revisan regularmente para abordar problemas comunes. No dudes en compartir ideas de funcionalidades, comentarios sobre la documentación o cualquier cosa relacionada con Intlayer, usamos esta información para definir nuestra hoja de ruta y mejorar el producto.

      npm install intlayer react-intlayernpm install vite-intlayer --save-devnpx intlayer init
      import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },  compiler: {    /**     * Indica si el compilador debe estar habilitado.     */    enabled: true,    /**     * Directorio de salida para los diccionarios optimizados.     */    output: ({ locale, key }) => `compiler/${locale}/${key}.json`,    /**     * Inserta solo el contenido en el archivo generado, sin clave.     */    noMetadata: false,    /**     * Prefijo de clave de diccionario     */    dictionaryKeyPrefix: "", // Eliminar el prefijo base    /**     * Indica si los componentes deben guardarse después de ser transformados.     * De esta manera, el compilador puede ejecutarse una sola vez para transformar la aplicación y luego puede eliminarse.     */    saveComponents: false,  },  ai: {    provider: "openai",    model: "gpt-5-mini",    apiKey: process.env.OPEN_AI_API_KEY,    applicationContext: "Esta aplicación es una aplicación de mapas", // Nota: puedes personalizar esta descripción de la aplicación  },};export default config;
      import { defineConfig } from "vite";import react from "@vitejs/plugin-react-swc";import { intlayer, intlayerCompiler } from "vite-intlayer";// https://vitejs.dev/config/export default defineConfig({  plugins: [react(), intlayer(), intlayerCompiler()],});
      import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt="Vite logo" />       </a>       <a href="https://react.dev" target="_blank">         <img src={reactLogo} className="logo react" alt="React logo" />       </a>     </div>     <h1>Vite + React</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         count is {count}       </button>       <p>         Edit <code>src/App.tsx</code> and save to test HMR       </p>     </div>     <p className="read-the-docs">       Click on the Vite and React logos to learn more     </p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
      { key: "app-content", content: {   nodeType: "translation",   translation: {     en: {       viteLogo: "Vite logo",       reactLogo: "React logo",       title: "Vite + React",       countButton: "count is",       editMessage: "Edit",       hmrMessage: "and save to test HMR",       readTheDocs: "Click on the Vite and React logos to learn more",     },     es: {       viteLogo: "Logotipo de Vite",       reactLogo: "Logotipo de React",       title: "Vite + React",       countButton: "la cuenta es",       editMessage: "Edita",       hmrMessage: "y guarda para probar HMR",       readTheDocs: "Haz clic en los logotipos de Vite y React para saber más",     },   } }}
      import { useState, type FC } from "react";import reactLogo from "./assets/react.svg";import viteLogo from "/vite.svg";import "./App.css";import { IntlayerProvider, useIntlayer } from "react-intlayer";const AppContent: FC = () => { const [count, setCount] = useState(0); const content = useIntlayer("app-content"); return (   <>     <div>       <a href="https://vitejs.dev" target="_blank">         <img src={viteLogo} className="logo" alt={content.viteLogo.value} />       </a>       <a href="https://react.dev" target="_blank">         <img           src={reactLogo}           className="logo react"           alt={content.reactLogo.value}         />       </a>     </div>     <h1>{content.title}</h1>     <div className="card">       <button onClick={() => setCount((count) => count + 1)}>         {content.countButton} {count}       </button>       <p>         {content.editMessage} <code>src/App.tsx</code> {content.hmrMessage}       </p>     </div>     <p className="read-the-docs">{content.readTheDocs}</p>   </> );};const App: FC = () => ( <IntlayerProvider>   <AppContent /> </IntlayerProvider>);export default App;
      import type { FC } from "react";import { Locales } from "intlayer";import { useLocale } from "react-intlayer";const LocaleSwitcher: FC = () => {  const { setLocale } = useLocale();  return (    <button onClick={() => setLocale(Locales.SPANISH)}>      Cambiar idioma a español    </button>  );};
      npx intlayer test         # Probar si faltan traducciones
      npx intlayer fill         # Rellenar traducciones faltantes
      import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");
      {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}
      # Ignorar los archivos generados por Intlayer.intlayer