Internationalizing Flutter apps is pretty simple and straightforward as documented in the official website. But there is no clear documentation about localizing a Flutter packages and adding support for more language if package does not support them or overriding default translations. However the the process is same with some minor differences.
You may know generating localization creates a LocalizationsDelegate
which we have to use in the MaterialApp
. We need same for our package. We generate the delegate and use it the app.
In the Package
This localization configuration ensures that the generated files are available in the source code inside src
folder and can be exported. l10n.yaml
file will look like this.
arb-dir: lib/src/l10n
output-dir: lib/src/l10n/generated
synthetic-package: false
template-arb-file: intl_en.arb
output-localization-file: awesome_package_localizations.dart
output-class: AwesomePackageLocalization
nullable-getter: false
untranslated-messages-file: lib/src/l10n/untranslated.txt
Now go ahead and edit intl_en.arb
located at lib/src/l10n
. Also add translations for other languages that are supported by the package.
To generate localization files use flutter gen-l10n
. It will also generate localization delegate.
Now export awesome_package_localizations.dart
file which is generated. And that is all you need to add localization support in you Flutter package. Next thing is how to use them in an app.
In the App
We just have to use the delegate generated in the package in the MaterialApp.
return MaterialApp.router(
title: My App',
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
AwesomePackageLocalization.delegate, // this
],
locale: Locale(LocaleService.instance.appLanguage.languageCode),
supportedLocales: const [
Locale('en'),
Locale('fr'),
],
);
If the package does not support the locales that the app has listed as supported then it will show a warning and eventually throw an error on runtime.
So what if the package you use doesn’t support locale you need in your app?
Overriding Localization or Adding Support for New Language
Sometimes a package you are using may not provide localization for the language you needed in you app or the translations should be changed. Let’s assume awesome package does not support French and you need to add support for it without updating the package.
I would like to describe it in 3 steps as follow.
Translation
Create a localization for French language by extending AwesomePackageLocalization
(generated in the package).
class AwesomePackageLocalizationFr extends AwesomePackageLocalization {
AwesomePackageLocalizationFr(super.locale);
@override
String get hi => 'Salut';
@override
String get thankYou => 'Merci';
}
Delegate
Now create a delegate to load AwesomePackageLocalizationFr
.
import 'package:intl/intl.dart' as intl;
class AwesomePackageLocalizationFrDelegate
extends LocalizationsDelegate<AwesomePackageLocalization> {
const AwesomePackageLocalizationFrDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'fr';
@override
Future<AwesomePackageLocalization> load(Locale locale) {
final languageCode = intl.Intl.canonicalizedLocale(locale.toString());
return SynchronousFuture<AwesomePackageLocalization>(
AwesomePackageLocalizationFr(languageCode),
);
}
@override
bool shouldReload(LocalizationsDelegate<AwesomePackageLocalization> old) => true;
}
Usage
To use it you can add delegate in the MaterialApp and now your app runs fine with French language even though the package did not support French originally.
return MaterialApp.router(
title: My App',
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
// to be able to override default value from AwesomePackageLocalization
// this delegate must be before it because only the first delegate of each
// [LocalizationsDelegate.type] is used.
AwesomePackageLocalizationNeDelegate(),
AwesomePackageLocalization.delegate,
],
locale: Locale(LocaleService.instance.appLanguage.languageCode),
supportedLocales: const [
Locale('en'),
Locale('fr'),
],
);
That was all for adding a new language or overriding the default one. You need to make sure if you want to override a language the delegate must be before the default one.
Thanks for reading.