Next.js
El paquete translate-projects-nextjs tiene dos partes: un comando que traduce tus archivos JSON y utilidades para usarlos en Next.js (App Router): middleware de idioma, provider de i18next, Link y hooks con autocompletado.
Requisitos
- Node.js 20 o superior.
- Next.js 14 o superior y React 18 o superior. Son dependencias peer: el paquete usa las de tu proyecto.
- Un proyecto y un API token de Translate Projects. Mira Primeros pasos.
1. Instala el paquete
npm i translate-projects-nextjs
i18next y react-i18next se instalan con el paquete.
2. Escribe tus textos
Pon los textos del idioma base en src/locales/<idioma base>/. Cada archivo JSON (también en subcarpetas) es un namespace de i18next y se conserva el anidamiento:
{
"home": {
"title": "Bienvenido"
}
}
3. Configura la traducción
Crea translate.config.mjs en la raíz. El API token se lee de la variable de entorno TRANSLATE_PROJECTS_API_KEY:
export default {
sourceLang: 'es', // Idioma base: el idioma por defecto del proyecto
targetLangs: ['en', 'pt-BR', 'fr'], // Idiomas a generar
apiKey: process.env.TRANSLATE_PROJECTS_API_KEY,
// outputDir: './src/locales', // Valor por defecto
// scanner: true, // Opcional: extrae t('...') y <Trans> de ./src
};
Añade el script en package.json:
{
"scripts": {
"translate": "translate-projects-nextjs translate"
}
}
4. Traduce
export TRANSLATE_PROJECTS_API_KEY=tu_token
npm run translate
El comando no lee archivos .env por sí solo: exporta la variable en la terminal o en CI, o cárgala tú, por ejemplo con node --env-file=.env.local node_modules/.bin/translate-projects-nextjs translate. Termina con código 0 si todos los idiomas se tradujeron y con 1 ante cualquier error.
Archivos que genera
src/locales/
├── es/translation.json ← tu idioma base
├── en/translation.json ← generado
├── pt-BR/translation.json
└── fr/translation.json
Haz commit de los archivos generados: la app los importa al compilar. No los edites a mano, se sobrescriben en la siguiente ejecución. Con el escáner activado, <idioma base>/translation.json también se sobrescribe con los textos encontrados en el código.
5. Usa las traducciones en Next.js
Middleware
Redirige a /<idioma>/... y guarda el idioma en la cookie NEXT_LOCALE. Las rutas /_next, /api, /locales y /favicon.ico se ignoran siempre.
import { NextRequest } from 'next/server';
import { langMiddleware } from 'translate-projects-nextjs/middleware';
export function middleware(request: NextRequest) {
return langMiddleware({
request,
defaultLocale: 'es',
locales: ['es', 'en', 'pt-BR', 'fr'],
ignorePaths: ['/images'], // Opcional
});
}
Provider
import { TranslationsProvider } from 'translate-projects-nextjs/provider';
import es from '@/locales/es/translation.json';
import en from '@/locales/en/translation.json';
export default async function Layout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
return (
<html lang={locale}>
<body>
<TranslationsProvider
lng={locale as any}
initialLocale={locale as any}
i18nConfig={{
fallbackLng: ['es'],
supportedLngs: ['es', 'en'],
resources: {
es: { translation: es },
en: { translation: en },
},
}}
>
{children}
</TranslationsProvider>
</body>
</html>
);
}
Textos con autocompletado
'use client';
import { useTypedTranslation } from 'translate-projects-nextjs/hooks';
import type es from '@/locales/es/translation.json';
export function Title() {
const { t } = useTypedTranslation<typeof es>();
return <h1>{t('home.title')}</h1>; // Las claves se autocompletan
}
useTranslation y <Trans> de react-i18next también funcionan.
Navegación
'use client';
import { Link } from 'translate-projects-nextjs/link';
import { useLocalizedRouter } from 'translate-projects-nextjs/hooks';
export function Nav() {
const router = useLocalizedRouter();
return (
<>
<Link href="/about">About</Link> {/* -> /<locale>/about */}
<button onClick={() => router.push('/', undefined, 'en')}>English</button>
</>
);
}
Caché y forzar
Los archivos sin cambios no se envían ni se traducen otra vez: una ejecución sin cambios hace una sola petición. Si borras un archivo generado, se vuelve a escribir desde la caché sin nuevas peticiones. Este paquete no tiene --force: para traducir todo de nuevo, borra ~/.config/translate-projects-core/cache.json (afecta a todos los proyectos del equipo, cada uno se sincroniza una vez) y vuelve a ejecutar. Más detalles en Caché y errores.
Errores comunes
Si la API falla o devuelve un resultado parcial, las traducciones existentes se conservan, el comando termina con código 1 y los textos que faltan se reintentan en la siguiente ejecución.
- Token inválido (401): revisa
TRANSLATE_PROJECTS_API_KEY. - Falta la key de IA (
MISSING_API_KEY): configura el proveedor, el modelo y la key en el proyecto. Mientras tanto, los textos sin traducción no se escriben en el archivo e i18next muestra el texto defallbackLng. Missing required configuration fields: apiKey: la variableTRANSLATE_PROJECTS_API_KEYno está definida en la terminal donde ejecutas el comando.- No se encuentra
translate.config.mjs: el comando debe ejecutarse en la raíz del proyecto. - Conflicto de dependencias al instalar: comprueba que tu proyecto use Next.js 14 o superior y React 18 o superior.
🚀 Automatiza tus traducciones gratis
Translate Projects es gratuito. Creas tu proyecto, conectas la key de tu proveedor de IA y solo le pagas a él lo que gastes.
- Sin planes ni tarjeta de crédito: Todas las funciones están disponibles desde el primer día.
- Usa tu propia IA: Claude, OpenAI, DeepSeek o Gemini. Tu key se guarda cifrada.
- Red de traducciones compartida: Si un texto ya fue traducido, lo recibes al instante sin gastar tu key.
- Panel de administración: Revisa y edita todas tus traducciones desde un solo lugar.
Estamos aquí para ayudarte
Si tienes alguna pregunta, necesitas ayuda o quieres contribuir, no dudes en contactarme. Estoy a tu disposición para apoyarte en lo que necesites.
- Sitio web: neiderruiz.com
- GitHub: @neiderruiz
- Twitter: @neiderruiz
- YouTube: Neider Ruiz
Apoya el Proyecto
Si este proyecto te ha sido útil, te invito a invitarme un café. Tu apoyo me ayuda a seguir mejorando y creando contenido de valor. ¡Gracias por estar aquí! ☕