i18n_multilanguage_with_flags
Generic Flutter i18n toolkit with:
- language metadata + flags
- lightweight translation lookup (
tr(key)) - optional persistence for language preferences
This package is app-agnostic. It does not enforce any domain keys, business logic, or architecture.
Install
dependencies:
i18n_multilanguage_with_flags: ^0.2.0
flutter pub get
Recommended File Structure
Use one file per language plus one aggregator file.
lib/
i18n/
translation_keys.dart
translations/
en_us.dart
pt_br.dart
all_translations.dart
1) Define translation keys
lib/i18n/translation_keys.dart
class TranslationKeys {
const TranslationKeys._();
static const appTitle = 'app.title';
static const save = 'actions.save';
}
2) Create one file per language
lib/i18n/translations/en_us.dart
import 'package:i18n_multilanguage_with_flags/i18n_multilanguage_with_flags.dart';
import '../translation_keys.dart';
const TranslationEntry enUsTranslations = TranslationEntry(
languageId: 'en_us',
values: {
TranslationKeys.appTitle: 'My App',
TranslationKeys.save: 'Save',
},
);
lib/i18n/translations/pt_br.dart
import 'package:i18n_multilanguage_with_flags/i18n_multilanguage_with_flags.dart';
import '../translation_keys.dart';
const TranslationEntry ptBrTranslations = TranslationEntry(
languageId: 'pt_br',
values: {
TranslationKeys.appTitle: 'Meu App',
TranslationKeys.save: 'Salvar',
},
);
3) Aggregate all translation files
lib/i18n/translations/all_translations.dart
import 'package:i18n_multilanguage_with_flags/i18n_multilanguage_with_flags.dart';
import 'en_us.dart';
import 'pt_br.dart';
final appTranslations = buildTranslationCatalog(
entries: const [
enUsTranslations,
ptBrTranslations,
],
);
4) Initialize controller
final controller = I18nMultilanguageController(
languages: buildConfigurableLanguageCatalog(
includeIds: const ['en_us', 'pt_br'],
),
initialUiLanguageId: 'en_us',
initialSecondaryLanguageId: 'pt_br',
translations: appTranslations,
);
5) Render text
Text(controller.tr(TranslationKeys.appTitle));
6) Add language selector UI
Simple selector:
LanguageFlagDropdown(
languages: controller.languages,
value: controller.uiLanguageId,
onChanged: (languageId) {
if (languageId == null) return;
controller.setUiLanguage(languageId);
},
)
Generic preferences form:
I18nPreferencesForm(
languages: controller.languages,
initialUiLanguageId: controller.uiLanguageId,
initialSecondaryLanguageId: controller.secondaryLanguageId,
initialDisplayName: controller.displayName,
showDisplayNameField: true,
requireSecondaryLanguage: true,
onSubmit: controller.applySnapshot,
)
7) Persist preferences (optional)
final storage = LanguageSelectionStorage();
await controller.loadFromStorage(storage);
await controller.saveToStorage(storage);
Default keys (generic):
i18n.ui_language_idi18n.secondary_language_idi18n.display_name
Legacy keys are still read automatically:
languagetarget_languageusernamelanguage_to_learn(legacy vector)
To also write legacy keys:
final storage = LanguageSelectionStorage(
writeLegacyAliasKeys: true,
);
Custom keys:
final storage = LanguageSelectionStorage(
keys: const I18nStorageKeys(
uiLanguageKey: 'myapp.ui_language',
secondaryLanguageKey: 'myapp.secondary_language',
displayNameKey: 'myapp.display_name',
),
);
API Overview
Main classes:
I18nMultilanguageControllerLanguageMetadataLanguageSelectionSnapshotLanguageSelectionStorageI18nStorageKeysTranslationEntryI18nPreferencesFormLanguageFlagDropdownFlagIcon
Catalog helpers:
defaultLanguageCatalogbuildDefaultLanguageCatalogMap()buildConfigurableLanguageCatalog(...)
Translation helpers:
buildTranslationCatalog(...)cloneTranslationCatalog(...)mergeTranslationCatalogs(...)
Backward Compatibility
Legacy naming is still supported (deprecated aliases):
targetLanguageId->secondaryLanguageIdusername->displayNamesetTargetLanguage(...)->setSecondaryLanguage(...)setUsername(...)->setDisplayName(...)I18nLanguageSelectionForm->I18nPreferencesForm
Example
A runnable app is available in example/.
cd example
flutter pub get
flutter run
Libraries
- i18n_multilanguage_with_flags
- Generic Flutter i18n toolkit with language metadata, flag widgets, and selection persistence helpers.