← Apprendre

Dépannage

Chaque entrée ci-dessous correspond à un mode de défaillance réellement rencontré. Chacune indique le symptôme, la cause et la solution — la plupart se résument à l'une de ces trois causes : la phrase ne figure pas dans le projet, le SDK n'a jamais été initialisé, ou un espace réservé a été écrit pour le mauvais contexte.

Rien n’est traduit — chaque phrase reste dans la langue source

Quand tout s’affiche en texte source, c’est presque certainement que le SDK n’a pas pu s’initialiser. Il échoue en douceur par conception (votre interface ne doit jamais planter), donc le seul signal visible est la console du navigateur — consultez-la en premier. Les causes habituelles, par ordre de probabilité :

  1. CORS. La première requête du SDK est authorize-project ; si votre API n'autorise pas explicitement l'origine de l'application, le navigateur la bloque et l'initialisation échoue aussitôt. Rappelez-vous qu'une origine correspond exactement à schéma + hôte + port : localhost:5173 et localhost:5174 sont des origines différentes, et les serveurs de développement changent de port lorsque leur port habituel est déjà pris. Autorisez chaque port sur lequel vous développez réellement.
  2. Identifiants incorrects. Un identifiant de projet ou une clé d'API manquant ou mal saisi fait échouer le même appel d'autorisation. La console affiche la requête en échec et son URL.
  3. Vous consultez la locale de base. Dans la locale de base, la « traduction » est le texte source — rien ne change visuellement. Passez à une locale cible pour tester.
L'échec CORS et sa solution
# 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

Une phrase ne se traduit pas (mais les autres, si)

La phrase dans votre code sert de clé de recherche — la phrase est la clé. Si une phrase isolée s'affiche en texte source alors que les phrases voisines sont traduites, c'est que cette clé ne figure pas dans le catalogue du projet :

Pourquoi les phrases manquantes ne génèrent-elles pas d'erreur ?

C'est voulu. En production, un système de traduction doit se dégrader vers un texte source lisible, jamais vers une page cassée — ainsi, une phrase non enregistrée s'affiche dans sa version source et le SDK reste silencieux. Revers de la médaille : avec une clé en lecture seule, une phrase manquante est silencieuse. Rien n'est journalisé, rien n'est enregistré, et vous ne l'apprenez que lorsqu'un utilisateur voit de l'anglais. Ce qui l'évite, c'est la séparation des clés : développez avec une clé d'écriture pour que chaque phrase affichée par votre interface soit découverte, puis déployez en lecture seule.

Clé d’écriture en dev, lecture seule en prod
# 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

Mon espace réservé s'affiche tel quel — « Hi %name% » ou « Hi {name} »

Ça fonctionne, puis ça se casse après plusieurs changements de locale successifs

Mettez à jour le SDK. Voici de vrais bugs corrigés dans ce domaine : le retour à la locale initiale/SSR laissait le catalogue précédent actif (corrigé dans langsys-js-typescript 0.2.2), et les consommateurs de Translate/Phrase en mode bloc de contenu pouvaient se bloquer indéfiniment sur un catalogue initialisé côté serveur (corrigé dans la 0.2.3). Si vous voyez des chaînes dans une ancienne locale ou des blocs qui ne se résolvent jamais, comparez votre version installée avec le journal des modifications du SDK de base avant de déboguer votre propre code.

Côté serveur : la page renvoie une erreur 500 au lieu de se dégrader en douceur

Le client du SDK PHP génère une exception s'il est construit sans identifiants : une application Laravel (ou PHP standard) dont LANGSYS_API_KEY est vide échoue donc dès la résolution du conteneur, avant toute traduction. Définissez les identifiants (ou, pour une application qui doit pouvoir démarrer sans eux, liez un client factice comme le font les applications de démo). Une fois les identifiants en place, les échecs de l'API à l'exécution se dégradent en douceur : si l'API est injoignable ou refuse la requête, le texte source est affiché et l'exception est signalée, sans jamais faire tomber la page.

Côté serveur : la première requête se bloque, puis tout est rapide

Le délai d’expiration HTTP du SDK PHP est de 30 secondes, et une instance d’API qui sort de veille peut s’en approcher dès le tout premier appel. Cette requête soit aboutit lentement (et réchauffe le cache du catalogue — tout ce qui suit est servi depuis le cache), soit expire et affiche le texte source. Si le premier chargement de page après une période d’inactivité est lent, c’est la raison : c’est l’API qui se réchauffe, pas votre intégration.

Côté serveur : j’ai effectué le rendu avec une clé d’écriture, mais la phrase n’apparaît pas dans le tableau de bord

Les phrases découvertes sont mises en file d'attente pendant la requête et envoyées après l'envoi de la réponse — c'est le middleware terminable de Laravel. Actualisez le tableau de bord un instant après le chargement de la page, et non pendant. Sur les environnements d'exécution de workers persistants (Octane, FrankenPHP, RoadRunner), assurez-vous d'utiliser l'intégration fournie par le SDK : le hook d'arrêt PHP standard n'est jamais déclenché entre deux requêtes d'un worker.

Rendu côté serveur : les traductions d'une requête se retrouvent dans une autre

Le SDK JS de base ne conserve que le catalogue d'une seule locale à la fois : c'est un singleton au niveau du module. Un serveur Node qui génère des locales différentes pour des requêtes simultanées va se heurter à des conflits d'accès. Récupérez le catalogue à chaque requête et initialisez le client avec celui-ci, comme dans les guides Next.js, Nuxt et SvelteKit, ou exécutez une locale par processus.

Toujours bloqué ? Ouvrez un ticket sur le dépôt du SDK — typescript, react, vue, svelte, php ou laravel — en joignant la sortie de la console (ou le journal du serveur) de la requête en échec. Vous pouvez aussi écrire à [email protected].

Rechercher dans la documentation et le centre d'apprentissage