Casi todos los proyectos de Next.js con i18n acaban igual: un translation.json en español y una tarde copiándolo en ChatGPT, pegando la respuesta y revisando que no se haya cambiado ninguna clave. Luego alguien añade un texto y vuelta a empezar.
En esta guía traducimos una app de Next.js (App Router) del español a inglés, japonés, portugués y francés con un solo comando, npm run translate, usando i18next y el paquete translate-projects-nextjs. Todo lo que ves abajo (archivos y terminal) es la salida real de una ejecución.
Qué necesitas
- Node.js 20 o superior, Next.js 14+ y React 18+.
- Una cuenta gratis de Translate Projects con un proyecto y su API token (Primeros pasos).
- La API key de tu proveedor de IA: Claude, OpenAI, DeepSeek o Gemini. No hay planes ni tarjeta: pagas solo a tu proveedor por lo que uses.
1. Instala el paquete
npm i translate-projects-nextjs
i18next y react-i18next se instalan con el paquete.
2. Escribe tus textos en el idioma base
Cada archivo JSON dentro de src/locales/<idioma base>/ es un namespace de i18next, y el anidamiento se conserva. Este es el archivo de la app de ejemplo:
// src/locales/es/translation.json
{
"nav": {
"inicio": "Inicio",
"precios": "Precios"
},
"hero": {
"titulo": "Organiza tus tareas sin perder el ritmo",
"subtitulo": "Planifica tu semana, comparte proyectos con tu equipo y recibe recordatorios a tiempo.",
"boton": "Empieza gratis"
},
"login": {
"email": "Correo electrónico",
"password": "Contraseña",
"entrar": "Iniciar sesión",
"olvido": "¿Olvidaste tu contraseña?"
}
}
3. Configura los idiomas
Crea translate.config.mjs en la raíz del proyecto. El token se lee de la variable de entorno TRANSLATE_PROJECTS_API_KEY:
export default {
sourceLang: 'es',
targetLangs: ['en', 'ja', 'pt-BR', 'fr'],
apiKey: process.env.TRANSLATE_PROJECTS_API_KEY,
};
Y 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
Salida real de la ejecución (sin las marcas de tiempo):
✅ Success: Total languages to translate: 4
ℹ️ Info: 🔄 Syncing (9) - src/locales/es/translation.json...
✅ Success: Translation completed: EN 📄 -> 📁 `src/locales/en/translation.json`
✅ Success: Translation completed: JA 📄 -> 📁 `src/locales/ja/translation.json`
✅ Success: Translation completed: PT-BR 📄 -> 📁 `src/locales/pt-BR/translation.json`
✅ Success: Translation completed: FR 📄 -> 📁 `src/locales/fr/translation.json`
✅ Success: Translation completed successfully.
Nueve textos a cuatro idiomas tardaron unos 14 segundos. Así queda el inglés, con las mismas claves:
// src/locales/en/translation.json
{
"nav": {
"inicio": "Home",
"precios": "Pricing"
},
"hero": {
"titulo": "Organize your tasks without losing momentum",
"subtitulo": "Plan your week, share projects with your team and get reminders on time.",
"boton": "Start for free"
},
"login": {
"email": "Email",
"password": "Password",
"entrar": "Sign in",
"olvido": "Forgot your password?"
}
}
Y el japonés:
// src/locales/ja/translation.json
{
"nav": {
"inicio": "ホーム",
"precios": "料金"
},
"hero": {
"titulo": "ペースを崩さずタスクを整理しよう",
"subtitulo": "週間計画を立て、チームとプロジェクトを共有し、期限に合わせてリマインダーを受け取れます。",
"boton": "無料で始める"
},
"login": {
"email": "メールアドレス",
"password": "パスワード",
"entrar": "ログイン",
"olvido": "パスワードをお忘れですか?"
}
}
El comando no lee .env por sí solo: exporta la variable en la terminal o en CI, o cárgala con node --env-file=.env.local node_modules/.bin/translate-projects-nextjs translate.
5. Usa las traducciones en Next.js
El paquete trae también la parte de la app: un middleware que redirige a /<idioma>/... y guarda la cookie NEXT_LOCALE, un provider de i18next, un Link localizado y hooks con autocompletado de claves.
// middleware.ts
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', 'ja', 'pt-BR', 'fr'],
});
}
// app/[locale]/title.tsx
'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('hero.titulo')}</h1>; // las claves se autocompletan
}
El provider (TranslationsProvider) va en app/[locale]/layout.tsx; el código completo está en la guía de Next.js. useTranslation y <Trans> de react-i18next también funcionan.
Cómo evita traducir dos veces
- Solo se envían los archivos que cambiaron: una ejecución sin cambios hace una sola petición.
- Hay una red compartida de traducciones: si un texto ya se tradujo antes a ese idioma, llega al instante sin gastar tu key de IA.
- Si borras un archivo generado, se vuelve a escribir desde la caché sin peticiones nuevas.
- Si la API falla, las traducciones existentes se conservan, el comando sale con código 1 y lo que falte se reintenta en la siguiente ejecución.
Errores comunes
- Token inválido (401): revisa
TRANSLATE_PROJECTS_API_KEY. - Missing required configuration fields: apiKey: la variable no está definida en la terminal donde corres el comando.
- Falta la key de IA (MISSING_API_KEY): configura proveedor, modelo y key en el proyecto.
- No encuentra translate.config.mjs: ejecuta el comando en la raíz del proyecto.
También hay paquetes para React, Astro, Docusaurus (npm) y Django (PyPI). Crea tu proyecto gratis en translateprojects.dev y traduce tu app hoy.