← Aprender

Solución de problemas

Cada entrada aquí es un modo de falla que alguien realmente encontró. Cada una indica el síntoma, por qué ocurre y la solución; la mayoría se reduce a una de tres cosas: la frase no está en el proyecto, el SDK nunca se inicializó o un marcador de posición se escribió para el contexto equivocado.

Nada se traduce: todas las frases permanecen en el idioma de origen

Cuando todo muestra el texto de origen, lo más probable es que el SDK no se haya inicializado. Está diseñado para fallar de forma silenciosa (tu interfaz nunca debe romperse), así que la única señal clara es la consola del navegador: revísala primero. Las causas habituales, por orden de probabilidad:

  1. CORS. La primera solicitud del SDK es authorize-project; si tu API no incluye el origen de la app en su lista de permitidos, el navegador la bloquea y la inicialización falla ahí mismo. Recuerda que un origen es exactamente esquema + host + puerto: localhost:5173 y localhost:5174 son orígenes distintos, y los servidores de desarrollo cambian de puerto cuando el habitual está ocupado. Agrega a la lista de permitidos todos los puertos que uses realmente para desarrollar.
  2. Credenciales incorrectas. Un ID de proyecto o una clave de API faltante o con errores de escritura hace fallar la misma llamada de autorización. La consola muestra la solicitud fallida y la URL.
  3. Estás viendo la configuración regional base. En la configuración regional base, la "traducción" es el texto original, por lo que no hay cambios visibles. Cambia a una configuración regional de destino para probar.
El fallo de CORS y su solución
# The SDK's first call is an authorize-project request.
# If the browser blocks it, NOTHING translates. Check the console for:
Access to fetch at 'https://your-api/api/authorize-project/...'
from origin 'http://localhost:5173' has been blocked by CORS policy

# Fix: allowlist the app's EXACT origin (scheme + host + port) on the API.
CORS_ALLOWED_ORIGINS=http://localhost:5173,https://app.example.com

Una frase no se traduce (pero otras sí)

La frase en tu código es la clave de búsqueda: la frase es la clave. Si una sola frase se muestra como texto fuente mientras las demás se traducen, esa clave no está en el catálogo del proyecto:

¿Por qué las frases faltantes no generan un error?

Es intencional. En producción, un sistema de traducción debe degradarse a texto fuente legible, nunca a una página rota; por eso una frase no registrada muestra su texto original y el SDK no emite avisos. La contrapartida: con una clave de solo lectura, una frase faltante es silenciosa. No se registra nada, no se guarda nada, y lo primero que te enteras es cuando un usuario ve inglés. La disciplina que lo evita es la separación de claves: desarrolla con una clave de escritura para que se descubra cada frase que renderiza tu interfaz, y luego publica con una clave de solo lectura.

Clave de escritura en desarrollo, de solo lectura en producción
# Development — write key: new phrases are discovered,
# registered, and machine-translated as you build.
VITE_LANGSYS_API_KEY=write-key

# Production — read-only key: fetches the finished catalog only.
# Unregistered phrases silently render their source text.
VITE_LANGSYS_API_KEY=read-only-key

Mi marcador de posición se muestra literalmente: "Hi %name%" o "Hi {name}"

Funciona, pero se rompe después de cambiar de idioma varias veces

Actualiza el SDK. Errores reales ya corregidos en esta área: volver a la configuración regional inicial o de SSR dejaba activo el catálogo anterior (corregido en langsys-js-typescript 0.2.2), y los consumidores de Translate/Phrase de bloques de contenido podían quedarse colgados para siempre con un catálogo precargado por el servidor (corregido en 0.2.3). Si ves cadenas de una configuración regional anterior o bloques que nunca se resuelven, compara tu versión instalada con el registro de cambios del SDK base antes de depurar tu propio código.

Del lado del servidor: la página devuelve un error 500 en lugar de degradarse con elegancia

El cliente del SDK de PHP lanza una excepción si se construye sin credenciales, así que una aplicación Laravel (o PHP simple) con LANGSYS_API_KEY vacía falla al resolver el contenedor, antes de que se ejecute cualquier traducción. Configura las credenciales (o, si la aplicación debe iniciar sin ellas, vincula un cliente sustituto como lo hacen las aplicaciones de demostración). Una vez que existen las credenciales, las fallas de la API en tiempo de ejecución sí se manejan sin romper nada: si la API no está disponible o rechaza la solicitud, se muestra el texto original y se reporta la excepción; nunca se cae la página.

En el servidor: la primera solicitud se queda colgada, luego todo es rápido

El tiempo de espera HTTP del SDK de PHP es de 30 segundos, y una instancia de la API que se reactiva tras estar inactiva puede acercarse a ese límite en la primera llamada. Esa solicitud o bien se completa con lentitud (y calienta la caché del catálogo: todo lo que sigue se sirve desde la caché) o bien agota el tiempo de espera y muestra el texto original. Si la primera carga de página después de un periodo de inactividad es lenta, esta es la razón: es la API que se está calentando, no tu integración.

Del lado del servidor: rendericé con una clave de escritura, pero la frase no aparece en el panel

Las frases descubiertas se ponen en cola durante la solicitud y se envían después de que se envía la respuesta, como el middleware terminable de Laravel. Actualiza el panel un momento después de que cargue la página, no durante la carga. En entornos de ejecución de workers de larga duración (Octane, FrankenPHP, RoadRunner), asegúrate de usar la integración que proporciona el SDK: el hook de cierre de PHP estándar nunca se activa entre las solicitudes de un worker.

Renderizado en el servidor: las traducciones de una solicitud se filtran a otra

El SDK base de JS mantiene el catálogo de una sola configuración regional a la vez: es un singleton a nivel de módulo. Un servidor Node que renderiza distintas configuraciones regionales para solicitudes concurrentes tendrá condiciones de carrera. Obtén el catálogo en cada solicitud e inicializa el cliente con él, el patrón de las guías de Next.js, Nuxt y SvelteKit, o ejecuta una configuración regional por proceso.

¿Sigues atascado? Abre un issue en el repositorio del SDK (typescript, react, vue, svelte, php o laravel) con la salida de la consola (o el registro del servidor) de la solicitud que falla. O escribe a [email protected].

Buscar en la documentación y el Centro de aprendizaje