{"id":32278190,"url":"https://github.com/aydinfatih/localization_plus","last_synced_at":"2026-02-22T18:01:36.483Z","repository":{"id":199044225,"uuid":"702035725","full_name":"aydinfatih/localization_plus","owner":"aydinfatih","description":"Easy, Advanced and Fast Internationalization for your Flutter Apps","archived":false,"fork":false,"pushed_at":"2024-03-03T08:54:33.000Z","size":628,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-23T00:26:32.610Z","etag":null,"topics":["dart","flutter","localization"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/localization_plus","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aydinfatih.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"aydinfatih","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2023-10-08T10:06:47.000Z","updated_at":"2024-11-17T03:59:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"da292383-3365-496e-b8cc-7ce844d960c5","html_url":"https://github.com/aydinfatih/localization_plus","commit_stats":null,"previous_names":["aydinfatih/localization_plus"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/aydinfatih/localization_plus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aydinfatih%2Flocalization_plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aydinfatih%2Flocalization_plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aydinfatih%2Flocalization_plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aydinfatih%2Flocalization_plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aydinfatih","download_url":"https://codeload.github.com/aydinfatih/localization_plus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aydinfatih%2Flocalization_plus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29721047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T15:10:41.462Z","status":"ssl_error","status_checked_at":"2026-02-22T15:10:04.636Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","flutter","localization"],"created_at":"2025-10-23T00:17:59.622Z","updated_at":"2026-02-22T18:01:36.476Z","avatar_url":"https://github.com/aydinfatih.png","language":"Dart","funding_links":["https://github.com/sponsors/aydinfatih"],"categories":[],"sub_categories":[],"readme":"# Easy, Advanced and Fast Internationalization for your Flutter Apps\n\n[![platform](https://img.shields.io/badge/Platform-Flutter-02569B?logo=flutter)](https://flutter.dev)\n[![platform](https://img.shields.io/badge/Platform-Dart-02569B?logo=dart)](https://dart.dev)\n[![pub package](https://img.shields.io/pub/v/localization_plus.svg?label=localization_plus\u0026color=02569B)](https://pub.dev/packages/localization_plus)\n[![license](https://img.shields.io/github/license/aydinfatih/localization_plus?color=02569B)](https://opensource.org/licenses/BSD-3-Clause)\n\n\n## About this library\n\n- ✅ Fully tested code (100% code coverage)\n- 🌐 Easy translations for many languages\n- 🛡️ Null safety\n- 📂 Load translations from JSON file\n- 🧩 Extension methods on BuildContext, String and Text, Enum\n- 🚀 Supports plural, nesting, choice, RTL locales and more\n- ↩️ Fallback locale keys redirection (Optional)\n- 💾 Persistent locale storage (Optional)\n- ❗ Error widget for missing translations\n- 🎧 Listening to localization changes via controller\n- 🔁 Context independent locale change via controller\n- 🌐 Enum translations\n\n\n## Installation\n\nAdd to your pubspec.yaml:\n\n```yaml\ndependencies:\n  localization_plus: \u003clast_version\u003e\n```\n\nCreate folder and add translation files like this\n```\ni18n\n    ├── {languageCode}.{ext}                  // useOnlyLangCode: true\n    └── {languageCode}-{countryCode}.{ext}    // useOnlyLangCode: false (default)\n```\n\nExample:\n\n```\ni18n\n    ├── en.json\n    └── en-US.json \n```\n\nDeclare your assets localization directory in `pubspec.yaml`:\n\n```yaml\nflutter:\n  assets:\n    - i18n/\n```\n\n### 🚨 Note on **iOS**\n\nFor translation to work on **iOS** you need to add supported locales to\n`ios/Runner/Info.plist` as described [here](https://flutter.dev/docs/development/accessibility-and-localization/internationalization#specifying-supportedlocales).\n\nExample:\n\n```xml\n\u003ckey\u003eCFBundleLocalizations\u003c/key\u003e\n\u003carray\u003e\n\t\u003cstring\u003een\u003c/string\u003e\n\t\u003cstring\u003enb\u003c/string\u003e\n\u003c/array\u003e\n```\n## Documentation\n\n### 📄 LocalizationPlusController properties\n| Properties              | Required | Default                   | Description                                                                                                                                                                      |\n| ----------------------- | -------- | ------------------------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| supportedLocales        | true     |                           | List of supported locales.                                                                                                                                                       |\n| path                    | true     |                           | Path to your folder with localization files.                                                                                                                                     |\n| loader             | false    | `RootBundleAssetLoader()` | Class loader for localization files. You can create your own class.                                                                                                              |\n| saveLocale              | false    | `true`                    | Whether to save on the device after changing the language                                                                                                                        |\n| useOnlyLangCode         | false    | `false`                   | Trigger for using only language code for reading localization files.\u003c/br\u003e\u003c/br\u003eExample:\u003c/br\u003e`en.json //useOnlyLangCode: true`\u003c/br\u003e`en-US.json //useOnlyLangCode: false (default)` |\n| useFallbackTranslations | false    | `false`                   | If a localization key is not found in the locale file, try to use the fallbackLocale file. sets the first supported language as fallback if fallback locale is not set                                                                                      |\n| fallbackLocale          | false    |                           | Set the locale to be used as an alternative if a localization key is not found in the locale file                                                                                                        |\n| startLocale             | false    |                           | If there is no saved language, set the language in which the system will start                                                                                                                                                        |\n\n\n### 📄 LocalizationPlus widget properties\n| Properties              | Required | Default                   | Description                                                                                                                                                                   |\n| ----------------------- | -------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| key                     | false    |                           | Widget key.                                                                                                                                                                   |\n| child                   | true     |                           | Place for your main page widget.                                                                                                                                              |\n| controller                    | true     |                           | LocalizationPlusController instance .                                                                                                                                  |\n\n### Replacing Parameters In Translation Strings\n\nIf you wish, you may define placeholders in your translation strings. All placeholders must be between curly brackets. For example, you may define a welcome message with a placeholder name:\n\n```json\n{\n    \"welcome\": \"Welcome, {name}\"\n}\n```\n\nIf your placeholder contains all capital letters, or only has its first letter capitalized, the translated value will be capitalized accordingly:\n\n```json\n\"welcome\": \"Welcome, {NAME}\" // Welcome, USER\n\"welcome\": \"Welcome, {Name}\" // Welcome, User\n```\n## Usage/Examples\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:localization_plus/localization_plus.dart';\n\nvoid main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n\n  // If you wish, you can define it so that it can be accessed \n  // from anywhere in the system with a package such as the getIt library\n  LocalizationPlusController controller = await LocalizationPlusController.init(\n    path: 'i18n',\n  );\n\n  runApp(\n    LocalizationPlus(\n      controller: controller,\n      supportedLocales: [\n        'en_US'.toLocale(),\n        'ar_DZ'.toLocale(),\n        'tr_TR'.toLocale(),\n        'ru_RU'.toLocale(),\n      ],\n      child: const MyApp()\n    ),\n  );\n}\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      // Localizations\n      localizationsDelegates: context.localizationDelegates,\n      supportedLocales: context.supportedLocales,\n      locale: context.locale,\n\n      home: MyHomePage()\n    );\n  }\n}\n\n```\n\n[**Full example**](https://github.com/aydinfatih/localization_plus/blob/master/example/lib/main.dart)\n\n### 🔥 Change locale\nYou can change the locale with the help of BuildContext extension method or controller.\n\n```dart\n// via context\ncontext.setLocale('en_US'.toLocale());\n\n// via controller\ncontroller.setLocale('en_US'.toLocale());\n```\n\n### 🔥 Reset locale `resetLocale()`\nReset locale to initial locale. Sets startLocale to `startLocale` if `startLocale` is defined, to `deviceLocale` if not defined\n\n```dart\n// via context\ncontext.resetLocale()\n\n// via controller\ncontroller.resetLocale();\n```\n\n### 🔥 Delete saved locale `deleteSavedLocale()`\nClears a saved locale from local storage \n\n```dart\n// via context\ncontext.deleteSavedLocale()\n\n// via controller\ncontroller.deleteSavedLocale();\n```\n\n### 🔥 Get locale `currentLocale`\nReturns the current locale in the application\n\n```dart\n// via context\ncontext.currentLocale;\n\n// via controller\ncontroller.currentLocale;\n```\n\n\n### 🔥 Get device locale `deviceLocale`\nReturns the device locale\n\n```dart\n// via context\ncontext.deviceLocale\n\n// via controller\ncontroller.deviceLocale\n```\n\n\n\n### 🔥 Get fallback locale `fallbackLocale`\nReturns the fallback locale. Returns null if `useFallbackTranslations` is `false`\n\n```dart\n// via context\ncontext.fallbackLocale\n\n// via controller\ncontroller.fallbackLocale\n```\n\n### 🔥 Translate `trans()`\nMain function for translate your language keys\n\nYou can use extension methods of `[String]` or `[Text]` widget, you can also use `trans()` as a helper function.\n\nExample:\n\n``` json\n{\n  \"notations\": \"Default: {arg}, Capital: {Arg}, Uppercase: {ARG}\",\n}\n```\n\n\n```dart\n'notations'.trans(arguments: {'arg': 'test'}) // String\n// Result: Default: test, Capital: Test, Uppercase: TEST\n\n\nconst Text('notations').trans(arguments: {'arg': 'test'}) // Text\n// Result: Text instance\n\n\ntrans('notations', arguments: {'arg': 'test'}) // Helper function\n// Result: Default: test, Capital: Test, Uppercase: TEST\n```\n\n#### Arguments:\n\n| Name      | Type                  | Description                                                                         |\n| --------- | --------------------- | ----------------------------------------------------------------------------------- |\n| arguments | `Map\u003cString, String\u003e` | Map of localized strings. Replaces the name keys `{key_name}` according to its name |\n\n\n### 🔥 Plurals `plural()`\nPluralization is a complex problem, as different languages have a variety of complex rules for pluralization; however, Localization Plus can help you translate strings differently based on pluralization rules that you define.\n\nYou can use extension methods of `[String]` or `[Text]` widget, you can also use `plural()` as a helper function.\n\n🚨 Key \"other\" required!\n\nExample:\n\n``` json\n{\n  \"clicked\": {\n    \"zero\": \"Today\",\n    \"one\": \"Tomorrow\",\n    \"two\": \"2 days later\",\n    \"few\": \"A few days later\",\n    \"many\": \"Weeks later\",\n    \"other\": \"After a long time\"\n  }\n}\n```\n\n\n```dart\n// String\n'clicked'.plural(0) // Today\n'clicked'.plural(1) // Tomorrow\n'clicked'.plural(2) // 2 days late\n'clicked'.plural(3) // A few days later (Depends on the language)\n'clicked'.plural(11) // Weeks later (Depends on the language)\n'clicked'.plural(1250) // After a long time (Depends on the language)\n\n// Text\nText('clicked').plural(0) // Today\nText('clicked').plural(1) // Tomorrow\nText('clicked').plural(2) // 2 days late\nText('clicked').plural(3) // A few days later (Depends on the language)\nText('clicked').plural(11) // Weeks later (Depends on the language)\nText('clicked').plural(1250) // After a long time (Depends on the language)\n\nplural('clicked', 0) // Today\nplural('clicked', 1) // Tomorrow\nplural('clicked', 2) // 2 days late\nplural('clicked', 3) // A few days later (Depends on the language)\nplural('clicked', 11) // Weeks later (Depends on the language)\nplural('clicked', 1250) // After a long time (Depends on the language)\n```\n\n#### Arguments:\n\n| Name      | Type                  | Description                                                                         |\n| --------- | --------------------- | ----------------------------------------------------------------------------------- |\n| arguments | `Map\u003cString, String\u003e` | Map of localized strings. Replaces the name keys `{key_name}` according to its name |\n\n\n### 🔥 Trans Choice `transChoice()`\nYou may create more complex pluralization rules which specify translation strings for multiple ranges of values.\n\nYou can use extension methods of `[String]` or `[Text]` widget, you can also use `transChoice()` as a helper function.\n\nExample:\n\n``` json\n{\n  \"price\": {\n    \"0\": \"Free\",\n    \"1:5\": \"Cheap\",\n    \"6:10\": \"Normal\",\n    \"*\": \"Expensive\"\n  }\n}\n```\n\n\n```dart\n// String\n'price'.transChoice(0) // Free\n'price'.transChoice(1) // Cheap\n'price'.transChoice(3) // Cheap\n'price'.transChoice(6) // Normal\n'price'.transChoice(10) // Normal\n'price'.transChoice(1250) // Expensive\n\n// Text\n('price').transChoice(0) // Free\n('price').transChoice(1) // Cheap\n('price').transChoice(3) // Cheap\n('price').transChoice(6) // Normal\n('price').transChoice(10) // Normal\n('price').transChoice(1250) // Expensive\n\ntransChoice('price', 0) // Free\ntransChoice('price', 1) // Cheap\ntransChoice('price', 3) // Cheap\ntransChoice('price', 6) // Normal\ntransChoice('price', 10) // Normal\ntransChoice('price', 1250) // Expensive\n```\n\n#### Arguments:\n\n| Name      | Type                  | Description                                                                         |\n| --------- | --------------------- | ----------------------------------------------------------------------------------- |\n| arguments | `Map\u003cString, String\u003e` | Map of localized strings. Replaces the name keys `{key_name}` according to its name |\n\n### 🔥 Listening for locale change\nYou can listen to locale changes with the help of the controller.\n\n```dart\ncontroller.addListener(() {\n  // Locale changed\n  // Refetch language dependent remote data etc.\n});\n```\n\n### 🔥 Linked translations:\nIf there's a translation key that will always have the same concrete text as another one you can just link to it. To link to another translation key, all you have to do is to prefix its contents with an @: sign followed by the full name of the translation key including the namespace you want to link to.\n\n\n``` json\n{\n  \"hello\": \"Hello\",\n  \"world\": \"World\",\n  \"hello_world\": \"@:hello @:world\"\n}\n```\n\nYou can also do nested anonymous and named arguments inside the linked messages.\n\n#### Formatting linked translations:\nIf the language distinguishes cases of character, you may need to control the case of the linked locale messages. Linked messages can be formatted with modifier `@.modifier:key`\n\nThe below modifiers are available currently.\n\n- `upper`: Uppercase all characters in the linked message.\n- `lower`: Lowercase all characters in the linked message.\n- `capitalize`: Capitalize the first character in the linked message.\n\nxample:\n\n```json\n{\n  ...\n  \"hello\": \"Hello\",\n  \"world\": \"World\",\n  \"hello_world\": \"@.upper:hello @.lower:world\" // HELLO world\n  ...\n}\n```\n\n### 🔥 Check translation exists `transExists()`\nYou can check if a key has a translation\n\n```dart\n'notations'.transExists() // String\n// Result: true\n\ntransExists('not_exists') // Helper function\n// Result: false\n```\n\n## 🧩 Extensions\n\n### String Extension\n\n```dart\n'en_US'.toLocale(); // Locale('en', 'US')\n\n//with custom separator\n'en|US'.toLocale(separator: '|') // Locale('en', 'US')\n```\n\n\n### Enum Extension\nYou can quickly add translations to your enum values.\n\n``` json\n{\n  \"enums\": {\n    \"response_status_type\": {\n      \"successful\": \"Successful\",\n      \"server_error\": \"Server Error\"\n    }\n  },\n}\n```\n\n```dart\nResponseStatusType.successful.description; //Successful\nResponseStatusType.serverError.description; //Server Error\n```\n\n\n### Build Context Extension\n\n```dart\ncontext.currentLocale // get current locale\n\ncontext.deviceLocale // get device locale\n\ncontext.fallbackLocale // get fallback locale\n\ncontext.supportedLocales // get supported locales\n\ncontext.localizationDelegates // get localization delegates\n```\n## Screenshots\n\n| Arabic RTL                                                                                                           | English LTR                                                                                                                   | Turkish LTR                                                                                                            | Russian LTR                                                                                                            |\n|----------------------------------------------------------------------------------------------------------------------| ----------------------------------------------------------------------------------------------------------------------------- |------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|\n| ![Arabic RTL](https://raw.githubusercontent.com/aydinfatih/localization_plus/master/screenshots/ar.png \"Arabic RTL\") | ![English LTR](https://raw.githubusercontent.com/aydinfatih/localization_plus/master/screenshots/en.png \"English LTR\") | ![Turkish LTR](https://raw.githubusercontent.com/aydinfatih/localization_plus/master/screenshots/tr.png \"Turkish LTR\") | ![Russian LTR](https://raw.githubusercontent.com/aydinfatih/localization_plus/master/screenshots/ru.png \"Russian LTR\") |\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faydinfatih%2Flocalization_plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faydinfatih%2Flocalization_plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faydinfatih%2Flocalization_plus/lists"}