0024 Internationalization Architecture
- Author:
- Catalyst Engineering Team
- Created:
- 2024-01-15
- Status:
- Accepted
- Tags:
-
Context¶
The Catalyst Voices frontend application must support multiple languages and locales to serve a global user base. We need a solution that:
- Supports multiple languages
- Provides type-safe access to translations
- Enables easy addition of new translations
- Maintains translation quality and consistency
- Works across all Flutter platforms
We evaluated several approaches:
- Hard-coded strings (not scalable)
- JSON-based translation files (no type safety)
- ARB files with code generation (Flutter's recommended approach)
Decision¶
We use ARB (Application Resource Bundle) files with Flutter's flutter_localizations package and code generation.
This provides:
- ARB Files: Translation files in ARB format (JSON-based)
- Code Generation: Automatic generation of type-safe
VoicesLocalizationsclass - Deferred Loading: Translations loaded on-demand for better performance
- Template File:
intl_en.arbserves as the template for all translations
Implementation Details¶
ARB File Structure¶
ARB files are located in packages/internal/catalyst_voices_localization/lib/l10n/:
{
"@@locale": "en",
"loginScreenUsernameLabelText": "Username",
"@loginScreenUsernameLabelText": {
"description": "Text shown in the login screen for the username field"
},
"loginScreenPasswordLabelText": "Password",
"@loginScreenPasswordLabelText": {
"description": "Text shown in the login screen for the password field"
}
}
Configuration¶
l10n.yaml configuration:
arb-dir: lib/l10n
output-dir: lib/generated/
template-arb-file: intl_en.arb
output-localization-file: catalyst_voices_localizations.dart
output-class: VoicesLocalizations
preferred-supported-locales:
- en
use-deferred-loading: true
use-escaping: false
relax-syntax: true
Usage in Code¶
import 'package:catalyst_voices_localization/catalyst_voices_localization.dart';
@override
Widget build(BuildContext context) {
return Text(context.l10n.loginScreenPasswordLabelText);
}
Adding New Translations¶
- Add to template file (
intl_en.arb):
{
"newFeatureTitle": "New Feature",
"@newFeatureTitle": {
"description": "Title for the new feature screen"
}
}
- Generate localizations:
-
Add translations to locale-specific ARB files (e.g.,
intl_es.arb) -
Use in code:
Translation Management¶
The project includes a manage_l10n.dart script for:
- Cleaning: Remove unused translation keys
- Sorting: Sort keys alphabetically
- Checking: Verify files are clean and sorted
dart run manage_l10n.dart --clean
dart run manage_l10n.dart --sort
dart run manage_l10n.dart --check
Supported Locales¶
Locales are configured in:
l10n.yamlfor Flutterios/Runner/Info.plistfor iOS (CFBundleLocalizations)- Android manifest for Android
Alternatives Considered¶
Hard-coded Strings¶
- Pros: Simple, no setup
- Cons: Not scalable, no type safety, difficult to maintain
- Rejected: Not suitable for multi-language support
JSON Translation Files¶
- Pros: Simple format
- Cons: No type safety, manual loading, error-prone
- Rejected: ARB provides better tooling and type safety
Third-party Packages (e.g., easy_localization)¶
- Pros: Additional features
- Cons: External dependency, less standard
- Rejected: Flutter's built-in solution is sufficient and standard
Consequences¶
Positive¶
- Type-safe access to translations
- Automatic code generation
- Standard Flutter approach
- Easy to add new translations
- Deferred loading improves performance
- Tooling support for management
Negative¶
- Code generation step required
- ARB file format learning curve
- Need to regenerate after adding translations
Best Practices¶
- Always add new strings to
intl_en.arbfirst - Include descriptions for all translation keys
- Use descriptive key names
- Run
manage_l10n.dart --checkin CI - Keep translations in sync across locales
- Use deferred loading for better performance