Introducing supa_l10n_manager: A Scalable Flutter Localization Solution
Localization in Flutter can be a challenging task, especially when managing translations across large apps with modularized structures. Developers often use flutter_localizations
(the default approach) or slang_flutter
, but both have trade-offs.
That’s where supa_l10n_manager
comes in. It provides a namespace-based, scalable localization solution with a CLI tool to automate translation management. In this blog, we’ll compare common approaches and explain why supa_l10n_manager
is an excellent alternative.
Why Do We Need a Better Localization Approach?
Localization in Flutter typically involves storing translations, loading them efficiently, and retrieving keys dynamically. However, traditional approaches have limitations:
Approach | Pros ✅ | Cons ❌ |
---|---|---|
flutter_localizations | ✅ Official support ✅ Works well for small apps | ❌ Requires manual .arb file management ❌ Not ideal for large projects |
slang_flutter | ✅ Generates Dart code for translations ✅ Type-safe access to keys | ❌ Requires code generation ❌ Can lead to compile-time issues |
supa_l10n_manager | ✅ Namespace-based JSON structure ✅ CLI automation (merge/extract) ✅ No code generation needed ✅ Works well with large, modular projects | ❌ No compile-time key validation |
Let’s explore each approach and why supa_l10n_manager
is a great alternative.
Option 1: Using flutter_localizations
(Default Approach)
Flutter provides built-in localization support using .arb
files and flutter_localizations
. While this works for basic translations, it quickly becomes hard to manage as your app grows.
Setup:
- Enable localization in
pubspec.yaml
:1 2 3
dependencies: flutter_localizations: sdk: flutter
- Add
.arb
files insidelib/l10n/
:1 2 3
lib/l10n/ app_en.arb app_vi.arb
- Use generated messages in Dart:
1 2 3
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; Text(AppLocalizations.of(context)!.hello);
Pros & Cons
✅ Official Flutter solution
✅ Works well for small projects
❌ Requires manual .arb
file management
❌ No namespace-based organization
❌ Not optimized for modular projects
Option 2: Using slang_flutter
(Code-Generated Approach)
slang_flutter
is a code-generation-based solution that provides type-safe translations.
Setup:
- Add
slang_flutter
topubspec.yaml
:1 2
dependencies: slang_flutter: ^3.19.0
- Create a translation JSON file:
1 2 3
assets/i18n/ en.json vi.json
- Run the code generator:
1
dart run build_runner build
- Use translations with type-safe access:
1
context.t.user.login.username
Pros & Cons
✅ Type-safe translations
✅ IDE autocomplete support
❌ Requires code generation
❌ Slower build times in large projects
Option 3: Using supa_l10n_manager
(Namespace-Based JSON Management)
flutter_localizations
is too rigid, and slang_flutter
requires code generation. What if you need dynamic JSON-based localization without extra build steps?
This is where supa_l10n_manager
excels.
Key Features
✅ Namespace-based JSON storage
✅ Automatic key extraction from Dart code
✅ Merge translations into a single JSON file per locale
✅ Works with Flutter’s LocalizationsDelegate
✅ No build runner or code generation required
How supa_l10n_manager
Works
1. Install the Package
1
2
3
4
dependencies:
supa_l10n_manager:
git:
url: https://github.com/thanhtunguet/supa_l10n_manager.git
Run:
1
flutter pub get
2. Organize Your Translations by Namespace
Instead of a single large JSON file, we use separate namespace files:
1
2
3
4
5
6
7
assets/i18n/
en/
user.json
product.json
vi/
user.json
product.json
Example: assets/i18n/en/user.json
1
2
3
4
{
"login.username": "Username",
"login.password": "Password"
}
This is automatically loaded as a nested structure:
1
2
3
4
5
6
7
8
{
"user": {
"login": {
"username": "Username",
"password": "Password"
}
}
}
3. Load Translations in Your App
Before using translations, load the locale:
1
2
3
4
5
6
7
import 'package:supa_l10n_manager/localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Localization.load('en');
runApp(MyApp());
}
4. Retrieve Translations with translate()
1
2
3
4
import 'package:supa_l10n_manager/translator.dart';
String username = translate('user.login.username');
print(username); // Output: "Username"
Dynamic values:
1
2
print(translate('dashboard.welcome', {'name': 'John'}));
// Output: "Welcome, John!"
5. Use the CLI Tool for Automation
Merge JSON Files
1
dart run bin/cli.dart merge
Combines user.json
and product.json
into a single en.json
.
Extract Missing Keys from Dart Code
1
dart run bin/cli.dart extract --locale en --source lib
Finds all translate('key')
usages and adds missing keys to the JSON files.
Why Choose supa_l10n_manager
?
| Feature | flutter_localizations | slang_flutter | supa_l10n_manager | | ———————————– | ——————— | ————- | —————– | | Namespace-based organization | ❌ No | ❌ No | ✅ Yes | | Auto key extraction | ❌ No | ❌ No | ✅ Yes | | Code generation required | ❌ No | ✅ Yes | ❌ No | | Works with large apps | ❌ Hard to manage | ✅ Scalable | ✅ Modular | | Dynamic translations at runtime | ❌ No | ❌ No | ✅ Yes |
Final Thoughts
Choose flutter_localizations
if…
✔ You’re working on a small app
✔ You don’t need runtime flexibility
Choose slang_flutter
if…
✔ You want type-safe translations
✔ You don’t mind code generation overhead
Choose supa_l10n_manager
if…
✔ You need modular, namespace-based translations
✔ You want automatic key extraction
✔ You want dynamic translations at runtime
🚀 Get Started Today!
flutter_localizations
is great but hard to scale, and slang_flutter
is too restrictive. If you need flexibility, automation, and modularization, then supa_l10n_manager
is the best localization solution for your Flutter app.
🔗 Try it now → GitHub Repository
Happy coding! 🚀