smart_localization 0.0.1
smart_localization: ^0.0.1 copied to clipboard
A backend-agnostic smart localization system for Flutter. Version-controlled translations with intelligent caching, fallback chains, and parameterized translations.
Smart Localization #
A backend-agnostic smart localization system for Flutter. It provides version-controlled translations with intelligent caching, automatic fallback chains, parameterized translations, and device language detection.
Features #
- Backend-Agnostic: Plug in Firestore, REST API, Supabase, or any other data source.
- Version-Controlled Translations: Download translations only when they change.
- Intelligent Caching: SharedPreferences-based caching with version tracking.
- Fallback Chain: Gracefully degrades from Current Language to Default Language to Provided Text.
- Parameterized Translations: Support for dynamic values (e.g.,
Hello {name}). - Device Language Detection: Automatically detects device language, including Chinese variants.
- Flexible Lookups: Supports both ID-based and key-based translation identification.
- Sync & Async APIs: Provides
context.localization()andcontext.localizationAsync(). - Built-In Backend: Includes
MapTranslationBackendfor simple setups and testing.
Installation #
Add the following to your pubspec.yaml:
dependencies:
smart_localization: ^0.0.1
Quick Start #
1. Initialization #
Initialize the service before running your app.
import 'package:smart_localization/smart_localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SmartLocalization.initialize(
backend: MapTranslationBackend(
translations: {
'en': {'home.title': 'My App', 'home.greeting': 'Hello {name}!'},
'tr': {'home.title': 'Uygulamam', 'home.greeting': 'Merhaba {name}!'},
},
),
);
runApp(MyApp());
}
2. Usage in Widgets #
Use the provided BuildContext extensions to access translations seamlessly.
// Simple translation
Text(context.localization('My App', id: 'home.title'))
// With parameters
Text(context.localization(
'Hello {name}!',
id: 'home.greeting',
params: {'name': userName},
))
// Async translation (waits for full fallback chain if necessary)
Text(await context.localizationAsync('My App', id: 'home.title'))
3. Switching Language #
await SmartLocalization.instance.setLanguage('tr');
setState(() {}); // Rebuild your widgets to reflect the new language
Custom Backend Integration #
Implement the TranslationBackend interface to connect your preferred data source.
Example: Firestore Backend #
class FirestoreBackend implements TranslationBackend {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
@override
Future<TranslationData?> fetchTranslations(String languageCode) async {
final doc = await _firestore.collection('translations').doc(languageCode).get();
if (!doc.exists) return null;
final data = doc.data()!;
return TranslationData(
translations: Map<String, String>.from(data['translations']),
version: data['version'],
isActive: data['isActive'] ?? true,
);
}
@override
Future<int> getRemoteVersion() async {
final doc = await _firestore.collection('translation_metadata').doc('version').get();
return doc.data()?['currentVersion'] ?? 0;
}
@override
Future<List<String>> getSupportedLanguages() async {
final doc = await _firestore.collection('translation_metadata').doc('version').get();
return List<String>.from(doc.data()?['supportedLanguages'] ?? ['en']);
}
}
Example: REST API Backend #
class RestApiBackend implements TranslationBackend {
final String baseUrl;
RestApiBackend({required this.baseUrl});
@override
Future<TranslationData?> fetchTranslations(String languageCode) async {
final response = await http.get(Uri.parse('$baseUrl/translations/$languageCode'));
if (response.statusCode != 200) return null;
final data = jsonDecode(response.body);
return TranslationData(
translations: Map<String, String>.from(data['translations']),
version: data['version'],
);
}
}
Configuration Options #
You can configure the behavior of SmartLocalization during initialization.
await SmartLocalization.initialize(
backend: myBackend,
config: SmartLocalizationConfig(
defaultLanguage: 'en',
versionCheckInterval: const Duration(minutes: 5),
enableLogging: true,
autoDetectLanguage: true,
),
);
| Property | Type | Default | Description |
|---|---|---|---|
defaultLanguage |
String |
'en' |
The ultimate fallback language. |
versionCheckInterval |
Duration |
5 min |
Minimum interval between version updates. |
enableLogging |
bool |
false |
Enables debug console logs. |
autoDetectLanguage |
bool |
true |
Automatically detects the device language on startup. |
API Reference #
SmartLocalization #
| Method / Property | Description |
|---|---|
initialize(backend, config) |
Initializes the service (expected to be called once in main()). |
instance |
Accesses the singleton instance. |
translate(text, {id, params}) |
Synchronous translation lookup. |
translateAsync(text, {id, params}) |
Asynchronous translation with the full fallback chain. |
setLanguage(code) |
Changes the active language and fetches updates if needed. |
getSupportedLanguages() |
Returns a list of supported language codes. |
getLanguageName(code) |
Returns the display name for a specific language code. |
checkForUpdates() |
Manually checks for version updates (respects throttling). |
refreshTranslations() |
Forces a refresh from the remote backend. |
clearCache() |
Clears all cached translation data. |
currentLanguage |
Returns the currently active language code. |
BuildContext Extensions #
| Method | Description |
|---|---|
context.localization(text, {id, params}) |
Synchronous translation access. |
context.localizationAsync(text, {id, params}) |
Asynchronous translation access. |
Translation Fallback Chain #
When a translation is requested, the system attempts to resolve it in the following order:
- Current language translation (by ID)
- Default language translation (by ID)
- Provided fallback text
Requirements #
- Flutter 3.10 or higher
- Dart 3.0 or higher
License #
This project is licensed under the MIT License. See the LICENSE file for details.