Create one JSON file per language inside your assets folder. The default path is assets/translations/. Files must be named after the language code (e.g. en.json, pt.json).
Note: If your translations span multiple files per locale, list every file individually or use a directory entry (e.g. assets/translations/en/). The path must match exactly what you pass to translationsPath.
2. MaterialApp configuration
import'package:flutter_localizations/flutter_localizations.dart';
import'package:internationalization/internationalization.dart';
const _supportedLocales = [
Locale('en'),
Locale('pt'),
Locale('es'),
];
MaterialApp(
supportedLocales: _supportedLocales,
localizationsDelegates: [
InternationalizationDelegate(
suportedLocales: _supportedLocales,
// Default path is 'assets/translations/' — only override if needed.
translationsPath: 'assets/translations/',
// Optional: merge translations fetched at runtime (API, remote config, etc.)
addTranslations: (locale) async {
return {
'remote_key': 'Value from the network for ${locale.languageCode}',
};
},
),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
);
InternationalizationDelegate parameters
Parameter
Type
Required
Default
Description
suportedLocales
List<Locale>
✅
—
Locales the app supports
translationsPath
String
'assets/translations/'
Path to the JSON files directory
addTranslations
Future<Map<String, dynamic>> Function(Locale)?
null
Callback to inject extra translations at load time
JSON structure
Translations are plain JSON objects. Keys can be flat or deeply nested:
TextIntl accepts all the same parameters as Text (style, textAlign, overflow, maxLines, etc.) plus the translation parameters parent, args, namedArgs, and pluralValue.
Interpolation
Positional arguments — {0}, {1}, …
JSON:
{"welcome_message":"Hello, {0}! You have {1} new messages."}
Dart:
context.translate(
'welcome_message',
args: ['Alice', '5'],
);
// → "Hello, Alice! You have 5 new messages."
{"order_ready":"Dear ::name::, your order #{0} is ready."}
Dart:
context.translate(
'order_ready',
args: ['42'],
namedArgs: {'name': 'Maria'},
);
// → "Dear Maria, your order #42 is ready."
Plurals
Define a zero, one, and other form for any key:
JSON:
{"cart":{"items":{"zero":"Your cart is empty.","one":"You have {0} item in your cart.","other":"You have {0} items in your cart."}}}
Dart:
// zero
context.translate('items', parent: ['cart'], pluralValue: 0, args: ['0']);
// → "Your cart is empty."// one
context.translate('items', parent: ['cart'], pluralValue: 1, args: ['1']);
// → "You have 1 item in your cart."// other
context.translate('items', parent: ['cart'], pluralValue: 42, args: ['42']);
// → "You have 42 items in your cart."
Plural forms can also be combined with named args:
Injected keys follow the same JSON structure and can be accessed with context.translate, the String extension, or TextIntl exactly like local keys.
Example
A full showcase example demonstrating every feature is available in the example/ directory. It covers simple strings, nested keys, interpolation, plurals, runtime injection, and NumberFormat/DateFormat — with a live language switcher between English, Portuguese, and Spanish.
cd example
flutter run
API reference
Translator
Method
Description
Translator.of(context)
Returns the Translator instance for the current locale