
Le guide complet de la localisation Flutter
Des fichiers ARB à la prise en charge du RTL : localisez votre application Flutter avec easy_localization, gérez les pluriels pour chaque langue et automatisez les traductions avec l'IA.
Installer easy_localization
Ajoutez le package easy_localization à votre pubspec.yaml. Il s'agit du package i18n le plus populaire pour Flutter, avec prise en charge des fichiers ARB/JSON, des pluriels et des extensions de contexte. Ajoutez également flutter_localizations depuis le SDK pour un formatage des dates, des nombres et du sens du texte tenant compte de la locale.
dependencies:
easy_localization: ^3.0.7
flutter_localizations:
sdk: flutterCréer des fichiers de traduction ARB
Les fichiers Application Resource Bundle (ARB) constituent le format de localisation standard pour Flutter. Chaque fichier contient des paires clé-valeur avec des métadonnées facultatives décrivant les espaces réservés, les règles de pluriel et le contexte destiné aux traducteurs. Créez un fichier par locale dans votre répertoire assets/translations.
{
"@@locale": "en",
"appTitle": "My App",
"@appTitle": {
"description": "The title of the application"
},
"greeting": "Hello, {name}!",
"@greeting": {
"description": "Greeting with user name",
"placeholders": {
"name": {
"type": "String",
"example": "Alice"
}
}
},
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemCount": {
"description": "Number of items in the cart",
"placeholders": {
"count": {
"type": "num",
"format": "compact"
}
}
}
}Configurer l'application
Enveloppez votre application avec le widget EasyLocalization. Il gère l'état de la locale, charge les traductions depuis vos fichiers d'assets et fournit les délégués de locale dont MaterialApp a besoin. Les trois propriétés de délégué requises sont localizationsDelegates, supportedLocales et locale — toutes disponibles via des extensions de contexte.
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(
EasyLocalization(
supportedLocales: [
Locale('en'),
Locale('ar'),
Locale('ja'),
Locale('de'),
],
path: 'assets/translations', // Path to your ARB/JSON files
fallbackLocale: Locale('en'),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: HomePage(),
);
}
}Traduire les widgets
Utilisez la méthode d'extension .tr() sur les clés de chaîne pour obtenir le texte traduit dans n'importe quel widget. Pour les pluriels, utilisez .plural() avec la valeur du compteur. easy_localization propose à la fois la syntaxe d'extension de chaîne ('key'.tr()) et la syntaxe de méthode de contexte (context.tr('key')).
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('appTitle'.tr()), // Simple key
),
body: Column(
children: [
// String with variable interpolation
Text('greeting'.tr(args: ['Alice'])),
// Named arguments
Text('greeting'.tr(namedArgs: {'name': 'Alice'})),
// Plural form
Text('itemCount'.plural(3)),
],
),
);
}
}Gérer les pluriels et les variables
Flutter utilise ICU MessageFormat pour les pluriels — le même standard qu'iOS, Android et le web. Définissez les formes plurielles à l'aide de la syntaxe {count, plural, ...} dans vos fichiers ARB. Chaque langue nécessite son propre jeu de formes, basé sur les règles de pluriel CLDR. L'arabe compte 6 formes, le russe 4, le japonais 1.
// English: 3 useful forms (=0, =1, other)
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}"
// Arabic: 6 forms (=0, =1, =2, few, many, other)
"itemCount": "{count, plural, =0{لا عناصر} =1{عنصر واحد} =2{عنصران} few{{count} عناصر} many{{count} عنصرًا} other{{count} عنصر}}"
// Japanese: 1 form (other)
"itemCount": "{count, plural, other{{count}個のアイテム}}"
// German: 2 forms (=1, other)
"itemCount": "{count, plural, =1{1 Artikel} other{{count} Artikel}}"
// Russian: 3 forms (one, few, many)
"itemCount": "{count, plural, =0{Нет товаров} one{{count} товар} few{{count} товара} many{{count} товаров} other{{count} товаров}}"// Simple variable
"welcome": "Welcome, {name}!"
// Multiple variables
"orderStatus": "Order #{orderId} — {status}"
// Variable in plural context
"unreadMessages": "{count, plural, =0{No unread messages} =1{1 unread message from {sender}} other{{count} unread messages}}"
// In widgets:
Text('welcome'.tr(namedArgs: {'name': userName}));
Text('orderStatus'.tr(namedArgs: {'orderId': '1234', 'status': 'Shipped'}));
Text('unreadMessages'.plural(count, namedArgs: {'sender': senderName}));Prendre en charge les langues RTL
Flutter met automatiquement en miroir l'intégralité de la mise en page lorsque la locale est une langue s'écrivant de droite à gauche (arabe, hébreu, persan, ourdou). Mais votre code doit utiliser des widgets et des propriétés tenant compte du sens d'écriture pour que la mise en miroir fonctionne correctement. Remplacez les valeurs gauche/droite codées en dur par leurs équivalents start/end.
import 'package:flutter/material.dart';
class AdaptiveLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isRtl = Directionality.of(context) == TextDirection.rtl;
return Scaffold(
body: Row(
children: [
// Use start/end instead of left/right
Expanded(
child: Padding(
padding: EdgeInsetsDirectional.only(
start: 16.0, // Leading edge (left in LTR, right in RTL)
end: 8.0, // Trailing edge
),
child: Text('content'.tr()),
),
),
// Flip icons for RTL
Icon(
isRtl ? Icons.arrow_back : Icons.arrow_forward,
),
],
),
);
}
}// Use Directional widgets for RTL-aware layouts
EdgeInsetsDirectional.only(start: 16, end: 8) // Not EdgeInsets.only(left: 16, right: 8)
AlignmentDirectional.centerStart // Not Alignment.centerLeft
BorderRadiusDirectional.only(topStart: Radius.circular(8))
// Automatically mirrors when locale changes to Arabic, Hebrew, etc.
// No conditional logic needed — Flutter handles text direction from localeChaînes de repli de locale intelligentes
Par défaut, lorsqu'une traduction pt-BR est manquante, Flutter revient directement à l'anglais — en ignorant des traductions pt-PT parfaitement valables. Le package locale_chain corrige ce problème grâce à des chaînes de repli configurables. Une seule ligne de configuration, aucune migration — vos appels .tr() existants fonctionnent tels quels.
import 'package:locale_chain/locale_chain.dart';
import 'package:locale_chain/easy_localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
LocaleChain.configure(); // Enable smart fallback chains
runApp(
EasyLocalization(
supportedLocales: [
Locale('en'),
Locale('pt', 'BR'),
Locale('pt', 'PT'),
Locale('es'),
Locale('es', 'MX'),
],
path: 'assets/translations',
assetLoader: LocaleChainAssetLoader( // Swap in the chain loader
baseLoader: RootBundleAssetLoader(),
),
fallbackLocale: Locale('en'),
child: MyApp(),
),
);
}
// Result: pt-BR user sees pt-PT translations when pt-BR keys are missing,
// instead of falling back directly to English.// Override specific chains while keeping built-in defaults
LocaleChain.configure(
fallbacks: {
'pt-BR': ['pt-PT', 'pt'], // pt-BR → pt-PT → pt → en
'es-MX': ['es-419', 'es'], // es-MX → es-419 → es → en
'fr-CA': ['fr'], // fr-CA → fr → en
},
);
// Or replace all defaults with your own chains
LocaleChain.configure(
fallbacks: {
'zh-Hant-HK': ['zh-Hant-TW', 'zh-Hans'],
'pt-BR': ['pt-PT', 'pt'],
},
mergeDefaults: false, // Only your chains, no built-in defaults
);Automatiser les traductions
Une fois votre configuration de localisation terminée, traduisez vos fichiers ARB à l'aide de l'IA. Dans votre IDE, demandez à votre assistant IA de traduire votre fichier ARB source, ou utilisez la CLI i18n Agent dans votre pipeline CI/CD. Les métadonnées ARB (espaces réservés, descriptions) fournissent un contexte qui améliore la qualité de la traduction.
# In your IDE, ask your AI assistant:
> Translate assets/translations/en.arb to Arabic, Japanese, and German
✓ ar.arb created (1.4s)
✓ ja.arb created (1.2s)
✓ de.arb created (1.1s)
# Or use the CLI in CI/CD:
npx i18n-agent translate assets/translations/en.arb --lang ar,ja,deAutomatiser la qualité des traductions
Pièges courants
Fichiers de traduction introuvables à l'exécution
Syntaxe de fichier ARB non valide
Les modifications de traduction n'apparaissent pas lors du hot reload
Valeurs gauche/droite codées en dur cassant le RTL
Structure de fichiers recommandée
my_flutter_app/
├── assets/
│ └── translations/
│ ├── en.arb # Source language (English)
│ ├── ar.arb # Arabic (with 6 plural forms)
│ ├── de.arb # German
│ ├── ja.arb # Japanese
│ ├── pt-BR.arb # Brazilian Portuguese
│ └── pt-PT.arb # European Portuguese
├── lib/
│ ├── main.dart # App entry with EasyLocalization
│ ├── app.dart # MaterialApp with locale delegates
│ └── widgets/
│ └── language_switcher.dart
├── pubspec.yaml # Dependencies
└── analysis_options.yamlEssayez i18n Agent maintenant
Déposez votre fichier de traduction ici
JSON, YAML, PO, XML, CSV, Markdown, Properties
ou cliquez pour parcourir
Langues cibles
Repli de locale avec locale_chain
Lorsqu'une clé de traduction est absente dans une locale régionale comme pt-BR, Flutter passe directement à la langue modèle au lieu de vérifier d'abord la locale parente pt.
flutter pub add locale_chainimport 'package:locale_chain/locale_chain.dart';
LocaleChain.configure(fallbacks: {
'pt-BR': ['pt', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
});
LocaleChainAssetLoader(baseLoader: RootBundleAssetLoader());Consultez notre guide de repli de locale pour découvrir la liste complète des frameworks pris en charge et les 75 chaînes intégrées. Learn more →