Integración con Next.js
@lingo.dev/compiler se integra con Next.js App Router a través de un wrapper de configuración asíncrono que soporta tanto Webpack como Turbopack.
Configuración
1. Instalar paquete
pnpm install @lingo.dev/compiler
2. Configurar Next.js
Actualiza tu next.config.ts para usar el wrapper asíncrono withLingo():
import type { NextConfig } from "next";
import { withLingo } from "@lingo.dev/compiler/next";
const nextConfig: NextConfig = {
// Your existing Next.js config
};
export default async function (): Promise<NextConfig> {
return await withLingo(nextConfig, {
sourceRoot: "./app",
sourceLocale: "en",
targetLocales: ["es", "de", "fr"],
models: "lingo.dev",
dev: {
usePseudotranslator: true,
},
});
}
¿Por qué asíncrono? El wrapper carga los plugins de forma diferida y resuelve la configuración dinámicamente. Esto mantiene tu compilación rápida y permite la carga condicional de plugins.
3. Añadir proveedor
Envuelve tu aplicación con LingoProvider en tu layout raíz:
// app/layout.tsx
import { LingoProvider } from "@lingo.dev/compiler/react";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<LingoProvider>
<html>
<body>{children}</body>
</html>
</LingoProvider>
);
}
Importante: Coloca LingoProvider dentro de <html> pero envolviendo todo el contenido. Funciona tanto con componentes de servidor como de cliente.
Componentes de servidor de React
El compilador soporta completamente los componentes de servidor de React (RSC). Los componentes de servidor se traducen en tiempo de compilación, y las traducciones se incrustan en la salida del servidor.
// app/page.tsx (Server Component)
export default function Page() {
return (
<div>
<h1>Welcome to our app</h1>
<p>This is a server component—translated at build time</p>
</div>
);
}
No se añade JavaScript del lado del cliente para el texto traducido en componentes de servidor.
Componentes de cliente
Para componentes de cliente, usa la directiva "use client":
"use client";
import { useLingoContext } from "@lingo.dev/compiler/react";
export function LanguageSwitcher() {
const { locale, setLocale } = useLingoContext();
return (
<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>
</select>
);
}
Los componentes de cliente reciben paquetes de traducción optimizados. Solo se incluyen las traducciones utilizadas en ese componente.
Detección de idioma
Por defecto, el idioma se almacena en una cookie (locale). El compilador maneja automáticamente la detección y persistencia del idioma.
Detección personalizada de idioma en el servidor
Para lógica personalizada (base de datos, encabezados, subdominio), crea .lingo/locale-resolver.server.ts:
// .lingo/locale-resolver.server.ts
import { headers } from "next/headers";
export async function getServerLocale(): Promise<string> {
const headersList = await headers();
const acceptLanguage = headersList.get("accept-language");
// Parse accept-language header
const locale = acceptLanguage?.split(",")[0]?.split("-")[0] || "en";
return locale;
}
Esta función se llama en el servidor para cada solicitud. Debe devolver el código de idioma (por ejemplo, "en", "es").
Persistencia personalizada de idioma en el cliente
Para lógica personalizada del lado del cliente (localStorage, parámetros de URL), crea .lingo/locale-resolver.client.ts:
// .lingo/locale-resolver.client.ts
export function getClientLocale(): string {
// Check URL parameter first
const params = new URLSearchParams(window.location.search);
const urlLocale = params.get("lang");
if (urlLocale) return urlLocale;
// Fall back to localStorage
return localStorage.getItem("locale") || "en";
}
export function persistLocale(locale: string): void {
localStorage.setItem("locale", locale);
// Optionally update URL
const url = new URL(window.location.href);
url.searchParams.set("lang", locale);
window.history.replaceState({}, "", url.toString());
}
Consulta Resolvedores de idioma personalizados para más detalles.
Middleware para enrutamiento de idiomas
Si deseas enrutamiento basado en idiomas (/en/about, /es/about), implementa el middleware de Next.js:
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
const locales = ["en", "es", "de", "fr"];
const defaultLocale = "en";
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// Check if pathname already has a locale
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
);
if (pathnameHasLocale) return;
// Get locale from cookie or accept-language header
const localeCookie = request.cookies.get("locale")?.value;
const acceptLanguage = request.headers.get("accept-language");
const locale =
localeCookie ||
acceptLanguage?.split(",")[0]?.split("-")[0] ||
defaultLocale;
// Redirect to localized pathname
request.nextUrl.pathname = `/${locale}${pathname}`;
return NextResponse.redirect(request.nextUrl);
}
export const config = {
matcher: ["/((?!api|_next|_vercel|.*\\..*).*)"],
};
Actualiza tus rutas para usar el segmento dinámico [locale]:
app/
[locale]/
page.tsx
about/
page.tsx
layout.tsx
Configuración de compilación
Compilación de desarrollo
{
dev: {
usePseudotranslator: true, // Fast fake translations
}
}
Ejecuta npm run dev para iniciar el servidor de desarrollo con pseudotraducciones instantáneas.
Compilación de producción
{
buildMode: "cache-only", // Use pre-generated translations
}
Ejecuta npm run build para compilar para producción. No se necesitan claves de API: las traducciones provienen de .lingo/metadata.json.
Buena práctica: Genera traducciones reales en CI antes de compilar para producción. Consulta Modos de compilación para el flujo de trabajo recomendado.
Compatibilidad con Turbopack
El compilador funciona tanto con Webpack como con Turbopack (Next.js 15+).
Para usar Turbopack en desarrollo:
next dev --turbo
El compilador detecta y configura automáticamente el empaquetador apropiado.
TypeScript
El compilador está completamente tipado. Importa los tipos desde @lingo.dev/compiler:
import type { LingoConfig } from "@lingo.dev/compiler";
const config: LingoConfig = {
sourceRoot: "./app",
sourceLocale: "en",
targetLocales: ["es", "de"],
models: "lingo.dev",
};
Problemas comunes
"Cannot find module '@lingo.dev/compiler/react'"
Asegúrate de haber instalado el paquete: pnpm install @lingo.dev/compiler
HMR no funciona después de añadir LingoProvider
Asegúrate de que LingoProvider esté colocado correctamente en tu layout raíz, no en un layout o página anidados.
Las traducciones no se muestran en la compilación de producción
Verifica que estés usando buildMode: "cache-only" y que .lingo/metadata.json contenga traducciones para todos los locales.
"Missing translations for locale X"
Ejecuta tu servidor de desarrollo con usePseudotranslator: false para generar traducciones reales, o ejecuta una compilación de CI para poblar .lingo/metadata.json.
Próximos pasos
- Referencia de configuración — Todas las opciones de configuración
- Resolvers de locale personalizados — Personaliza la detección de locale
- Sobrescrituras manuales — Sobrescribe traducciones específicas
- Mejores prácticas — Patrones y flujos de trabajo recomendados