
De complete handleiding voor Flutter-lokalisatie
Van ARB-bestanden tot RTL-ondersteuning: lokaliseer je Flutter-app met easy_localization, verwerk meervoudsvormen voor elke taal en automatiseer vertalingen met AI.
easy_localization installeren
Voeg het pakket easy_localization aan je pubspec.yaml toe. Dit is het populairste i18n-pakket voor Flutter en ondersteunt ARB-/JSON-bestanden, meervoudsvormen en contextextensies. Voeg ook flutter_localizations uit de SDK toe voor localegevoelige opmaak van datums en getallen en voor de juiste tekstrichting.
dependencies:
easy_localization: ^3.0.7
flutter_localizations:
sdk: flutterARB-vertaalbestanden maken
Application Resource Bundle-bestanden (ARB) zijn de standaardindeling voor Flutter-lokalisatie. Elk bestand bevat sleutel-waardeparen met optionele metadata over placeholders, meervoudsregels en context voor vertalers. Maak per locale één bestand in de map 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"
}
}
}
}De app configureren
Plaats de EasyLocalization-widget rond je app. Deze beheert de localestatus, laadt vertalingen uit je assetbestanden en levert de localedelegates die MaterialApp nodig heeft. De drie vereiste delegate-eigenschappen zijn localizationsDelegates, supportedLocales en locale. Ze zijn allemaal via contextextensies beschikbaar.
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(),
);
}
}Widgets vertalen
Gebruik de extensiemethode .tr() op tekstsleutels om in elke widget vertaalde tekst op te halen. Gebruik voor meervouden .plural() met het aantal. easy_localization biedt zowel de syntaxis van een tekstextensie ('key'.tr()) als die van een contextmethode (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)),
],
),
);
}
}Meervouden en variabelen verwerken
Flutter gebruikt ICU MessageFormat voor meervouden, dezelfde standaard als iOS, Android en het web. Definieer in je ARB-bestanden meervoudsvormen met de syntaxis {count, plural, ...}. Elke taal heeft op basis van de CLDR-meervoudsregels eigen vormen nodig. Arabisch heeft 6 vormen, Russisch 4 en Japans 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}));RTL-talen ondersteunen
Flutter spiegelt de volledige lay-out automatisch wanneer de locale een taal van rechts naar links gebruikt, zoals Arabisch, Hebreeuws, Perzisch of Urdu. Je code moet wel richtingsbewuste widgets en eigenschappen gebruiken om correct te kunnen spiegelen. Vervang hardgecodeerde links/rechts-waarden door de equivalenten 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 localeSlimme locale-fallbackketens
Wanneer een pt-BR-vertaling ontbreekt, valt Flutter standaard direct terug op Engels en worden prima pt-PT-vertalingen overgeslagen. Het pakket locale_chain lost dit op met configureerbare fallbackketens. Eén configuratieregel, geen migratie: je bestaande .tr()-aanroepen blijven gewoon werken.
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
);Vertalingen automatiseren
Wanneer je lokalisatieconfiguratie gereed is, vertaal je ARB-bestanden met AI. Vraag je AI-assistent in je ontwikkelomgeving om het ARB-bronbestand te vertalen of gebruik de CLI van i18n Agent in je CI/CD-pipeline. ARB-metadata, zoals placeholders en beschrijvingen, biedt context die de vertaalkwaliteit verbetert.
# 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,deVertaalkwaliteit automatisch bewaken
Veelvoorkomende valkuilen
Vertaalbestanden niet gevonden tijdens runtime
Ongeldige syntaxis in ARB-bestand
Vertaalwijzigingen verschijnen niet na hot reload
Hardgecodeerd links/rechts verstoort RTL
Aanbevolen bestandsstructuur
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.yamlProbeer i18n Agent nu
Zet je vertaalbestand hier neer
JSON, YAML, PO, XML, CSV, Markdown, Properties
of klik om een bestand te selecteren
Doeltalen
Locale-fallback met locale_chain
Wanneer een vertaalsleutel ontbreekt in een regionale locale zoals pt-BR, springt Flutter direct naar de sjabloontaal in plaats van eerst de bovenliggende locale pt te controleren.
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());Bekijk onze handleiding voor locale-fallback voor de volledige lijst met ondersteunde frameworks en 75 ingebouwde ketens. Learn more →