{"id":15388125,"url":"https://github.com/ilteoood/flutter_i18n","last_synced_at":"2025-04-08T04:13:35.136Z","repository":{"id":32919250,"uuid":"146212351","full_name":"ilteoood/flutter_i18n","owner":"ilteoood","description":"I18n made easy, for Flutter!","archived":false,"fork":false,"pushed_at":"2025-01-29T17:44:13.000Z","size":1010,"stargazers_count":218,"open_issues_count":1,"forks_count":58,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-01T03:33:09.592Z","etag":null,"topics":["dart","flutter","hacktoberfest","i18n","internationalization","localization"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ilteoood.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,"publiccode":null,"codemeta":null},"funding":{"patreon":"ilteoood"}},"created_at":"2018-08-26T20:02:06.000Z","updated_at":"2025-01-29T17:44:17.000Z","dependencies_parsed_at":"2023-12-29T12:28:03.967Z","dependency_job_id":"9e19eec8-ec82-4908-9ed7-6e503c7c9d35","html_url":"https://github.com/ilteoood/flutter_i18n","commit_stats":{"total_commits":291,"total_committers":23,"mean_commits":"12.652173913043478","dds":0.4604810996563574,"last_synced_commit":"8b8ce4a6ce91600b28982dcbd6909ab40efa4c19"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilteoood%2Fflutter_i18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilteoood%2Fflutter_i18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilteoood%2Fflutter_i18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilteoood%2Fflutter_i18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ilteoood","download_url":"https://codeload.github.com/ilteoood/flutter_i18n/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247773719,"owners_count":20993639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","hacktoberfest","i18n","internationalization","localization"],"created_at":"2024-10-01T14:55:34.847Z","updated_at":"2025-04-08T04:13:35.110Z","avatar_url":"https://github.com/ilteoood.png","language":"Dart","funding_links":["https://patreon.com/ilteoood","https://www.patreon.com/ilteoood","https://www.buymeacoffee.com/ilteoood"],"categories":[],"sub_categories":[],"readme":"# flutter_i18n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\nI18n made easy, for Flutter!\n\n\u003c!-- Badges --\u003e\n[![Pub Package](https://img.shields.io/pub/v/flutter_i18n.svg)](https://pub.dev/packages/flutter_i18n)\n[![GitHub Actions](https://github.com/ilteoood/flutter_i18n/workflows/Publish%20plugin/badge.svg)](https://github.com/ilteoood/flutter_i18n/actions)\n\n------------------------------------------------\n\n## Table of contents\n\n* [Why should you use flutter_i18n?](#why-should-you-use-flutter_i18n)\n* [Loaders](#loaders)\n  * [FileTranslationLoader](#filetranslationloader-configuration)\n  * [NetworkFileTranslationLoader](#networkfiletranslationloader-configuration)\n  * [NamespaceFileTranslationLoader](#namespacefiletranslationloader-configuration)\n  * [E2EFileTranslationLoader](#e2efiletranslationloader-configuration)\n* [flutter_i18n in action](#flutter_i18n-in-action)\n* [Plugins](#plugins)\n* [Contributors](#contributors-)\n\n## Why should you use flutter_i18n?\n\nThe main goal of *flutter_i18n* is to simplify the i18n process in Flutter.\nI would like to recreate the same experience that you have with the Angular i18n: simple *json* files, one for each language that you want to support.\n\n\n## Loaders\n\nLoader is a class which loads your translations from specific source. \nYou can easy override loader and create your own.\n\nAvailable loaders:\n\n| Class name | Purpose |  \n| --- | --- |\n| `FileTranslationLoader` |  Loads translation files from JSON, YAML, TOML or XML format |\n| `LocalTranslationLoader` |  Is a copy of `FileTranslationLoader`, but used to loads the files from the device storage instead of assets folder | \n| `NetworkFileTranslationLoader` | Loads translations from the remote resource | \n| `NamespaceFileTranslationLoader` | Loads translations from separate files |\n| `E2EFileTranslationLoader` | Special loader for solving isolates problem with flutter drive |\n\n### `FileTranslationLoader` configuration\n\nTo use this library, you must create a folder in your project's root: the `basePath`. Some examples:\n\n\u003e /assets/flutter_i18n (the default one)\n\u003e\n\u003e /assets/i18n\n\u003e\n\u003e /assets/locales\n\nInside this folder, you'll put the *json*, *yaml*, *xml* or *toml* files containing the translated keys. You have different options:\n\n- If you want to specify the country code\n\n    \u003e `basePath`/{languageCode}_{countryCode}.json\n\n- If you want to specify the script code\n\n    \u003e `basePath`/{languageCode}_{scriptCode}.json\n\n- If you want to specify both\n\n    \u003e `basePath`/{languageCode}_{scriptCode}_${countryCode}_.json\n\n- otherwise\n\n    \u003e `basePath`/{languageCode}.json\n\nIf the *json* file is not available, we will look for a *yaml* file with the same name. In case both exist, the *json* file will be used.\n\nOf course, you must declare the subtree in your ***pubspec.yaml*** as assets:\n\n```yaml\nflutter:\n  assets:\n    - {basePath}\n```\n\nThe next step consist in the configuration of the *localizationsDelegates*; to use *flutter_i18n*, you should configure as follows:\n\n```dart\nlocalizationsDelegates: [\n        FlutterI18nDelegate(\n          translationLoader: FileTranslationLoader(...parameters...),\n          missingTranslationHandler: (key, locale) {\n            print(\"--- Missing Key: $key, languageCode: ${locale.languageCode}\");\n          },\n        ),\n        GlobalMaterialLocalizations.delegate,\n        GlobalWidgetsLocalizations.delegate\n],\nbuilder: FlutterI18n.rootAppBuilder() //If you want to support RTL.\n```\n\nBelow you can find the name and description of the accepted parameters.\n\nThe ***useCountryCode*** parameter depends on the *json* configuration:\n- if you used the pattern {languageCode}_{countryCode}, ***useCountryCode*** must be **true**\n- if you used the pattern {languageCode}, ***useCountryCode*** must be **false**\n\nThe ***fallbackFile*** parameter was entroduces with the version **0.1.0** and provide a default language, used when the translation for the current running system is not provided. This should contain the name of a valid *json* file in *assets* folder.\n\nThe ***basePath*** parameter is optionally used to set the base path for translations. If this option is not set, the default path will be `assets/flutter_i18n`. This path must be the same path as the one defined in your ***pubspec.yaml***.\n\nThe ***forcedLocale*** parameter is optionally used to force a locale instead finding the system one.\n\nThe ***decodeStrategies*** parameters is optionally used to choose witch kind of file you want to load. By default JSON, YAML and XML are enabled. If you use only one format, you can speed-up the bootstrap process using only the one you need.\n\nIf there isn't any translation available for the required key, even in the fallback file, the same key is returned.\n\n### `NetworkFileTranslationLoader` configuration\n\nBehaviour of this loader very similar as `FileTranslationLoader`. The main difference that we load translations from `NetworkAssetBundle` instead of `CachingAssetBundle`.\n\nBelow you can find the name and description of the accepted parameters.\n\nThe ***baseUri*** parameter provide base Uri for your remote translations.\n\nThe ***useCountryCode*** parameter depends on the *json* configuration:\n- if you used the pattern {languageCode}_{countryCode}, ***useCountryCode*** must be **true**\n- if you used the pattern {languageCode}, ***useCountryCode*** must be **false**\n\nThe ***fallbackFile*** parameter provide a default language, used when the translation for the current running system is not provided.\n\nThe ***forcedLocale*** parameter is optionally used to force a locale instead finding the system one.\n\nFor example if your translation files located at \n`https://example.com/static/en.json` you should configure as follows:\n\n```dart\nMaterialApp(\n  localizationsDelegates: [\n        FlutterI18nDelegate(translationLoader: \n          NetworkFileTranslationLoader(baseUri: Uri.https(\"example.com\", \"static\")),\n        GlobalMaterialLocalizations.delegate,\n        GlobalWidgetsLocalizations.delegate\n  ],\n)\n```\n\n### `NamespaceFileTranslationLoader` configuration\n\nBehaviour of this loader very similar as `FileTranslationLoader`. The main difference that we load translations from separate files per each language.\n\nFor example `FileTranslationLoader` format:\n\n\u003e /assets/flutter_i18n/en.json\n\u003e\n\u003e /assets/flutter_i18n/it.json\n\n`NamespaceFileTranslationLoader` format:\n\n\u003e /assets/flutter_i18n/en/home_screen.json\n\u003e\n\u003e /assets/flutter_i18n/en/about_screen.json\n\u003e\n\u003e /assets/flutter_i18n/it/home_screen.json\n\u003e\n\u003e /assets/flutter_i18n/it/about_screen.json\n\nExample configuration:\n\n```dart\nMaterialApp(\n  localizationsDelegates: [\n        FlutterI18nDelegate(translationLoader: \n          NamespaceFileTranslationLoader(namespaces: [\"home_screen\", \"about_screen\"]),\n        GlobalMaterialLocalizations.delegate,\n        GlobalWidgetsLocalizations.delegate\n  ],\n)\n```\n\nBelow you can find the name and description of the accepted parameters.\n\nThe ***namespaces*** provide a list of filenames for the specific language directory.\n\nThe ***useCountryCode*** parameter depends on the *json* configuration:\n- if you used the pattern {languageCode}_{countryCode}, ***useCountryCode*** must be **true**\n- if you used the pattern {languageCode}, ***useCountryCode*** must be **false**\n\nThe ***fallbackDir*** provide a default language directory, used when the translation for the current running system is not provided.\n\nThe ***basePath*** parameter is optionally used to set the base path for translations. If this option is not set, the default path will be `assets/flutter_i18n`. This path must be the same path as the one defined in your ***pubspec.yaml***.\n\nThe ***forcedLocale*** parameter is optionally used to force a locale instead finding the system one.\n\n### `E2EFileTranslationLoader` configuration\n\nThe same as `FileTranslationLoader` configuration. This loader can be used for solving problem with flutter drive testing.\nIt removes using separate isolate for loading translations (detailed issue described here: [issues/24703](https://github.com/flutter/flutter/issues/24703)).\n\nThe ***useE2E*** parameter:\n- if you are in flutter drive testing mode – must be **true**\n- if you are in normal mode – must be **false**, in this case `FileTranslationLoader` will be used\n\n## flutter_i18n in action\n\nAfter the configuration steps, the only thing to do is invoke the following method:\n\n```dart\nFlutterI18n.translate(buildContext, \"your.key\")\n```\n\nWhere:\n- *buildContext* is the *BuildContext* instance of the widget\n- *your.key* is the key to translate\n\nOther examples of use:\n\nForce a language to be loaded at run-time:\n```dart\nawait FlutterI18n.refresh(buildContext, languageCode, {countryCode});\n```\n\nPlural translations:\n```dart\nFlutterI18n.plural(buildContext, \"your.key\", pluralValue);\n```\n\nText widget shorthand:\n```dart\nI18nText(\"your.key\", child: Text(\"\"))\nI18nText(\"your.key\", translationParams: {\"user\": \"Flutter lover\"})\nI18nPlural(\"clicked.times\", 1)\nI18nPlural(\"clicked.times\", 2, child: Text(\"\"))\n```\n\nIf you need to listen the translation loading status, you can use:\n- ```FlutterI18n.retrieveLoadingStream``` method, that allows you to listen to every status change\n- ```FlutterI18n.retrieveLoadedStream``` method, that allows you to listen when the translation is loaded\n\nFor more informations and details, read the [CHANGELOG.md](CHANGELOG.md).\n\n## Utilities\n\nUsing *flutter pub run flutter_i18n* inside the root of your project you can enjoy some utilities that will help you with the translations files management.\n\n### Commands\n\n#### Validate\n\nThis command is used to validate all the translations files inside the project.\n\n```sh\n\u003e flutter pub run flutter_i18n validate\n[flutter_i18n DEBUG]: I've found assets/i18n/en.yaml\n[flutter_i18n DEBUG]: I've found assets/i18n/it.json\n[flutter_i18n DEBUG]: I've found assets/i18n/es.xml\n[flutter_i18n DEBUG]: I've found assets/i18n_namespace/en/common.json\n[flutter_i18n DEBUG]: I've found assets/i18n_namespace/en/home.yaml\n[flutter_i18n DEBUG]: I've found assets/i18n_namespace/ua/common.json\n[flutter_i18n DEBUG]: I've found assets/i18n_namespace/ua/home.json\n[flutter_i18n INFO]: YAML file loaded for en\n[flutter_i18n INFO]: Valid file: assets/i18n/en.yaml\n[flutter_i18n INFO]: JSON file loaded for it\n[flutter_i18n INFO]: Valid file: assets/i18n/it.json\n[flutter_i18n INFO]: XML file loaded for es\n[flutter_i18n INFO]: Valid file: assets/i18n/es.xml\n[flutter_i18n INFO]: JSON file loaded for common\n[flutter_i18n INFO]: Valid file: assets/i18n_namespace/en/common.json\n[flutter_i18n INFO]: YAML file loaded for home\n[flutter_i18n INFO]: Valid file: assets/i18n_namespace/en/home.yaml\n[flutter_i18n INFO]: JSON file loaded for common\n[flutter_i18n INFO]: Valid file: assets/i18n_namespace/ua/common.json\n[flutter_i18n INFO]: JSON file loaded for home\n[flutter_i18n INFO]: Valid file: assets/i18n_namespace/ua/home.json\n```\n\n#### Diff\n\nThis command is used to find the differences between the keys of the desired translation files.\n\n```sh\n\u003e flutter pub run flutter_i18n diff en.yaml it.json\n[flutter_i18n INFO]: [en.yaml, it.json]\n[flutter_i18n INFO]: YAML file loaded for en\n[flutter_i18n INFO]: JSON file loaded for it\n[flutter_i18n ERROR]: The compared dictionary doesn't contain the key \u003etitle\n```\n\n## Plugins\n\n| Plugin | Description |\n|---------|-------------|\n| [flutter_i18n_locize](https://github.com/defint/flutter_i18n_locize) | Easy integration locize.io to flutter_i18n. |\n\n## Do you like my work?\n\u003cp\u003e\n    \u003ca href=\"https://www.patreon.com/ilteoood\"\u003e\n        \u003cimg align=\"center\" alt=\"patreon\" src=\"https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dilteoood%26type%3Dpatrons\u0026style=for-the-badge\"\u003e\n        \u003c/img\u003e\n    \u003c/a\u003e\n    or\n    \u003ca href=\"https://www.buymeacoffee.com/ilteoood\"\u003e\n        \u003cimg align=\"center\" alt=\"buy-me-a-coffee\" src=\"https://img.shields.io/badge/-buy_me_a%C2%A0coffee-gray?logo=buy-me-a-coffee\"\u003e\n        \u003c/img\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/defint\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/1523848?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAnton\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#infra-defint\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e \u003ca href=\"https://github.com/ilteoood/flutter_i18n/commits?author=defint\" title=\"Tests\"\u003e⚠️\u003c/a\u003e \u003ca href=\"https://github.com/ilteoood/flutter_i18n/commits?author=defint\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://lucasvienna.dev\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/1761244?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eLucas Vienna\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/ilteoood/flutter_i18n/commits?author=Avyiel\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/jlcool\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/381375?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ejlcool\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/ilteoood/flutter_i18n/commits?author=jlcool\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/juumixx\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/5200179?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJulian\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/ilteoood/flutter_i18n/commits?author=juumixx\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#ideas-juumixx\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://andreygordeev.com\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/2883524?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndrey Gordeev\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/ilteoood/flutter_i18n/commits?author=agordeev\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/ilteoood/flutter_i18n/issues?q=author%3Aagordeev\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Amir-P\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/8766492?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAmir Panahandeh\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/ilteoood/flutter_i18n/issues?q=author%3AAmir-P\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e \u003ca href=\"https://github.com/ilteoood/flutter_i18n/commits?author=Amir-P\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filteoood%2Fflutter_i18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filteoood%2Fflutter_i18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filteoood%2Fflutter_i18n/lists"}