flutterpack_localize 0.0.2
flutterpack_localize: ^0.0.2 copied to clipboard
A powerful and flexible internationalization package for Flutter apps with interpolation, pluralization, and persistence.
π¦ flutterpack_localize #
A simple, powerful, and lazy-loading i18n package for Flutter apps, inspired by Angular's internationalization.
Supports dynamic language switching, nested keys, pluralization, and parameter interpolation.
β¨ Features #
β
Nested JSON keys
β
Pluralization support
β
Interpolation (e.g., {name})
β
Lazy loading from asset files
β
Caching to avoid redundant loads
β
Persistence of the selected locale
β
Per-call control over persistence (changeLocaleWithPreference)
β
Simple tr() helper function
π Getting Started #
1οΈβ£ Install #
Add to your pubspec.yaml:
dependencies:
localize:
git:
url: https://github.com/FlutterPack/localize.git
Or once published to pub.dev:
dependencies:
localize: ^0.0.2
2οΈβ£ Create Translation Files #
Inside your assets/i18n folder, create JSON files:
en.json:
{
"auth": {
"login": "Login"
},
"greeting": "Hello {name}!",
"items": {
"zero": "No items",
"one": "One item",
"other": "{count} items"
}
}
fr.json:
{
"auth": {
"login": "Connexion"
},
"greeting": "Bonjour {name}!",
"items": {
"zero": "Aucun Γ©lΓ©ment",
"one": "Un Γ©lΓ©ment",
"other": "{count} Γ©lΓ©ments"
}
}
3οΈβ£ Configure pubspec.yaml assets #
flutter:
assets:
- assets/i18n/
π οΈ Usage Example #
Initialize #
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterPackLocalizeConfig.init(
const Locale('en'),
persistLanguage: true,
fileLoader: LocalizeFileLoader('assets/i18n'),
);
runApp(MyApp());
}
Provide Delegates and Reactive Locale #
Example 1:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: LocalizeConfig.currentLocale,
builder: (context, locale, _) {
return ValueListenableBuilder(
valueListenable: FlutterPackLocalizeConfig.translationsNotifier,
builder: (context, _, __) {
return MaterialApp(
locale: locale,
supportedLocales: [
Locale('en'),
Locale('fr'),
],
localizationsDelegates: [
LocalizeConfig.delegate(),
],
home: HomePage(),
);
},
);
},
);
}
}
Example 2:
/// main.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:linkist/core/configs/intializer.dart';
import 'package:linkist/core/injections/injections.dart';
import 'package:linkist/core/localize/src/flutterpack_localize_config.dart';
import 'package:linkist/core/localize/src/flutterpack_localize_file_loader.dart';
import 'package:linkist/core/themes/lt_themes.dart';
Future<void> main() async {
// Initialize widget binding
WidgetsFlutterBinding.ensureInitialized();
// Initialize dependencies
await init();
// Initialize Localize (default to English)
await FlutterPackLocalizeConfig.init(
const Locale('dz'),
persistLanguage: true,
fileLoader: FlutterPackLocalizeFileLoader('assets/i18n'),
);
// Set status bar style
if (GetPlatform.isAndroid) LTAppTheme.setStatusBarStyle();
// Run the app
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<Locale>(
valueListenable: FlutterPackLocalizeConfig.currentLocale,
builder: (context, locale, _) {
return MultiBlocProvider(
providers: [...providers()],
child: child(locale),
);
},
);
}
}
/// intializer.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';
import 'package:linkist/core/constants/lt_texts.dart';
import 'package:linkist/core/injections/injections.dart';
import 'package:linkist/core/localize/src/flutterpack_localize_config.dart';
import 'package:linkist/core/routes/routes.dart';
import 'package:linkist/core/themes/lt_themes.dart';
import 'package:linkist/features/authentication/presentation/bloc/authentication_bloc.dart';
List<BlocProvider> providers() {
return [
BlocProvider<AuthenticationBloc>(create: (_) => sl<AuthenticationBloc>()),
];
}
Widget child(Locale locale) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Localization',
enableLog: true,
builder: EasyLoading.init(),
onGenerateRoute: onGenerateRoute,
// β¨ Localization
locale: locale,
supportedLocales: const [Locale('en'), Locale('dz'), Locale('fr')],
localizationsDelegates: [
FlutterPackLocalizeConfig.delegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
);
}
Translating Text #
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(tr(context, 'auth.login')),
Text(tr(context, 'greeting', params: {'name': 'Alice'})),
Text(tr(context, 'items', plural: 3)),
ElevatedButton(
onPressed: () {
LocalizeConfig.changeLocale(const Locale('fr'));
},
child: Text('Switch to French'),
),
],
);
}
}
π Per-Call Persistence Control #
Sometimes you may want user A to persist language selection but user B to not.
Use changeLocaleWithPreference:
// Switch to French and persist this choice
await LocalizeConfig.changeLocaleWithPreference(
const Locale('fr'),
persist: true,
);
// Switch to English only for this session
await LocalizeConfig.changeLocaleWithPreference(
const Locale('en'),
persist: false,
);
π§© API Reference #
LocalizeConfig.init
Initializes localization:
await LocalizeConfig.init(
Locale('en'),
persistLanguage: true,
fileLoader: LocalizeFileLoader('assets/i18n'),
);
-
persistLanguage: true β automatically remembers the userβs last selected language.
-
If persistLanguage is false, it always starts with your defaultLocale.
LocalizeConfig.changeLocale
Switches language (respecting persistLanguage):
await LocalizeConfig.changeLocale(Locale('fr'));
LocalizeConfig.changeLocaleWithPreference
Switches language and specifies whether to persist this change:
await LocalizeConfig.changeLocaleWithPreference(
Locale('fr'),
persist: true,
);
tr()
Helper for translating:
tr(context, 'auth.login')
tr(context, 'greeting', params: {'name': 'Alice'})
tr(context, 'items', plural: 2)
π Comparison With Other Packages #
Hereβs a quick look at how localize compares to popular Flutter i18n solutions:
| Feature | localize | intl | easy_localization | get |
|---|---|---|---|---|
| Format | JSON nested keys | ARB files | JSON / CSV | JSON |
| Code generation required | β None | β Yes | β No | β No |
| Lazy loading | β Yes | β No | β οΈ Partial | β No |
| Caching | β In-memory | β No | β οΈ Limited | β οΈ Limited |
| Pluralization | β Supported | β Supported | β Supported | β οΈ Limited |
| Interpolation | β
{name} syntax |
β
{name} syntax |
β
{name} syntax |
β
{name} syntax |
| Dynamic locale switching | β Yes | β οΈ Manual rebuild | β Yes | β Yes |
| Per-call persistence control | β Yes | β No | β No | β No |
| Dependencies | Minimal | Medium | Medium | Medium |
| Learning curve | Super low | Medium | Medium | Low |
π― When Should You Use localize? #
Choose localize if:
- You want Angular-style simplicity without build steps.
- You need lazy loading and caching to save memory.
- You prefer full control over persistence for each user.
- You like small, clean, auditable codebases.
- You want to ship multilingual apps fast with minimal boilerplate.
β οΈ Known Limitations #
- No right-to-left (RTL) helpers (yet).
- No ICU plural rules (advanced pluralization logic).
- Currently loads from asset bundles (not remote URLs).
If youβd like to contribute or request features, please open an issue or pull request!
π Contributing #
Contributions are welcome!
Feel free to:
- Submit pull requests
- Report bugs
- Suggest improvements
π‘ Example Apps #
We recommend you create a small demo app to see localize in action before integrating into production.
π« Support #
Questions or need help?
Open an issue or contact the maintainer.