Integración con Vite + React

@lingo.dev/compiler se integra con Vite a través de un plugin que funciona tanto con configuraciones SPA como SSR.

Configuración

1. Instalar paquete

pnpm install @lingo.dev/compiler

2. Configurar Vite

Añade lingoCompilerPlugin a tu configuración de Vite:

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";

export default defineConfig({
  plugins: [
    lingoCompilerPlugin({
      sourceRoot: "src",
      sourceLocale: "en",
      targetLocales: ["es", "de", "fr"],
      models: "lingo.dev",
      dev: {
        usePseudotranslator: true,
      },
    }),
    react(),
  ],
});

Orden de plugins: Coloca lingoCompilerPlugin antes del plugin react(). Esto asegura que el compilador transforme tu JSX antes de que React lo procese.

3. Añadir proveedor

Envuelve tu aplicación con LingoProvider en tu punto de entrada:

// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { LingoProvider } from "@lingo.dev/compiler/react";
import App from "./App";
import "./index.css";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <LingoProvider>
      <App />
    </LingoProvider>
  </StrictMode>
);

Importante: Coloca LingoProvider lo más alto posible en tu árbol de componentes. Si usas TanStack Router o React Router, coloca LingoProvider por encima del proveedor del router.

Configuración SPA

Para aplicaciones de página única, la configuración anterior es suficiente. El locale se gestiona del lado del cliente.

Selector de idioma

"use client";

import { useLingoContext } from "@lingo.dev/compiler/react";

export function LanguageSwitcher() {
  const { locale, setLocale } = useLingoContext();

  return (
    <div>
      <label>Language:</label>
      <select value={locale} onChange={(e) => setLocale(e.target.value)}>
        <option value="en">English</option>
        <option value="es">Español</option>
        <option value="de">Deutsch</option>
        <option value="fr">Français</option>
      </select>
    </div>
  );
}

Configuración SSR (React Router, Remix, TanStack Start)

Para frameworks SSR, es posible que necesites gestionar la detección de locale en el servidor.

Detección de locale personalizada

Crea .lingo/locale-resolver.server.ts para la lógica del lado del servidor:

// .lingo/locale-resolver.server.ts
export async function getServerLocale(): Promise<string> {
  // Access request context (framework-specific)
  // Example: parse cookies, headers, or database
  return "en"; // Return detected locale
}

Y .lingo/locale-resolver.client.ts para el lado del cliente:

// .lingo/locale-resolver.client.ts
export function getClientLocale(): string {
  return localStorage.getItem("locale") || "en";
}

export function persistLocale(locale: string): void {
  localStorage.setItem("locale", locale);
}

Consulta Resolvers de locale personalizados para ejemplos específicos de cada framework.

Integración con TanStack Router

Para TanStack Router, coloca LingoProvider encima de RouterProvider:

// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { RouterProvider, createRouter } from "@tanstack/react-router";
import { LingoProvider } from "@lingo.dev/compiler/react";
import { routeTree } from "./routeTree.gen";

const router = createRouter({ routeTree });

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <LingoProvider>
      <RouterProvider router={router} />
    </LingoProvider>
  </StrictMode>
);

Esto garantiza que las traducciones estén disponibles en todos tus componentes enrutados y que el contexto no se rompa por la división de código.

Integración con React Router

Para React Router v6/v7:

// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { LingoProvider } from "@lingo.dev/compiler/react";
import App from "./App";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <LingoProvider>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </LingoProvider>
  </StrictMode>
);

HMR y desarrollo

El compilador es totalmente compatible con Hot Module Replacement (HMR) de Vite. Cuando actualizas texto traducible:

  1. El compilador detecta el cambio
  2. El servidor de traducción genera nuevas traducciones (o pseudotraducciones)
  3. HMR actualiza tu componente sin recarga completa
  4. El estado del componente se conserva

Fast Refresh funciona con normalidad: el compilador no interfiere con el HMR de Vite.

Configuración de compilación

Compilación de desarrollo

{
  dev: {
    usePseudotranslator: true, // Fast fake translations
  }
}

Ejecuta npm run dev para obtener feedback instantáneo con pseudotraducciones.

Compilación de producción

{
  buildMode: "cache-only", // Use pre-generated translations
}

Ejecuta npm run build. Las traducciones provienen de .lingo/metadata.json: no se necesitan llamadas a la API.

Buena práctica: genera traducciones reales en CI antes de las compilaciones de producción. Consulta Modos de compilación.

División de código

El compilador respeta la división de código de Vite. Cada fragmento cargado de forma diferida incluye solo las traducciones que necesita.

// Lazy-loaded route
const Dashboard = lazy(() => import("./pages/Dashboard"));

// Dashboard component's translations are bundled with the Dashboard chunk

Las traducciones se optimizan automáticamente mediante tree-shaking: solo se incluyen las traducciones utilizadas en cada fragmento.

TypeScript

El compilador está completamente tipado:

import type { LingoConfig } from "@lingo.dev/compiler";

const config: LingoConfig = {
  sourceRoot: "src",
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
};

Variables de entorno

Utiliza el sistema de variables de entorno de Vite para las claves de API:

# .env
VITE_LINGO_API_KEY=your_key_here

Accede en la configuración:

{
  models: "lingo.dev",
  // API key is automatically read from LINGODOTDEV_API_KEY env variable
}

Nunca hagas commit de claves de API. Añade .env a .gitignore.

Problemas comunes

"Cannot find module '@lingo.dev/compiler/react'" Asegúrate de que el paquete esté instalado: pnpm install @lingo.dev/compiler

HMR se rompe después de añadir LingoProvider Verifica que lingoCompilerPlugin esté colocado antes del plugin react() en tu configuración de Vite.

Las traducciones no se muestran en producción Verifica buildMode: "cache-only" y que .lingo/metadata.json tenga traducciones para todos los locales.

Contexto roto con code splitting Asegúrate de que LingoProvider esté colocado por encima de tu proveedor de enrutador (TanStack Router, React Router, etc.). De lo contrario, las rutas con code-split pueden perder el contexto.

Puerto 60000 ya en uso El servidor de traducción encuentra automáticamente puertos disponibles (60000-60099). Si todos están en uso, configura manualmente:

{
  dev: {
    translationServerStartPort: 61000, // Use different port range
  }
}

Próximos pasos