flutter_bhasha 1.0.2 copy "flutter_bhasha: ^1.0.2" to clipboard
flutter_bhasha: ^1.0.2 copied to clipboard

A production-grade Flutter localization package with dynamic language switching, JSON translations, RTL/LTR support, interpolation, fallback language, persistent storage, and a clean developer API.

flutter_bhasha #

A production-grade Flutter package for bilingual and multilingual localization with dynamic language switching, JSON-based translations, RTL/LTR support, interpolation, fallback language, persistent storage, and a clean developer API.

pub.dev License: MIT


Features #

Feature Details
Dynamic language switching Swap locale at runtime — no app restart
JSON translations Simple en.json, te.json, … files
Nested + namespaced keys auth.login, errors.network
Parameter interpolation "welcome": "Hello, {name}!"
Fallback language Auto-falls back when a key is missing
Persistent storage Remembers the user's choice via shared_preferences
Device locale detection Matches device language on first launch
RTL / LTR auto-detection Arabic, Hebrew etc. get TextDirection.rtl
Missing key logger Console warnings during development
Provider integration ChangeNotifier + Provider for reactive rebuilds
Extension methods context.tr("key") and "key".tr()
Ready-made widgets LanguageSelectorDropdown, LanguageSelectorListTile, RtlWrapper

Installation #

dependencies:
  flutter_bhasha: ^1.0.0
  provider: ^6.1.2
  flutter_localizations:
    sdk: flutter

Add your translation assets to pubspec.yaml:

flutter:
  assets:
    - assets/translations/en.json
    - assets/translations/te.json
    # add more languages here

Quick Start #

1. Create translation files #

assets/translations/en.json

{
  "hello": "Hello",
  "welcome": "Welcome, {name}!",
  "auth": {
    "login": "Login"
  }
}

assets/translations/te.json

{
  "hello": "హలో",
  "welcome": "స్వాగతం, {name}!",
  "auth": {
    "login": "లాగిన్"
  }
}

2. Initialize #

import 'package:flutter_bhasha/flutter_bhasha.dart';

const enLocale = BhashaLocale(
  languageCode: 'en',
  displayName: 'English',
  nativeName: 'English',
  flagEmoji: '🇺🇸',
);

const teLocale = BhashaLocale(
  languageCode: 'te',
  displayName: 'Telugu',
  nativeName: 'తెలుగు',
  flagEmoji: '🇮🇳',
);

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final controller = await BhashaController.initialize(
    config: BhashaConfig(
      supportedLocales: [enLocale, teLocale],
      fallbackLocale: enLocale,
      assetPath: 'assets/translations',
      persistLocale: true,
      useDeviceLocale: true,
    ),
  );

  runApp(
    BhashaProvider(
      controller: controller,
      child: const MyApp(),
    ),
  );
}

3. Wire up MaterialApp #

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final controller = context.watch<BhashaController>();
    return MaterialApp(
      locale: controller.currentLocale.toLocale(),
      supportedLocales: controller.config.flutterLocales,
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      home: const HomeScreen(),
    );
  }
}

4. Translate #

// BuildContext extension
Text(context.tr('hello'))
Text(context.tr('welcome', params: {'name': 'Ranganath Pavan'}))

// String extension (no context needed)
Text('hello'.tr())
Text('welcome'.tr(params: {'name': 'Ranganath Pavan'}))

5. Switch language #

// Programmatically
await context.bhasha.setLocale(teLocale);
await context.bhasha.setLocaleByCode('te');

// Built-in dropdown widget
LanguageSelectorDropdown()

API Reference #

BhashaConfig #

Property Type Default Description
supportedLocales List<BhashaLocale> required All locales the app supports
fallbackLocale BhashaLocale required Used when no match is found
assetPath String packages/flutter_bhasha/assets/translations Path to JSON files in asset bundle
persistLocale bool true Save selected locale to shared_preferences
useDeviceLocale bool true Auto-detect device locale on first run
missingKeyBehavior MissingKeyBehavior returnKey What to return for missing keys
logMissingKeys bool true Print console warning for missing keys

BhashaLocale #

const BhashaLocale(
  languageCode: 'ar',
  countryCode: 'SA',        // optional
  displayName: 'Arabic',
  nativeName: 'العربية',   // shown in the language selector
  textDirection: TextDirection.rtl,
  flagEmoji: '🇸🇦',        // optional
)

