{"id":19722943,"url":"https://github.com/translation/lingui","last_synced_at":"2025-06-26T07:32:04.060Z","repository":{"id":57167506,"uuid":"346032767","full_name":"translation/lingui","owner":"translation","description":"React and JS translation made \u003cTrans\u003esimple\u003c/Trans\u003e with LinguiJS","archived":false,"fork":false,"pushed_at":"2025-01-27T13:13:42.000Z","size":68,"stargazers_count":12,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-15T12:05:35.864Z","etag":null,"topics":["i18n","internationalization","javascript","linguijs","localization","react","translation"],"latest_commit_sha":null,"homepage":"https://translation.io/lingui","language":null,"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/translation.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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,"zenodo":null}},"created_at":"2021-03-09T14:24:53.000Z","updated_at":"2025-04-02T10:38:25.000Z","dependencies_parsed_at":"2025-04-29T22:41:27.180Z","dependency_job_id":null,"html_url":"https://github.com/translation/lingui","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/translation/lingui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/translation%2Flingui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/translation%2Flingui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/translation%2Flingui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/translation%2Flingui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/translation","download_url":"https://codeload.github.com/translation/lingui/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/translation%2Flingui/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262022437,"owners_count":23246310,"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":["i18n","internationalization","javascript","linguijs","localization","react","translation"],"created_at":"2024-11-11T23:19:02.399Z","updated_at":"2025-06-26T07:32:04.039Z","avatar_url":"https://github.com/translation.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# [Translation.io](https://translation.io/lingui) client for React \u0026 JavaScript (using [Lingui](https://github.com/lingui/js-lingui))\n\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)\n\nAdd this package to localize your **React**, **React Native** or **JavaScript** application.\n\nUse this \u003ca href=\"#react-jsx-syntax\"\u003e`\u003cTrans\u003eReact syntax\u003c/Trans\u003e`\u003c/a\u003e\n or this \u003ca href=\"#javascript-syntax\"\u003e``t`JavaScript syntax` ``\u003c/a\u003e.\n\nWrite only the source text, and keep it synchronized with your translators on\n[Translation.io](https://translation.io/lingui).\n\n\u003ca href=\"https://translation.io/lingui\"\u003e\n  \u003cimg width=\"720px\" alt=\"Translation.io interface\" src=\"https://translation.io/gifs/translation.gif\"\u003e\n\u003c/a\u003e\n\n----------\n\n**Important Information:**\n\n* The [Translation.io](https://translation.io/lingui) client is directly integrated into\nthe [Lingui](https://github.com/lingui/js-lingui) i18n framework.\n\n* This repository provides additional documentation and a useful meta-package\nto simplify the installation of [Lingui](https://github.com/lingui/js-lingui).\nYou can refer directly to the [Lingui documentation](https://lingui.dev/) for more advanced Lingui features.\n\n----------\n\n * To use Lingui **v5**, you need to install  `@translation/lingui` **v 3.0.0** (latest)\n * To use Lingui **v4**, you need to install [`@translation/lingui` **v 2.0.0**](https://www.npmjs.com/package/@translation/lingui/v/2.0.0)\n\n----------\n\nNeed help? [contact@translation.io](mailto:contact@translation.io)\n\n## Table of contents\n\n * [Localization syntaxes](#localization-syntaxes)\n   * [React JSX Syntax](#react-jsx-syntax)\n   * [JavaScript Syntax](#javascript-syntax)\n * [Installation](#installation)\n * [Usage](#usage)\n   * [Sync](#sync)\n   * [Sync and Purge](#sync-and-purge)\n * [Manage Languages](#manage-languages)\n   * [Add or Remove Language](#add-or-remove-language)\n   * [Edit Language](#edit-language)\n   * [Custom Languages](#custom-languages)\n   * [Fallbacks](#fallbacks)\n * [Change the current locale](#change-the-current-locale)\n * [Dynamic loading of .JS translation catalogs](#dynamic-loading-of-js-translation-catalogs)\n * [List of clients for Translation.io](#list-of-clients-for-translationio)\n   * [Ruby on Rails (Ruby)](#ruby-on-rails-ruby)\n   * [Laravel (PHP)](#laravel-php)\n   * [React, React Native and JavaScript](#react-react-native-and-javascript)\n   * [Angular](#angular)\n   * [Others](#others)\n * [Contributing](#contributing)\n * [License](#license)\n\n## Localization syntaxes\n\n### React JSX Syntax\n\n#### Singular\n\n~~~javascript\nimport { Trans } from \"@lingui/react/macro\"\n~~~\n\n~~~jsx\n{/* Regular */}\n\u003cTrans\u003e\n  Text to be translated\n\u003c/Trans\u003e\n\n{/* Variable Interpolation */}\n\u003cTrans\u003e\n  Hello {name}\n\u003c/Trans\u003e\n\n{/* Comment for translators */}\n\u003cTrans comment=\"Acronym for Key Performance Indicator\"\u003e\n  View KPIs\n\u003c/Trans\u003e\n\n{/* Simple HTML Tags: translators will see \"Text with \u003c0\u003eHTML\u003c/0\u003e tags\" */}\n\u003cTrans\u003e\n  Text with \u003cem\u003eHTML\u003c/em\u003e tags\n\u003c/Trans\u003e\n\n{/* Complex HTML Tags: translators will see \"Text with a \u003c0\u003elink\u003c/0\u003e\" */}\n\u003cTrans\u003e\n  Text with a\n  \u003ca href=\"https://google.com\" target=\"_blank\"\u003elink\u003c/a\u003e\n\u003c/Trans\u003e\n\n{/* Context: to help translators and allow different translations for the same source text */}\n\u003cdiv\u003e\n  \u003cTrans context=\"romantic meeting with someone\"\u003e\n    Date\n  \u003c/Trans\u003e\n\n  \u003cTrans context=\"a moment in time\"\u003e\n    Date\n  \u003c/Trans\u003e\n\u003c/div\u003e\n\n{/* Explicit IDs: to have more control over the structure of your localization keys */}\n\u003cdiv\u003e\n  \u003cTrans id=\"index.header.title\"\u003e\n    Dashboard\n  \u003c/Trans\u003e\n\n  \u003cTrans id=\"modal.buttons.cancel\"\u003e\n    Cancel\n  \u003c/Trans\u003e\n\u003c/div\u003e\n~~~\n\nN.B. Attributes (`comment`, `context`, `id`) can be used together.\n\n#### Plural\n\n~~~javascript\nimport { Plural } from \"@lingui/react/macro\"\n~~~\n\n~~~jsx\n{/* Regular */}\n\u003cPlural\n  value={count}\n  one=\"You've got 1 message\"\n  other=\"You've got # messages\"\n/\u003e\n\n{/* Custom plural forms */}\n\u003cPlural\n  value={count}\n  _0=\"Your inbox is empty!\"\n  _42=\"You've found the ultimate answer\"\n  one=\"You've got 1 message\"\n  other=\"You've got # messages\"\n/\u003e\n\n{/* Variable interpolation */}\n\u003cPlural\n  value={count}\n  one={`Hello ${name}, you've got 1 message`}\n  other={`Hello ${name}, you've got # messages`}\n/\u003e\n\n{/* HTML tags */}\n\u003cPlural\n  value={count}\n  one={\u003cTrans\u003eYou've got \u003cstrong\u003e1\u003c/strong\u003e message\u003c/Trans\u003e}\n  other={\u003cTrans\u003eYou've got \u003cstrong\u003e#\u003c/strong\u003e messages\u003c/Trans\u003e}\n/\u003e\n~~~\n\n**Note:** English has only 2 plural forms (`one` and `other`), but other languages\nhave more of them, from this list: `zero`, `one`, `two`, `few`, `many`,\n`other`.\n\nOn Translation.io, your translators will see the correct list of plural forms directly\nin the interface, with examples in their target language:\n\n\u003ca href=\"https://translation.io/lingui\"\u003e\n  \u003cimg width=\"500px\" alt=\"Translation.io plural management\" src=\"https://translation.io/gifs/lingui/translation-plural-forms.png\"\u003e\n\u003c/a\u003e\n\nYou can find the complete list of plural forms and plural rules here:\n[available languages and plural forms](https://translation.io/docs/languages_with_plural_cases)\n\n### JavaScript Syntax\n\n#### Singular\n\n~~~javascript\nimport { t } from \"@lingui/core/macro\"\n~~~\n\n~~~javascript\n// Regular\nt`Text to be translated`\n\n// Variable Interpolation\nt`Hello ${name}`\n\n// Comment for translators\nt({\n  comment: \"Acronym for Key Performance Indicator\",\n  message: \"View KPIs\"\n})\n\n{/* Context: to help translators and allow different translations for the same source text */}\nt({\n  context: \"romantic meeting with someone\",\n  message: \"Date\"\n})\n\nt({\n  context: \"a moment in time\",\n  message: \"Date\"\n})\n\n{/* Explicit IDs: to have more control over the structure of your localization keys */}\nt({\n  id: \"index.header.title\",\n  message: \"Dashboard\"\n})\n\nt({\n  id: \"modal.buttons.cancel\",\n  message: \"Cancel\"\n})\n~~~\n\n#### Plural\n\n~~~javascript\nimport { plural } from \"@lingui/core/macro\"\n~~~\n\n~~~javascript\n// Regular\nplural(count, {\n  one: \"You've got 1 message\",\n  other: \"You've got # messages\"\n})\n\n// Custom plural forms\nplural(count, {\n  _0: \"Your inbox is empty!\",\n  _42: \"You've found the ultimate answer\",\n  one: \"You've got 1 message\",\n  other: \"You've got # messages\"\n})\n\n// Variable interpolation\nplural(count, {\n  one: `Hello ${name}, you've got 1 message`,\n  other: `Hello ${name}, you've got # messages`\n})\n~~~\n\n**Note:** English has only 2 plural forms (`one` and `other`) but other languages\nhave more of them, from this list: `zero`, `one`, `two`, `few`, `many`,\n`other`.\n\nTranslators will have the correct list of plural forms proposed directly\nin the interface, with examples in their target language:\n\n\u003ca href=\"https://translation.io/lingui\"\u003e\n  \u003cimg width=\"500px\" alt=\"Translation.io plural management\" src=\"https://translation.io/gifs/lingui/translation-plural-forms.png\"\u003e\n\u003c/a\u003e\n\nYou can find the complete list of plural forms and plural rules here:\nhttps://translation.io/docs/languages_with_plural_cases\n\n## Installation\n\n### 1. Install the package\n\n#### Solution 1: Meta-package\n\nQuick way to install Lingui with the correct dependencies.\n\n~~~bash\n# NPM\nnpm install @translation/lingui\n\n# Yarn\nyarn add @translation/lingui\n~~~\n\n#### Solution 2: Fine-Grained Install\n\nMore complex but cleaner install, with some packages in development only.\n\n~~~bash\n# NPM\nnpm install --save-dev @lingui/cli\nnpm install --save-dev @lingui/babel-plugin-lingui-macro\nnpm install @lingui/react\n~~~\n\n~~~bash\n# Yarn\nyarn add --dev @lingui/cli\nyarn add --dev @lingui/babel-plugin-lingui-macro\nyarn add @lingui/react\n~~~\n\n### 2. Add the following scripts\n\nAdd these lines to your `package.json` to make your life easier.\n\n~~~json\n{\n  \"scripts\": {\n    \"sync\": \"lingui extract --overwrite \u0026\u0026 lingui compile\",\n    \"sync_and_purge\": \"lingui extract --overwrite --clean \u0026\u0026 lingui compile\"\n  }\n}\n~~~\n\n### 3. Create a new translation project\n\nCreate your new project [from the UI](https://translation.io/lingui) and select\nthe correct source and target languages.\n\n### 4. Configure your project\n\nCopy the `.linguirc` configuration file that was generated for you to the\nroot of your application.\n\nThe configuration file looks like this:\n\n~~~json\n{\n  \"locales\": [\"en\", \"fr\", \"nl\", \"de\", \"es\"],\n  \"sourceLocale\": \"en\",\n  \"catalogs\": [{\n    \"path\": \"src/locales/{locale}/messages\",\n    \"include\": [\"src\"]\n  }],\n  \"format\": \"po\",\n  \"service\": {\n    \"name\": \"TranslationIO\",\n    \"apiKey\": \"abcdefghijklmnopqrstuvwxyz012345\"\n  }\n}\n~~~\n\n### 5. Setup your application\n\nFor React (cf. [React Documentation](https://lingui.dev/tutorials/react) or [React Native documentation](https://lingui.dev/tutorials/react-native)):\n\n~~~jsx\nimport { i18n } from '@lingui/core'\nimport { I18nProvider } from '@lingui/react'\nimport { messages } from './locales/en/messages' // English catalog of translations\nimport Inbox from './Inbox'\n\ni18n.load('en', messages)\ni18n.activate('en')\n\nconst App = () =\u003e (\n  \u003cI18nProvider i18n={i18n}\u003e\n    \u003cInbox /\u003e\n  \u003c/I18nProvider\u003e\n)\n~~~\n\nFor JavaScript (cf. [documentation](https://lingui.dev/tutorials/javascript)):\n\n~~~javascript\nimport { i18n } from '@lingui/core'\nimport { messages } from './locales/en/messages' // English catalog of translations\n\ni18n.load('en', messages)\ni18n.activate('en')\n~~~\n\n### 6. Localize your code\n\nLocalize your app using the \u003ca href=\"#react-jsx-syntax\"\u003e`\u003cTrans\u003eReact syntax\u003c/Trans\u003e`\u003c/a\u003e\nor the \u003ca href=\"#javascript-syntax\"\u003e``t`JavaScript syntax` ``\u003c/a\u003e.\n\n### 7. Initialize your project\n\nRun the following commands to push your source keys and \nexisting translations to Translation.io:\n\n~~~bash\n# NPM\nnpm run sync\n\n# Yarn\nyarn sync\n~~~\n\nIf you need to add or remove languages in the future, please read\n[this section](#add-or-remove-language) about that.\n\n## Usage\n\n### Sync\n\nTo send new translatable strings and get new translations from Translation.io,\nand at the same time generate the minified Javascript catalog files, simply run:\n\n~~~bash\n# NPM\nnpm run sync\n\n# Yarn\nyarn sync\n~~~\n\n### Sync and Purge\n\nIf you need to remove unused strings from Translation.io, using\nthe current branch as reference, use the `--clean` option.\n\n~~~bash\n# NPM\nnpm run sync_and_purge\n\n# Yarn\nyarn sync_and_purge\n~~~\n\nAs the name says, this operation will also perform a sync at the same time.\n\n**Warning:** all strings that are not present in the current local branch will be\n**permanently deleted from Translation.io**.\n\n## Manage Languages\n\n### Add or Remove Language\n\nYou can add or remove a language by updating `\"locales\": []` in your\n`.linguirc` file, and syncing your project again.\n\nIf you want to add a new language with existing translations (ex. if you already have\na translated PO file in your project), you will need to create a\nnew empty project on Translation.io and init it for the first time again.\n\n### Edit Language\n\nTo edit existing languages while keeping their translations (e.g. changing from `en` to `en-US`).\n\n 1. Create a new project on Translation.io with the correct languages.\n 2. Adapt `.linguirc` (new API key and languages)\n 3. Adapt the language code in the PO directory structure, and also the language header in PO files.\n 4. Sync your project for the first time and check that everything went fine.\n 5. Invite your collaborators in the new project.\n 6. Remove the old project.\n\nSince you created a new project, the translation history and tags will unfortunately be lost.\n\n### Custom Languages\n\nCustom languages are convenient if you want to customize translations for a specific customer\nor another instance of your application.\n\nA custom language is always be derived from an [existing language](https://translation.io/docs/languages).\nIts structure should be like:\n\n~~~javascript\n`${existingLanguageCode}-${customText}`\n~~~\n\nwhere `customText` can only contain alphabetic characters and `-`.\n\nExamples: `en-microsoft` or `fr-BE-custom`.\n\n### Fallbacks\n\nLanguage fallbacks will work as expected for any regional or custom\nlanguage. It means that if the `en-GB` translation is missing,\nthen it will fallback to `en`. So you only need to translate keys that\nare different from the main language when you specialize a language.\n\nNote that fallbacks are chained, so `en-US-custom` will fallback to `en-US` that will\nfallback to `en`.\n\nYou can find more information about Lingui fallback configuration\n[here](https://lingui.dev/ref/conf#fallbacklocales).\n\n## Change the current locale\n\nYou can change the current locale by using:\n\n~~~javascript\nimport { i18n } from '@lingui/core'\nimport { messages } from './locales/en/messages.js'\n\n// [...]\ni18n.load('en', messages)\ni18n.activate('en')\n~~~\n\nYou may be able to detect the default locale of the user, based on many things\nlike navigator meta tags, HTML language tag, subdomain, path, cookie, etc.\n\nThe easiest way to do that would be to use the small\n[`@lingui/detect-locale`](https://lingui.dev/ref/locale-detector) package.\n\n~~~javascript\nimport { detect, fromUrl, fromStorage, fromNavigator } from \"@lingui/detect-locale\"\n\n// can be a function with custom logic or just a string, `detect` method will handle it\nconst DEFAULT_FALLBACK = () =\u003e \"en\"\n\nconst result = detect(\n  fromUrl(\"lang\"),\n  fromStorage(\"lang\"),\n  fromNavigator(),\n  DEFAULT_FALLBACK\n)\n\nconsole.log(result) // \"en\"\n~~~\n\nYou will find more information about this package\n[here](https://lingui.dev/ref/locale-detector)\n\n## Dynamic loading of .JS translation catalogs\n\nIt’s your responsibility to load the correct translation catalog based on the active locale.\n\nThere is a clean [dynamic loader helper](https://lingui.dev/guides/dynamic-loading-catalogs)\nthat will assist you with this task.\n\n~~~typescript\n// i18n.ts\n\nimport { i18n } from '@lingui/core';\n\nexport const locales = {\n  en: \"English\",\n  cs: \"Česky\",\n};\nexport const defaultLocale = \"en\";\n\n/**\n* We do a dynamic import of just the catalog that we need\n* @param locale any locale string\n*/\nexport async function dynamicActivate(locale: string) {\n  const { messages } = await import(`./locales/${locale}/messages`)\n  i18n.load(locale, messages)\n  i18n.activate(locale)\n}\n~~~\n\nPlease read more about this loader [here](https://lingui.dev/guides/dynamic-loading-catalogs).\n\n## List of clients for Translation.io\n\nThe following clients are officially supported by [Translation.io](https://translation.io)\nand are well documented.\n\nSome of these implementations (and other non-officially supported ones)\nwere started by contributors for their own translation projects.\nWe are thankful to all contributors for their hard work!\n\n### Ruby on Rails (Ruby)\n\nOfficially supported on [https://translation.io/rails](https://translation.io/rails)\n\n * GitHub: https://github.com/translation/rails\n * RubyGems: https://rubygems.org/gems/translation/\n\nCredits: [@aurels](https://github.com/aurels), [@michaelhoste](https://github.com/michaelhoste)\n\n### Laravel (PHP)\n\nOfficially supported on [https://translation.io/laravel](https://translation.io/laravel)\n\n * GitHub: https://github.com/translation/laravel\n * Packagist: https://packagist.org/packages/tio/laravel\n\nCredits: [@armandsar](https://github.com/armandsar), [@michaelhoste](https://github.com/michaelhoste)\n\n### React, React Native and JavaScript\n\nOfficially supported on [https://translation.io/lingui](https://translation.io/lingui)\n\nTranslation.io is directly integrated in the great\n[Lingui](https://lingui.dev/) internationalization project.\n\n * GitHub: https://github.com/translation/lingui\n * NPM: https://www.npmjs.com/package/@translation/lingui\n\n### Angular\n\nOfficially supported on [https://translation.io/angular](https://translation.io/angular)\n\n * GitHub: https://github.com/translation/angular\n * NPM: https://www.npmjs.com/package/@translation/angular\n \nCredits: [@SimonCorellia](https://github.com/SimonCorellia), [@didier-84](https://github.com/didier-84), [@michaelhoste](https://github.com/michaelhoste)\n\n### Others\n\nIf you want to create a new client for your favorite language or framework, please read our\n[Create a Translation.io Library](https://translation.io/docs/create-library)\nguide and use the special\n[init](https://translation.io/docs/create-library#initialization) and\n[sync](https://translation.io/docs/create-library#synchronization) endpoints.\n\nYou can also use the more [traditional API](https://translation.io/docs/api).\n\nFeel free to contact us on [contact@translation.io](mailto:contact@translation.io)\nif you need some help or if you want to share your library.\n\n## Contributing\n\nThis is a dumb meta-package that doesn't need any contribution.\n\nIf you want to contribute, please refer to\n[the official Lingui CONTRIBUTING.md](https://github.com/lingui/js-lingui/blob/main/CONTRIBUTING.md)\nfile.\n\n## License\n\nThis meta-package is released under MIT license.\n\nThe Lingui MIT License is located here [here](https://github.com/lingui/js-lingui/blob/main/LICENSE)\n\n(c) [https://translation.io](https://translation.io) / [contact@translation.io](mailto:contact@translation.io)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftranslation%2Flingui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftranslation%2Flingui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftranslation%2Flingui/lists"}