La localisation comme étape de pipeline.
Enveloppez une chaîne dans _(), remplissez toutes les locales avec une seule commande, et modifiez toute traduction en direct dans votre application — les fichiers .po de bout en bout, réécrits directement dans votre dépôt. Ou gérez le tout vous-même avec une véritable API HTTP.
Outils de construction pour JavaScript et TypeScript.
Quatre paquets npm permettent à Echo Lingua de passer d'une chaîne marquée à une traduction déployée, sans quitter votre codebase : le runtime @echo-lingua/i18n, l'extraction et la compilation avec @echo-lingua/i18n-cli, le remplissage de chaque locale avec @echo-lingua/sdk, et l'édition en direct dans le navigateur avec @echo-lingua/inline-editor. Le même @echo-lingua/i18n-cli gère aussi PHP et Laravel ; voir outils de build pour chaque plateforme ci-dessous.
@echo-lingua/i18n
Entourez les chaînes avec _() ; le i18n-cli extrait un .po par locale et compile un runtime léger.
@echo-lingua/sdk
Remplissez toutes les locales via l'API — depuis la CLI ou un client typé.
Traduire →@echo-lingua/inline-editor
Une barre d'outils de développement pour modifier les traductions dans l'application en cours d'exécution.
Modifier dans le navigateur →Enveloppez une chaîne. Expédiez un runtime léger.
Entourez le texte de l'UI avec _() provenant du runtime @echo-lingua/i18n ; l'outil @echo-lingua/i18n-cli scanne votre source, hydrate un .po par locale, et compile les éléments traduits dans un runtime compact avec placeholders, pluriels et texte enrichi. Ajoutez un contexte, des drapeaux ou une note au modèle directement sur le site d'appel. Le runtime est optionnel et uniquement JS ; le CLI est la moitié indépendante du projet.
marquez les chaînes, ajoutez des indicateurs si nécessaireimport { _, EL } from '@echo-lingua/i18n'; _('Save changes'); _('Hello {name}', { name }); _('You have {count} item', 'You have {count} items', { count }); // La suite des options : indicateurs, un msgctxt et une note pour le modèle. _('Order', {}, { context: 'verb' }); _('Save', {}, { flags: [EL.CONTEXT_UI_LABEL] }); _('There is a file', 'There are {count} files', { count }, { flags: [EL.QUALITY_PRO, EL.CONTEXT_LEGAL], comment: 'Shown under the section title', });
extraire → compiler# Le runtime pour votre application, la chaîne d'outils pour votre build npm i @echo-lingua/i18n npm i -D @echo-lingua/i18n-cli # Scannez le code, hydratez un .po par locale npx echo-lingua-i18n extract # Compiler les catalogues traduits dans le runtime npx echo-lingua-i18n compile
Outils de build pour chaque plateforme.
L'extracteur et compilateur, @echo-lingua/i18n-cli, est indépendant du projet. Il scanne JavaScript, TypeScript et PHP (y compris les modèles .phtml), hydrate les mêmes fichiers .po et les compile vers ce que votre runtime lit nativement : le catalogue JS, un .mo binaire pour gettext() PHP, ou du JSON plat pour __() Laravel. Il n'y a pas de runtime Echo Lingua à adopter en dehors de JS ; vous gardez le vôtre. Toute autre pile gettext (Python, Go, C) pilote la même plateforme via l'API HTTP ci-dessous.
marquer des chaînes en PHP ou .phtml<?php // Marquez les chaînes avec les fonctions gettext / Laravel que vous utilisez déjà _('Account settings'); ngettext('one invoice', '{count} invoices', $n); pgettext('nav', 'Home'); __('Welcome back'); // clé de chaîne Laravel
compiler des cibles natives// i18n.config.mjs — une configuration pour toute la chaîne d'outils export default { locales: ['de', 'fr'], include: ['src/**/*.{php,phtml}'], compileTargets: ['mo'], // ou 'laravel' (JSON plat), ou 'js' }; # Écrit un .mo natif par locale pour PHP gettext() npx echo-lingua-i18n sync
Traduisez depuis la CLI ou votre propre code.
Le client API et la CLI de traduction. echo-lingua translate lit votre configuration, remplit le .po de chaque locale via l'API et les réécrit. Ou appelez le client typé depuis votre propre code — créez une tâche, attendez, téléchargez la sortie formatée pour votre dépôt.
la CLI de traduction# Remplir le .po de chaque locale via l'API, en place npm i @echo-lingua/sdk # Lit votre configuration, réécrit les traductions npx echo-lingua translate
ou le client typéimport { EchoLingua } from '@echo-lingua/sdk'; const el = new EchoLingua({ apiKey: process.env.ECHO_LINGUA_KEY }); // Créez une tâche, attendez qu'elle se termine, récupérez le fichier zip formaté pour votre dépôt. const job = await el.createJob({ sourceLanguage: 'en', contextMode: 'ui-label', quality: 'standard', inputs: [{ filename: 'de/messages.po', targetLanguage: 'de', content }], }); const done = await el.waitForJob(job.id, { onProgress: (j) => log(j.status) }); const zip = await el.downloadJob(done.id);
Modifier les traductions dans l'application en cours d'exécution.
Une barre d'outils réservée au développement s'intègre à votre application. Maintenez Alt et cliquez sur n'importe quelle chaîne traduite pour modifier sa traduction en direct, corriger la source anglaise, ajouter un contexte ou des indicateurs, ou laisser l'IA corriger, raccourcir ou retraduire automatiquement. Gérez les formes plurielles, remplacez l'anglais affiché et exécutez l'intégralité du cycle extraction → traduction → compilation — chaque modification est directement réécrite dans votre dépôt.
ajouter le plugin Vite (développement uniquement)// vite.config.ts — dev only import { echoLinguaBabel, echoLinguaInlineEditor } from '@echo-lingua/inline-editor'; export default defineConfig(({ command }) => ({ plugins: [ react(command === 'serve' ? { babel: { plugins: [echoLinguaBabel()] } } : {}), echoLinguaInlineEditor(), ], }));
@echo-lingua/inline-editor
L'éditeur dans le navigateur. Il s'associe à @echo-lingua/i18n — une transformation Babel fait correspondre chaque clic à l'appel _() exact, et un serveur de développement lit et écrit vos fichiers .po et votre code source. Jamais expédié en production.
Ou configurez-le vous-même.
Vous n'utilisez pas JavaScript ou vous automatisez depuis une autre pile ? Chaque fonctionnalité ci-dessus est un simple appel HTTP — une clé, une requête POST, un webhook signé une fois terminé. Cela fonctionne avec n'importe quel projet gettext, dans n'importe quel langage.
Estimez le coût, puis créez la tâche.
Testez la taille et le coût d'abord avec /v1/jobs/estimate — rien n'est facturé — puis créez l'exécution avec le même corps. Chaque entrée inputs est un fichier .po avec son propre targetLanguage ; sourceLanguage et contextMode sont requis, quality est draft, standard ou pro.
POST /v1/jobs/estimatecurl -X POST https://api.echo-lingua.com/v1/jobs/estimate \ -H "Authorization: Bearer $ECHO_LINGUA_KEY" \ -H "Content-Type: application/json" \ -d @job.json # same body as the create call — nothing is charged
200 · taille + coût, aucun frais facturé{
"entries": 550,
"chunks": 10,
"words": 7400,
"chargedMicros": 2386500,
"creditRequiredMicros": 2505825
}POST /v1/jobscurl -X POST https://api.echo-lingua.com/v1/jobs \ -H "Authorization: Bearer $ECHO_LINGUA_KEY" \ -H "Content-Type: application/json" \ -d '{ "sourceLanguage": "en", "contextMode": "ui-label", "quality": "standard", "inputs": [ { "filename": "de/messages.po", "targetLanguage": "de", "content": "…" }, { "filename": "ar/messages.po", "targetLanguage": "ar", "content": "…" } ] }'
201 · la tâche créée{
"id": "job_8f2c41",
"status": "QUEUED",
"sourceLanguage": "en",
"contextMode": "ui-label",
"quality": "standard",
"createdAt": 1726669120000
}Un jeton bearer unique. Les portées que vous lui accordez.
Créez des clés dans l’application, chacune s’affiche once, comporte une date d’expiration et est révocable. L’utilisation est attribuée par clé. Authentifiez-vous avec un en-tête unique :
chaque requêteAuthorization: Bearer elk_live_2b7f…
# elk_-prefixed. Affiché une seule fois lors de la création, stockez-le dans un secret.translate:write
Créer des tâches, relancer les entrées en échec, annuler des exécutions.
jobs:read
Lire le statut et les totaux des tâches, lister les tâches, télécharger les sorties.
Livraison signée, fini l’interrogation.
Enregistrez un point de terminaison pour job.completed et job.failed. Chaque envoi est signé au format HMAC-SHA256 sur le corps brut, vérifiez-le avant de l’utiliser. Les nouvelles tentatives utilisent un délai exponentiel borné.
livraison · en-têtes et corpsPOST https://your-app.example/hooks/echo-lingua X-EchoLingua-Signature: 9f86d0818… (HMAC-SHA256 hexadécimal du corps brut) X-EchoLingua-Timestamp: 1726669123456 X-EchoLingua-Delivery: whd_3f9c8a { "id": "whd_3f9c8a", "type": "job.completed", "createdAt": 1726669123456, "data": { "jobId": "job_8f2c41", "status": "COMPLETE", "downloadUrl": "/v1/jobs/job_8f2c41/download" } }
verify.ts, sur le corps brutimport { createHmac, timingSafeEqual } from 'node:crypto'; // Vérifier sur le corps de requête BRUT, avant l'analyse JSON. export function verify(rawBody, signature, secret) { const expected = createHmac('sha256', secret).update(rawBody).digest('hex'); const a = Buffer.from(signature); const b = Buffer.from(expected); return a.length === b.length && timingSafeEqual(a, b); }
Traduisez lors de la publication, ouvrez la PR.
Déclenchez une tâche depuis votre CI, laissez le webhook signé vous avertir lorsqu’elle est terminée, puis récupérez la sortie structurée pour le dépôt et ouvrez une pull request, sans intervention d’un navigateur.
.github/workflows/translate.ymlname: Translate on release
on:
release:
types: [published]
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Kick off a translation job
run: |
curl -sS -X POST https://api.echo-lingua.com/v1/jobs \
-H "Authorization: Bearer ${{ secrets.ECHO_LINGUA_KEY }}" \
-H "Content-Type: application/json" \
-d @job.json
# Un webhook `job.completed` signé ouvre la PR avec les catalogues traduits.Les points de terminaison que vous utiliserez réellement.
Les points de terminaison ci-dessus sont ceux que vous solliciterez en premier. Voir tous les points de terminaison dans la documentation →
Traduisez chaque locale directement depuis votre pipeline.
Créez une clé ciblée, envoyez une tâche en POST et configurez le webhook. Les frais de service de votre premier mois sont pour nous.
Obtenir une clé API