my_lang 1.1.0 copy "my_lang: ^1.1.0" to clipboard
my_lang: ^1.1.0 copied to clipboard

A library that provides flexible and easy-to-use localization support for Flutter applications.

codecov GitHub Buy Me A Coffee PayPal Sponsor Support Me on Ko-fi

my_lang is a library that provides flexible and easy-to-use localization support for Flutter applications.

Requires Dart 3.9 or newer and Flutter 3.35 or newer. The current release is verified with Flutter 3.47.1 and Dart 3.13.1.

Features #

  • JSON, ARB, YAML, CSV, and XML translation files.
  • Nested keys, locale fallback, and compact multi-locale CSV files.
  • Missing-translation callbacks and custom decoders.
  • ICU placeholders, plurals, and selects for ARB-style messages.
  • In-memory locale cache and protection from out-of-order async loads.
  • Efficient listener-based locale switching with legacy compatibility.
  • Easy to integrate and use.
  • Dynamic language switching in the app.
  • Generates safe, typed Dart helpers from every supported file format.

Installation #

Add the following to your pubspec.yaml:

my_lang: ^1.1.0

flutter:
  assets:
    - assets/i18n/

Translation file formats #

Files use the locale name followed by the selected extension, for example en.json, en-US.arb, or zh-Hant.yaml.

JSON #

Create JSON files inside the assets/i18n/ directory:

en.json

{
  "welcomeBack": "Welcome Back",
  "welcomeBackNameApp": "Welcome @nameUser Back @nameApp"
}

Nested maps are flattened automatically, so {"home":{"title":"Home"}} can be read with translate('home.title').

ARB and ICU messages #

ARB metadata is ignored while messages remain available for lookup:

{
  "@@locale": "en",
  "cartItems": "{count, plural, =0{No items} one{# item} other{# items}}",
  "@cartItems": {
    "description": "Number of products in the cart"
  }
}
myLang.translateMessage('cartItems', arguments: {'count': 2});

YAML #

home:
  title: Home
  subtitle: Welcome back

CSV #

A file per locale can use key,value:

key,value
home.title,Home
welcome,"Hello, world"

One compact file can contain multiple locales:

key,en,vi
home.title,Home,Trang chu
await myLang.setUp(
  listLocale: const [Locale('en'), Locale('vi')],
  format: MyLangFileFormat.csv,
  fileName: 'translations.csv',
);

The shared CSV source is cached once while each locale column gets its own decoded map.

XML #

<resources>
  <string name="home.title">Home</string>
  <string name="welcome">Welcome</string>
</resources>

Custom formats #

Provide an extension and decoder when a project needs another format:

await myLang.setUp(
  listLocale: listLocale,
  fileExtension: 'toml',
  decoder: (source, locale) => decodeMyToml(source),
);

vi.json

{
  "welcomeBack": "Chào mừng trở lại",
  "welcomeBackNameApp": "Chào mừng @nameUser trở lại @nameApp"
}

Initializing the Library #

import 'package:my_lang/my_lang.dart';
import 'package:flutter/widgets.dart';

MyLang myLang = MyLang();

const listLocale = [
  Locale('en'),
  Locale('vi'),
];

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await myLang.setUp(
    listLocale: listLocale,
    format: MyLangFileFormat.json,
    fallbackLocale: const Locale('en'),
    onMissingTranslation: (key, locale) {
      debugPrint('Missing $key for $locale');
    },
  );
  runApp(MyApp());
}

Generating typed translation code #

The generator supports JSON, ARB, YAML/YML, CSV, and XML. The input format is inferred from the file extension:

dart run my_lang:my_lang \
  --input assets/i18n/en.yaml \
  --output lib/languages/interpreter.dart \
  --class OurLang

Use --format json|arb|yaml|csv|xml to override detection. For a compact CSV containing multiple locale columns, select the source column with --locale:

dart run my_lang:my_lang \
  --input assets/i18n/translations.csv \
  --output lib/languages/interpreter.dart \
  --class OurLang \
  --locale en

