supa_l10n_manager
A Flutter localization package with a CLI tool to manage and load translations efficiently.
Features
✅ Namespace-Based Key Organization - Keeps translation files modular
✅ Automatic Translation Key Extraction - Finds missing keys in your Dart code
✅ CLI Tool for JSON Merging, Key Extraction & Reordering - Simplifies localization management
✅ Async & Cached Translation Loading - Ensures performance
✅ Fallback Locale Support - Prevents missing translation issues
Installation
Add the package to your pubspec.yaml
:
dependencies:
supa_l10n_manager:
git:
url: https://github.com/thanhtunguet/supa_l10n_manager.git
Then run:
flutter pub get
File Structure
Translations are stored in namespace-based JSON files inside assets/i18n/<locale>/
.
assets/i18n/
en/
user.json
product.json
vi/
user.json
product.json
Each file contains a flat JSON structure:
assets/i18n/en/user.json
{
"login.username": "Username",
"login.password": "Password"
}
Automatically converted into this nested map:
{
"user": {
"login": {
"username": "Username",
"password": "Password"
}
}
}
Usage in a Flutter App
1. Load Localization Data
Before using translations, load the desired locale:
import 'package:supa_l10n_manager/localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Localization.load('en');
runApp(MyApp());
}
2. Retrieve Translations
Use the translate
function in your app:
import 'package:supa_l10n_manager/translator.dart';
String usernameLabel = translate('user.login.username');
print(usernameLabel); // Output: "Username"
You can also use dynamic values:
print(translate('dashboard.welcome', {'name': 'John'}));
// Output: "Welcome, John!"
Flutter Integration
To integrate with Flutter’s localization system, use the provided delegate:
import 'package:flutter/material.dart';
import 'package:supa_l10n_manager/localization_delegate.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: const [
AppLocalizationsDelegate(fallbackLocale: 'en'),
],
supportedLocales: const [
Locale('en'),
Locale('vi'),
],
home: Scaffold(
appBar: AppBar(title: const Text('Localization Example')),
body: Center(
child: Text(translate('user.login.username')),
),
),
);
}
}
CLI Tool
The package provides a CLI tool to merge JSON files, extract missing keys, and reorder translation keys.
1. Merge JSON Files
Merges all namespace.json
files into a single file per locale:
dart run bin/supa_l10n_manager.dart merge
After merging:
assets/i18n/
en.json // Merged file
vi.json // Merged file
2. Extract Missing Keys
Scans Dart code for translate('key')
usages and updates namespace files.
dart run bin/supa_l10n_manager.dart extract --locale en --source lib
If the following keys are found in Dart code:
translate('user.login.username');
translate('user.login.password');
Then assets/i18n/en/user.json
is created/updated:
{
"login.username": "Username",
"login.password": "Password"
}
- If
user.json
does not exist, it is automatically created. - If a key is missing, it is added with an empty string.
3. Reorder Translation Keys
Alphabetically sorts all keys in translation files for better organization and easier version control:
dart run bin/supa_l10n_manager.dart reorder
This command:
- Works on both merged locale files (e.g.,
en.json
) and individual namespace files - Processes all JSON files in the
assets/i18n
directory tree - Keeps translation files organized with consistent key ordering
- Makes comparing and merging translations easier
Before reordering:
{
"login.password": "Password",
"profile.email": "Email",
"login.username": "Username"
}
After reordering:
{
"login.password": "Password",
"login.username": "Username",
"profile.email": "Email"
}
Example JSON Files After Extraction
assets/i18n/en/user.json
(Updated)
{
"login.username": "Username",
"login.password": "Password",
"profile.email": ""
}
The missing key "profile.email"
was automatically added.
Performance Considerations
✅ Loads only necessary locale JSON files at runtime
✅ Caches translations for efficient lookups
✅ Uses async file loading for better performance
Contributing
- Fork the repository
- Make changes
- Submit a pull request
License
MIT License. Free to use and modify. 🚀