| name | anas-localization |
| description | Flutter localization with the `anas_localization` package — setup with AnasLocalization widget, code generation via CLI tooling, type-safe Dictionary access, locale switching with persistence, RTL support, pluralization, and number/date formatting. Use when asked to add localization to a Flutter app using the anas_localization package, set up multi-language support, generate Dictionary classes, or validate locale files. |
| compatibility | opencode |
| license | MIT |
Anas Localization
Overview
anas_localization is a Flutter/Dart localization package with runtime locale switching, code generation for type-safe translation access, RTL support, pluralization, and enhanced formatting.
Package: anas_localization · Version: ≥ 0.1.6
Dart: ≥ 3.3.0 · Flutter: ≥ 3.19.0
When to Use This Skill
- Add multi-language support to a Flutter app.
- Set up code-generated type-safe Dictionary classes.
- Implement runtime locale switching with persistence.
- Format dates, numbers, currency, and relative times per locale.
- Support RTL languages and bidirectional text.
- Validate locale JSON/YAML/ARB files and plural rules.
Quick Start
1. Add dependency
dependencies:
anas_localization: ^0.1.6
2. Wrap your app
import 'package:anas_localization/anas_localization.dart';
void main() {
runApp(
const AnasLocalization(
app: MyApp(),
fallbackLocale: Locale('en'),
assetPath: 'assets/lang',
assetLocales: [Locale('en'), Locale('ar'), Locale('tr')],
),
);
}
3. Add locale asset files
Place JSON/YAML/ARB files at assets/lang/en.json, assets/lang/ar.json, etc., and register them in pubspec.yaml:
flutter:
assets:
- assets/lang/
4. Access translations
// Via BuildContext extension
context.dict.welcomeMessage
// Via global shorthand
t.appName
// Via AnasLocalization static
AnasLocalization.dictionary.getString('welcome_message')
5. (Optional) Generate Dictionary class
dart run anas_localization:cli generate
This creates a dictionary.dart file with type-safe getters matching your translation keys.
Core API Reference
AnasLocalization Widget
| Parameter | Type | Default | Description |
|---|
app | Widget | required | The root app widget |
fallbackLocale | Locale | Locale('en') | Fallback when a key is missing |
assetPath | String | 'assets/lang' | Asset folder for locale files |
assetLocales | List<Locale> | [Locale('en')] | Supported locales |
animationSetup | bool | true | Show animated setup overlay |
previewDictionaries | Map | null | In-memory dictionaries for previews/tests |
dictionaryFactory | Function | null | Factory for generated Dictionary class |
Accessing Translations
// From any widget (requires AnasLocalization ancestor)
final dict = AnasLocalization.of(context).dictionary;
final locale = AnasLocalization.of(context).locale;
// Extension methods (import anas_localization.dart)
context.dict // Dictionary instance
context.locale // Current Locale
context.supportedLocales // List<Locale>
// Global shorthand
t.appName // Top-level getter
Dictionary Methods
dict.getString('key') // Simple string
dict.getStringWithParams('welcome', {'name': 'Alice'}) // With params
dict.hasKey('key') // Existence check
dict.getPluralData('items') // Plural data access
Locale Switching
// Change locale at runtime
await AnasLocalization.of(context).setLocale(Locale('ar'));
// Locale is persisted via SharedPreferences automatically
// No need for manual save/load
RTL Support
// Wrap directional content
AnasDirectionalityWrapper(
child: Text(context.dict.message),
)
// Check direction
context.isRTL
Formatting
final fmt = AnasNumberFormatter(context.locale);
fmt.formatCurrency(1234.56, currencyCode: 'USD')
fmt.formatPercentage(0.85)
fmt.formatCompact(1234567)
fmt.formatFileSize(2048)
final dtf = AnasDateTimeFormatter(context.locale);
dtf.formatDate(DateTime.now())
dtf.formatTime(DateTime.now())
dtf.formatDateTime(DateTime.now())
dtf.formatRelativeTime(DateTime.now().subtract(Duration(hours: 2)))
Pluralization
// In translation JSON:
{ "items": { "one": "1 item", "other": "{count} items" } }
// Generated usage:
dict.itemsCount(count: 5) // "5 items"
// Manual:
dict.getStringWithParams('items', {'count': '5'})
Custom Locale Storage
// Save/load/clear locale preference manually
await AnasLocalizationStorage.saveLocale('en');
String? locale = await AnasLocalizationStorage.loadLocale();
await AnasLocalizationStorage.clearLocale();
// Inject custom storage
AnasLocalizationStorage.storageFactory = () async => MyCustomStorage();
Pre-built UI Widgets
// Language selection dialog
AnasLanguageDialog(
supportedLocales: context.supportedLocales,
)
// Inline language selector
AnasLanguageSelector(
supportedLocales: context.supportedLocales,
)
// Quick toggle between two locales
AnasLanguageToggle(
primaryLocale: Locale('en'),
secondaryLocale: Locale('ar'),
)
CLI Tooling
dart run anas_localization:cli generate
dart run anas_localization:cli validate
dart run anas_localization:cli export --format csv
dart run anas_localization:cli import --format csv translations.csv
Architecture
AnasLocalization (StatefulWidget)
└─ AnasLocalizationScope (InheritedWidget)
├─ Locale management
├─ Dictionary loading via LocalizationService
├─ Persistence via AnasLocalizationStorage
└─ Generated Dictionary class (type-safe getters)
Translation resolution order:
- Preview dictionaries (in-memory, for tests/previews)
- App assets (
assets/lang/<locale>.*)
- Package assets (
packages/anas_localization/assets/lang/<locale>.*)
- Remote localization cache (if configured)
- Fallback chain: exact → language-only → project fallback
Additional Resources