BhashaController #

Method / Getter Description
BhashaController.initialize(config:) Creates and returns the singleton
setLocale(BhashaLocale) Switch to locale (persists if configured)
setLocaleByCode(String) Switch by language code string
resetLocale() Revert to fallback and clear persistence
translate(key, params:) Translate with optional interpolation
currentLocale Active BhashaLocale
isRTL true when current locale is RTL
isLoading true while loading translation files
supportedLocales All configured locales

Context extensions #

context.tr('key')                         // translate
context.tr('key', params: {'x': 'val'})  // with interpolation
context.bhasha                            // controller (no rebuild)
context.bhashaWatch                       // controller (rebuilds on change)
context.setLocale(locale)                // switch locale

Widgets #

Widget Description
BhashaProvider Root provider — wraps your MaterialApp
BhashaBuilder Consumer-style builder
LanguageSelectorDropdown Dropdown for AppBar / toolbar
LanguageSelectorListTile Settings-screen list tile
RtlWrapper Auto Directionality driven by active locale

Adding a New Language #

  1. Create assets/translations/fr.json.
  2. Register it in pubspec.yaml under flutter: assets:.
  3. Add a BhashaLocale to BhashaConfig.supportedLocales:
const frLocale = BhashaLocale(
  languageCode: 'fr',
  displayName: 'French',
  nativeName: 'Français',
  flagEmoji: '🇫🇷',
);

No code generation required.


Nested & Namespaced Keys #

{
  "auth": {
    "login": "Login",
    "errors": {
      "invalid_email": "Invalid email address"
    }
  }
}
context.tr('auth.login')
context.tr('auth.errors.invalid_email')

RTL Support #

const arLocale = BhashaLocale(
  languageCode: 'ar',
  displayName: 'Arabic',
  textDirection: TextDirection.rtl,
);

Use the built-in wrapper:

RtlWrapper(child: MyWidget())

Or manually:

Directionality(
  textDirection: context.bhashaWatch.textDirection,
  child: MyWidget(),
)

Performance Tips #

  • Pre-warm cache — call TranslationLoader.preload() at startup for all languages to avoid lag on first switch.
  • Lazy-load — only the active locale loads at startup; subsequent locales are loaded and cached on first access.
  • Keep JSON lean — split large translation sets into namespaced files and load on demand.
  • Use context.bhasha (not context.bhashaWatch) in widgets that don't need to rebuild on locale change.

Enterprise Scalability #

  • Remote translations — replace TranslationLoader with a custom implementation that fetches JSON from a CDN or API.
  • OTA updates — inject a custom AssetBundle that reads from disk/network to push translation fixes without a new release.
  • Custom storage — implement LocaleStorage to store the locale in a database, Keychain, or user profile service.
  • Namespace splitting — load feature-level JSON files on demand by creating multiple TranslationLoader instances with different assetPath values.

Publishing to pub.dev #

# Validate
flutter pub publish --dry-run

# Publish
flutter pub publish

Checklist:

  • ❌ Real homepage and repository in pubspec.yaml
  • CHANGELOG.md entry for the current version
  • dart pub publish --dry-run clean
  • flutter test passes
  • flutter analyze zero issues

Score boosters:

  • Add topics: [localization, i18n, l10n, flutter, multilingual] to pubspec.yaml
  • Keep description 60–180 characters
  • Provide a complete example/ app
  • Achieve 80%+ test coverage

Testing #

flutter test

Use _NoOpStorage and a fake AssetBundle to keep tests hermetic:

final controller = await BhashaController.initialize(
  config: config,
  storage: _NoOpStorage(),
  loader: TranslationLoader(bundle: FakeAssetBundle()),
);

Call BhashaController.reset() in setUp to clear the singleton between tests.


License #

MIT

flutter_bhasha #

0
likes
140
points
0
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A production-grade Flutter localization package with dynamic language switching, JSON translations, RTL/LTR support, interpolation, fallback language, persistent storage, and a clean developer API.

Repository (GitHub)
View/report issues

Topics

#localization #i18n #l10n #multilingual #flutter

License

MIT (license)

Dependencies

flutter, flutter_localizations, intl, provider, shared_preferences

More

Packages that depend on flutter_bhasha