Flutter API Reference
En esta página
Complete API reference for the better_i18n Flutter/Dart SDK.
BetterI18nProvider #
The top-level widget. Manages the BetterI18nController lifecycle and provides translations to all descendant widgets via BetterI18nScope.
BetterI18nProvider(
projectId: 'acme/app',
defaultLocale: 'en',
storage: SharedPrefsStorage(),
loadingBuilder: (_) => const CircularProgressIndicator(),
child: const MyApp(),
)Props #
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
projectId | String | Yes | — | Project ID — "org/project" slug or canonical UUID |
defaultLocale | String | Yes | — | Fallback locale used when no locale is set |
child | Widget | Yes | — | Root widget of your app |
locale | String? | No | null | Externally controlled locale (e.g., from a Cubit/BLoC) |
cdnBaseUrl | String? | No | https://cdn.better-i18n.com | CDN URL override |
ttl | int? | No | 300000 | Memory cache TTL in milliseconds (5 min) |
timeout | int? | No | 10000 | CDN fetch timeout in milliseconds |
retry | int? | No | 1 | Number of retry attempts on CDN failure |
storage | TranslationStorage? | No | null | Persistent storage adapter — use SharedPrefsStorage() |
staticData | Map<String, Messages>? | No | null | Bundled fallback translations for airplane mode first launch |
loadingBuilder | WidgetBuilder? | No | null | Widget shown while translations are loading (initial load only) |
errorBuilder | Widget Function(BuildContext, Object)? | No | null | Widget shown when a fatal error occurs |
BuildContext Extensions #
Available on any BuildContext below BetterI18nProvider in the widget tree.
Translate a key with optional interpolation arguments.
// Simple key
Text(context.t('common.welcome'))
// With interpolation
Text(context.t('common.greeting', args: {'name': 'Osman'}))
// → "Hello, Osman!" (if translation is "Hello, {{name}}!")Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
key | String | Yes | Key in "namespace.key" format |
args | Map<String, dynamic>? | No | Interpolation arguments |
Returns: String — Translated text, or the key itself if not found.
Key format: "namespace.key" (e.g., "common.hello", "auth.loginButton"). The part before the first . is the namespace; the rest is the key within that namespace.
Returns the current active locale code.
final locale = context.i18nLocale;
// → "en", "tr", "de", etc.Returns: String
Returns the list of available languages from the CDN manifest.
final languages = context.i18nLanguages;
// → [LanguageOption(code: 'en', name: 'English', ...), ...]Returns: List<LanguageOption>
Switch to a new locale. Fetches translations from CDN (or cache) and triggers a widget rebuild.
await context.setI18nLocale('tr');Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
code | String | Yes | Locale code (e.g., "tr", "de") |
Returns: Future<void>
Direct access to the BetterI18nController. Use for advanced scenarios.
final controller = context.i18n;
final isReady = controller.isReady;
final messages = controller.messages;Returns: BetterI18nController
BetterI18nController #
Manages i18n state — locale, messages, and languages. Extends ChangeNotifier so widgets rebuild when state changes.
final controller = BetterI18nController(
config: const I18nConfig(
projectId: 'acme/app',
defaultLocale: 'en',
),
initialLocale: 'tr',
);
await controller.initialize();Constructor #
| Parameter | Type | Required | Description |
|---|---|---|---|
config | I18nConfig | Yes | Core configuration |
initialLocale | String? | No | Starting locale — defaults to config.defaultLocale |
Getters #
| Getter | Type | Description |
|---|---|---|
locale | String | Current active locale |
messages | Messages? | Loaded translation messages (null until ready) |
languages | List<LanguageOption> | Available languages from CDN manifest |
isLoading | bool | Whether translations are currently loading |
isReady | bool | Whether the controller is initialized and ready |
error | Object? | Last error that occurred during loading, if any |
Methods #
Fetches the CDN manifest and initial locale messages in parallel. Called automatically by BetterI18nProvider — only call manually when using BetterI18nController directly.
await controller.initialize();Returns: Future<void>
Switch to a new locale and reload messages.
await controller.setLocale('tr');Returns: Future<void>
Translate a key with optional interpolation arguments. Returns the key itself if not found.
final text = controller.translate('common.welcome', args: {'name': 'Osman'});Returns: String
I18nCore #
The pure Dart core engine — no Flutter dependency. Implements the 4-tier fallback chain. Used internally by BetterI18nController.
final core = I18nCore(
config: NormalizedConfig(
projectId: 'acme/app',
defaultLocale: 'en',
cdnBaseUrl: 'https://cdn.better-i18n.com',
manifestCacheTtlMs: 300000,
timeout: 10000,
retry: 1,
),
);Methods #
Fetch the CDN manifest with full fallback chain (memory → CDN → storage).
final manifest = await core.getManifest();
final manifest = await core.getManifest(forceRefresh: true);Returns: Future<ManifestResponse>
Fetch translation messages for a locale with full fallback chain.
final messages = await core.getMessages('tr');Returns: Future<Messages>
Get available languages as LanguageOption list.
final languages = await core.getLanguages();Returns: Future<List<LanguageOption>>
Get available locale codes.
final locales = await core.getLocales();
// → ["en", "tr", "de"]Returns: Future<List<String>>
Clear all static caches — manifest and messages. Useful between tests.
I18nCore.clearAllCaches();Also available as separate methods:
I18nCore.clearManifestCache();
I18nCore.clearMessagesCache();BetterI18nScope #
Low-level InheritedNotifier that provides BetterI18nController to the widget tree. Used internally by BetterI18nProvider — use directly only for testing or advanced scenarios.
BetterI18nScope(
controller: myController,
child: MyWidget(),
)Static Methods #
Look up the nearest BetterI18nController in the widget tree.
final controller = BetterI18nScope.of(context);Returns: BetterI18nController
Throws if no BetterI18nScope is found in the ancestor tree.
Types #
Simplified language info for UI components (e.g., language picker).
class LanguageOption {
final String code; // "en", "tr"
final String? name; // "English", "Turkish" (English name)
final String? nativeName; // "English", "Türkçe" (native name)
final String? flagUrl; // URL to flag image (from dashboard)
final bool isDefault; // true for the source/default language
}Translation messages keyed by namespace, then by key.
typedef Messages = Map<String, Map<String, dynamic>>;
// Example:
// {
// "common": {"welcome": "Welcome", "appTitle": "My App"},
// "auth": {"loginButton": "Sign In"},
// }Matches the CDN response format exactly.
Abstract interface for persistent storage adapters.
abstract class TranslationStorage {
Future<String?> get(String key);
Future<void> set(String key, String value);
Future<void> remove(String key);
}Implement this class to use a custom storage backend (SQLite, Hive, secure storage, etc.).
Core configuration class passed to BetterI18nController.
const I18nConfig({
required String project, // "org/project"
required String defaultLocale, // "en"
String? cdnBaseUrl, // CDN URL override
int? ttl, // memory cache TTL (ms)
int? timeout, // fetch timeout (ms)
int? retry, // retry count
TranslationStorage? storage, // persistent storage
Map<String, Messages>? staticData, // bundled fallback
})CDN manifest data returned by I18nCore.getManifest().
class ManifestResponse {
final List<ManifestLanguage> languages;
final String? projectSlug;
final String? sourceLanguage;
final String? updatedAt;
}Raw language info from the CDN manifest.
class ManifestLanguage {
final String code;
final String? name;
final String? nativeName;
final String? flagUrl;
final bool isSource; // true for source language
}Storage #
Persistent storage adapter backed by shared_preferences. The recommended choice for production Flutter apps.
import 'package:better_i18n/better_i18n.dart';
BetterI18nProvider(
projectId: 'acme/app',
defaultLocale: 'en',
storage: SharedPrefsStorage(),
child: const MyApp(),
)Requires the shared_preferences package in pubspec.yaml.
Testing Utilities #
Inject a pre-configured controller directly into the widget tree — no CDN calls needed:
import 'package:better_i18n/better_i18n.dart';
import 'package:flutter_test/flutter_test.dart';
testWidgets('renders translated welcome text', (tester) async {
// Clear static caches between tests
I18nCore.clearAllCaches();
final controller = BetterI18nController(
config: const I18nConfig(
projectId: 'test/app',
defaultLocale: 'en',
staticData: {
'en': {
'common': {
'welcome': 'Welcome',
'greeting': 'Hello, {{name}}!',
},
},
},
),
);
await controller.initialize();
await tester.pumpWidget(
BetterI18nScope(
controller: controller,
child: Builder(
builder: (ctx) => MaterialApp(
home: Scaffold(
body: Text(ctx.t('common.welcome')),
),
),
),
),
);
expect(find.text('Welcome'), findsOneWidget);
});Static method to clear all in-memory caches between tests. Essential when multiple tests share the same project identifier.
setUp(() {
I18nCore.clearAllCaches();
});Clears both manifest and messages caches. Also available as:
I18nCore.clearManifestCache()— manifest onlyI18nCore.clearMessagesCache()— messages only
Better I18N