Le CLI Lingo.dev traduit les ressources de chaînes Android (strings.xml) via un moteur de localisation configuré. Avec le format android, le CLI comprend nativement les éléments <resources>, <string>, <string-array> et <plurals>, tout en préservant la structure XML et en générant les bonnes catégories de pluriel pour chaque langue cible.
Ce guide vous explique, de bout en bout, comment localiser une application Android : configurer le CLI, traduire en local et automatiser le tout en CI pour livrer les traductions à chaque push.
Dépôt de démonstration
Clonez ou forkez lingodotdev/android-app-localization-example pour suivre ce guide. Le dépôt contient un projet Android opérationnel avec des ressources de chaînes, une configuration CLI Lingo.dev et des traductions déjà commit pour chaque langue cible.
Comment fonctionne la localisation Android#
Android s’appuie sur une convention de répertoires de ressources où chaque langue dispose de son propre répertoire values-[locale]/. Le système charge le bon fichier strings.xml à l’exécution, en fonction de la langue définie sur l’appareil.
app/src/main/res/
values/ # Default (source) strings
strings.xml
values-es/ # Spanish
strings.xml
values-fr/ # French
strings.xml
values-ja/ # Japanese
strings.xmlUn fichier strings.xml standard contient trois types d’éléments :
<resources>
<!-- Simple strings -->
<string name="app_name">My App</string>
<string name="welcome_message">Welcome back!</string>
<!-- String arrays -->
<string-array name="planets">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
</string-array>
<!-- Plurals -->
<plurals name="items_count">
<item quantity="one">%d item</item>
<item quantity="other">%d items</item>
</plurals>
</resources>Le CLI analyse ces trois types d’éléments, traduit leur contenu via le moteur de localisation, puis écrit un fichier par langue dans les bons répertoires values-[locale]/.
Prérequis#
Créer un moteur de localisation
À chaque exécution du CLI, le contenu passe par un moteur de localisation : la configuration qui détermine le modèle de LLM, le glossaire, la voix de marque et les règles à appliquer. Créez-en un dans le tableau de bord Lingo.dev.
Vérifier Node.js
Le CLI nécessite Node.js 22 ou une version supérieure :
node -vInstaller le CLI
Installez le CLI globalement pour exposer la commande lingo :
npm install -g @lingo.dev/cliSe connecter
Authentifiez-vous avec un mot de passe à usage unique :
lingo loginPour la CI, utilisez plutôt une clé API — passez --api-key ou définissez LINGO_API_KEY.
Configurer votre projet Android
Votre projet doit inclure un fichier strings.xml par défaut dans app/src/main/res/values/. Android Studio crée ce fichier lorsque vous démarrez un nouveau projet. Consultez le guide de localisation d’Android pour configurer les répertoires de ressources.
Configurer le CLI#
Exécutez lingo init à la racine du projet pour créer .lingo/config.json avec vos langues source et cibles ainsi que les motifs de fichiers, puis lingo link pour associer votre organisation et votre moteur. Vous obtiendrez ceci :
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android"
}
]
}Le motif pointe vers votre répertoire de ressources par défaut — le values/ sans qualificateur — exactement là où Android attend les chaînes source. Aucun code de langue n’y figure, et ce n’est pas nécessaire.
Pourquoi `format` est défini explicitement
Le CLI détecte automatiquement la plupart des formats à partir de l’extension du fichier, mais .xml est ambigu. Les fichiers de ressources Android nécessitent donc un "format": "android" explicite dans l’entrée files.
Plusieurs fichiers de ressources
Si votre projet répartit les chaînes dans plusieurs fichiers (par exemple, strings.xml et arrays.xml), ajoutez une entrée files pour chacun :
{
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android"
},
{
"pattern": "app/src/main/res/values/arrays.xml",
"format": "android"
}
]
}Validez .lingo/config.json dans votre dépôt.
Répertoires de langue et qualificateurs#
Android place la langue par défaut dans un répertoire values/ sans qualificateur, donc le chemin source ne comporte aucun code de langue. Le CLI en tient compte : il traite un simple values/ comme la langue source et ajoute le qualificateur cible pour chaque autre langue.
| langue | Répertoire de ressources |
|---|---|
en (source) | values/ |
es | values-es/ |
pt-BR | values-pt-rBR/ |
zh-Hans | values-b+zh+Hans/ |
Les langues régionales et les langues avec script méritent qu’on s’y attarde, car un qualificateur de ressource n’est pas une balise BCP 47 brute. Android accepte deux écritures : l’ancienne forme langue-région (values-pt-rBR/) et une forme BCP 47 préfixée par b+ (values-b+pt+BR/, API 24 et versions ultérieures). Un répertoire nommé values-pt-BR/ est purement et simplement ignoré — les chaînes existeraient, mais ne seraient jamais chargées.
En définissant "format": "android", le CLI génère automatiquement la bonne écriture : l’ancienne forme partout où elle permet d’exprimer la langue, et b+ pour les scripts, les langues à trois lettres et les régions numériques.
Migrer depuis une ancienne configuration
Les anciennes versions du CLI exigeaient que la langue apparaisse dans le chemin source, et ce guide recommandait alors un lien symbolique values-en -> values pour faire le lien entre les deux conventions. À partir de @lingo.dev/cli 1.12.0, ce n’est plus nécessaire — faites pointer le motif vers values/strings.xml et supprimez le lien symbolique.
Traduire en local#
Exécutez le CLI. Lors de la première exécution — ou chaque fois que vous ajoutez une nouvelle langue cible — utilisez --backfill-missing pour traduire toutes les chaînes existantes :
lingo push --backfill-missingLe CLI lit votre fichier source strings.xml, identifie les entrées non traduites à l’aide du run state, traduit le delta via votre moteur de localisation, puis écrit les résultats dans les répertoires cibles values-[locale]/. Ouvrez n’importe quel fichier cible pour voir les chaînes traduites.
Lors des exécutions suivantes, lingo push ne traduit que ce qui a changé :
lingo pushPour limiter une exécution à des fichiers précis, passez un glob. Les motifs sont comparés aux chemins source : ciblez donc le fichier source plutôt qu’un fichier cible.
lingo push "app/src/main/res/values/strings.xml"Pour récupérer dans votre arborescence de travail des traductions produites ailleurs (par exemple en CI), exécutez lingo pull.
Pluriels#
Android utilise des éléments <plurals> avec des chaînes de quantité CLDR (zero, one, two, few, many, other) pour gérer les formes plurielles. Chaque langue a ses propres catégories de pluriel : l’anglais en utilise deux (one et other), le russe en utilise quatre et l’arabe six.
Le CLI préserve la structure <plurals> pendant la traduction et génère les entrées de quantité appropriées pour chaque langue cible. Une entrée source avec deux catégories :
<plurals name="messages_count">
<item quantity="one">%d new message</item>
<item quantity="other">%d new messages</item>
</plurals>Le CLI génère les bonnes catégories pour chaque langue cible. Le moteur de localisation sait quelles règles de pluriel CLDR s’appliquent à chaque langue et ne génère que les catégories requises.
Verrouillage des clés#
Certaines chaînes doivent rester identiques dans toutes les langues : noms de marque, endpoints d’API ou formats. Utilisez le verrouillage des clés pour recopier ces valeurs sans les traduire :
{
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android",
"lockedKeys": ["app_name", "api_base_url"]
}
]
}Les clés verrouillées sont copiées du fichier source vers tous les fichiers cibles, sans passer par le pipeline de traduction.
Automatiser en CI#
La meilleure façon de garder vos traductions à jour est d’utiliser la GitHub App Lingo.dev. Elle s’exécute côté serveur, lit vos fichiers .lingo/config.json et engineId versionnés, puis ouvre automatiquement des mises à jour de traduction — sans runner, sans secret stocké et sans gestion de lockfile de votre côté. Installez-la et connectez-la à votre dépôt pour traduire à chaque push.
Si vous préférez exécuter le CLI dans votre propre pipeline, ajoutez un workflow qui installe le CLI et lance lingo push :
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install -g @lingo.dev/cli
- run: lingo push --backfill-missing
env:
LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}Stockez votre clé API sous LINGO_API_KEY dans Settings > Secrets and variables > Actions de votre dépôt GitHub, puis validez les fichiers cibles mis à jour (ou ouvrez une pull request) à l’étape suivante.
Vérifier avant le déploiement#
Utilisez lingo check comme garde-fou au déploiement pour vous assurer qu’aucune chaîne non traduite ne parte en production. La commande renvoie un statut non nul si certaines entrées doivent encore être traduites :
lingo checkAjoutez cette vérification comme étape CI distincte avant votre build :
- name: Verify translations
run: lingo check
env:
LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}