¿Deseas implementar soporte multilingüe profesional en una aplicación estática construida con Next.js 13? Aunque Symfony/Translation es una biblioteca de PHP, su robustez la hace ideal para gestionar traducciones durante el proceso de generación estática. Esta guía muestra cómo integrarla efciazmente en un entorno moderno basado en JavaScript.
Ventajas clave de Symfony/Translation
- Compatibilidad con múltiples formatos: admite archivos en JSON, YAML, XLIFF y gettext (PO).
- Gestión avanzada de plurales: maneja reglas lingüísticas complejas para diferentes idiomas.
- Carga modular: permite definir fuentes personalizadas de traducciones (archivos, bases de datos, etc.).
- Herramientas de extracción: facilita la identificación automática de cadenas traducibles en el código fuente.
Estructura recomendada del proyecto
locales/
├── en/
│ ├── messages.json
│ └── validation.json
├── fr/
│ ├── messages.json
│ └── validation.json
└── es/
├── messages.json
└── validation.json
Configuración básica
Aunque Next.js no ejecuta PHP en tiempo de ejecución, puedes usar Symfony/Translation durante la fase de construcción. Primero, instala la biblioteca mediante Composer:
composer require symfony/translation
Generación estática con traducciones preprocesadas
Durante el build de Next.js, ejecuta un script PHP que procese los catálogos de traducción y genere archivos JSON consumibles por el front end:
$translator = new \Symfony\Component\Translation\Translator('es');
$translator->addLoader('json', new \Symfony\Component\Translation\Loader\JsonFileLoader());
$translator->addResource('json', __DIR__.'/locales/es/messages.json', 'es');
// Exporta todas las traducciones a un archivo plano
$catalogue = $translator->getCatalogue('es');
file_put_contents('public/locales/es.json', json_encode($catalogue->all()));
Consumo en el frontend de Next.js
En el lado del cliente, carga las traducciones generadas estáticamente según el idioma activo:
// hooks/useTranslation.ts
import { useEffect, useState } from 'react';
export const useTranslation = (locale: string) => {
const [messages, setMessages] = useState<Record<string, string>>({});
useEffect(() => {
fetch(`/locales/${locale}.json`)
.then(res => res.json())
.then(data => setMessages(data));
}, [locale]);
return (key: string) => messages[key] || key;
};
Manejo de plurales
Symfony/Translation permite expresar formas plurales con sintaxis explícita. Durante la generación estática, estas reglas se resuelven y se almacenan como valores concretos:
// En PHP (durante el build)
$count = 3;
$text = $translator->trans('%count% manzana|%count% manzanas', ['%count%' => $count], null, 'es');
Rutas multilingües en App Router
Utiliza el sistema de rutas dinámicas de Next.js 13 para segmentar por idioma:
// app/[lang]/page.tsx
export async function generateStaticParams() {
return [{ lang: 'en' }, { lang: 'es' }, { lang: 'fr' }];
}
export default function Home({ params }: { params: { lang: string } }) {
// Renderiza contenido usando `params.lang`
}
Optimización y mantenimiento
- Extracción automática: usa herramientas como
PhpAstExtractorpara escanear componentes y extraer claves traducibles. - Sincronización de catálogos: emplea operaciones de fusión (
MergeOperation) para mantener coherecnia entre idiomas. - SEO multilingüe: genera etiquetas
<link rel="alternate" hreflang="..." />dinámicamente en cada página.
Consideraciones finales
La integración de Symfony/Translation en un flujo de trabajo de Next.js 13 requiere un enfoque híbrido: PHP para el procesamiento de traducciones en tiempo de compilación, y JavaScript para la renderización en el cliente. Este modelo aprovecha lo mejor de ambos ecosistemas, permitiendo aplicaciones estáticas altamente escalables con soporte lingüístico profesional.