The generated extension contains getters for ordinary messages, parameters for @name placeholders, and typed arguments for ICU placeholders, plurals, and selects. Run dart run my_lang:my_lang --help for all options.

Creating interpreter.dart manually #

You can also create the extension without the generator:

import 'package:my_lang/my_lang.dart';

extension OurLang on MyLang {
  String get welcomeBack => translate('welcomeBack');
  String welcomeBackNameApp(String nameUser, String nameApp) =>
      translate('welcomeBackNameApp', params: {
        'nameUser': nameUser,
        'nameApp': nameApp,
      });
}

Usage #

print(myLang.welcomeBack); // "Welcome Back" or "Chào mừng trở lại"
print(myLang.welcomeBackNameApp("John", "MyApp"));

Changing language efficiently #

Wrap the part of the app that reads translations with a listener. MyLang then rebuilds listeners instead of reassembling the full widget tree:

ListenableBuilder(
  listenable: myLang,
  builder: (context, child) => MaterialApp(
    locale: myLang.locale,
    supportedLocales: listLocale,
    localizationsDelegates: GlobalMaterialLocalizations.delegates,
    home: const HomePage(),
  ),
);

Add Flutter's flutter_localizations SDK dependency when setting MaterialApp.locale, so Material and Cupertino widgets also use the selected locale.

await myLang.loadFile(
  locale: myLang.locale.languageCode == 'en'
      ? const Locale('vi')
      : const Locale('en'),
);

You can also use the helper:

await myLang.loadFile(
  locale: myLang.locale.isEnglish
      ? const Locale('vi')
      : const Locale('en'),
);

Decoded locale maps are cached. Call myLang.clearCache() after replacing translation assets at runtime. loadFileJson() remains available for existing applications.

Locale Helper #

Check the language of a Locale quickly:

final locale = myLang.locale;

if (locale.isEnglish) {
  // ...
}

if (locale.isLanguage('vi')) {
  // ...
}

Generating OurLang Automatically #

Run the following command to automatically generate interpreter.dart:

dart pub global activate my_lang
my_lang 
my_lang -i assets/i18n/en.arb -o lib/interpreter.dart -c YourLang
my_lang -i assets/i18n/translations.csv -o lib/interpreter.dart -c YourLang -l en

💡 Tip: Quickly copy a file path using these shortcuts on Android Studio:

  • MacBook: Command (⌘) + Option (⌥) + C
  • Windows: Ctrl + Shift + C

Two languages at the same time #

import 'package:my_lang/my_lang.dart';
import 'package:flutter/widgets.dart';

MyLang myLang = MyLang();
MyLang myLang2 = MyLang();

const listLocale = [
  Locale('en'),
  Locale('vi'),
];

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await myLang.setUp(listLocale: listLocale);
  await myLang2.setUp(
      listLocale: listLocale,
      keySaveLocale: "otherKeyForSharedPreference"
  );
  runApp(MyApp());
}

Note:
The keySaveLocale must be different for each instance.
This key is used to store the selected language in SharedPreferences.

Usage example: #

You can use both language instances as normal:

print(myLang.welcomeBack);
print(myLang2.welcomeBack);

Contribution #

If you have any suggestions or find any issues, feel free to open an issue or submit a pull request on GitHub. If you want to know what i do in package, checking my document here https://wong-coupon.gitbook.io/flutter/ui/multi-language

Developer Team: #

Any comments please contact us ThaoDoan and DucNguyen.

2
likes
150
points
23
downloads
screenshot

Documentation

API reference

Publisher

verified publisherwongcoupon.com

Weekly Downloads

A library that provides flexible and easy-to-use localization support for Flutter applications.

Repository (GitHub)
View/report issues

Topics

#localization #i18n #translation #multi-language #flutter

Funding

Consider supporting this project:

buymeacoffee.com
ko-fi.com
github.com
paypal.me

License

MIT (license)

Dependencies

csv, flutter, intl, shared_preferences, xml, yaml

More

Packages that depend on my_lang