{"id":22355430,"url":"https://github.com/owja/i18n","last_synced_at":"2025-07-30T10:31:42.289Z","repository":{"id":57134617,"uuid":"188584690","full_name":"owja/i18n","owner":"owja","description":":fish: lightweight (\u003c1kb) internationalization library written in typescript","archived":false,"fork":false,"pushed_at":"2021-05-27T11:22:09.000Z","size":1400,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-03T14:20:06.421Z","etag":null,"topics":["i18n","internationalization","javascript","language","library","translation","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/owja.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-25T15:47:33.000Z","updated_at":"2022-11-30T03:01:30.000Z","dependencies_parsed_at":"2022-09-04T09:52:18.641Z","dependency_job_id":null,"html_url":"https://github.com/owja/i18n","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owja%2Fi18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owja%2Fi18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owja%2Fi18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owja%2Fi18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/owja","download_url":"https://codeload.github.com/owja/i18n/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227965658,"owners_count":17848465,"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","language","library","translation","typescript"],"created_at":"2024-12-04T14:06:30.634Z","updated_at":"2024-12-04T14:06:31.297Z","avatar_url":"https://github.com/owja.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![OWJA! i18n](resources/owja-i18n-logo.png)\n\n[![npm version](https://img.shields.io/npm/v/@owja/i18n.svg)](https://badge.fury.io/js/%40owja%2Fi18n)\n[![codecov](https://codecov.io/gh/owja/i18n/branch/master/graph/badge.svg)](https://codecov.io/gh/owja/i18n)\n[![Build Status](https://travis-ci.org/owja/i18n.svg?branch=master)](https://travis-ci.org/owja/i18n)\n[![size](https://img.badgesize.io/https://unpkg.com/@owja/i18n/index.module.js.svg?compression=brotli\u0026label=size)](https://unpkg.com/@owja/i18n/index.module.js)\n\nThis is a lightweight internationalization library which is in early **alpha** state. This means it is\nwork in progress, unstable, can contain bugs and the API can change until first stable release.\n\n### Features\n\n* lightweight bundle size **~1 kb** (brotli compressed, without plugins)\n* no global state\n* it is made with dependency injection in mind\n* Build-in support for plurals, interpolation and context\n* uses Intl.Locale and Intl.PluralRules under the hood\n* Extendable with plugins\n\n##### What does it not have and why?\n\n* No loading mechanism. Nowadays we have dynamic imports and fetch and both can do this\njob perfectly\n* No namespaces. You can add translations while runtime without the need for namespaces\nIf you want some kind of namespaces you can use multidimensional objects\n* No nesting. Could be implemented with a plugin\n* No objects, no arrays\n* No formatting. Could be implemented with a plugin\n\n### Extendability (Plugins)\n\nThere will be a few plugins on stable release. Planed are:\n\n* **[done]** Datetime Formatter, like `[[date|1558819424|short]]` to `05/25`\n* **[done]** Currency Formatter, like `[[cur|2.323122]]` to `€ 2,32`\n* **[done]** Number Formatter, like `[[number|2.323122|2]]` to `2,32`\n* **[todo]** Html2Char Converter, for some useful codes like `\u0026shy;` to `0x00AD`\n\nThe reason why this functionality isn't included in the main bundle is that in\nmany cases they are not needed, or you need only one or two and not all.\n\n### Usage\n\n##### Step 1 - Creating an instance of the Translator \n\n```typescript\nimport {Translator} from \"@owja/i18n\";\nconst translator = new Translator({default:\"de\",fallback:\"en\"});\n```\nIf you use a [dependency injection tool](https://github.com/owja/ioc), you can bind the `.t()` method of the `translator` constant \nto make accessing the main functionality as easy as possible.\n\n##### Step 2 - Importing Translations\n\na) Adding with static imports\n```typescript\nimport de from \"lang/de.json\";\nimport en from \"lang/de.json\";\n\ntranslator.addResource(\"de\", de);\ntranslator.addResource(\"en\", en);\n```\n\nb) Adding with dynamic imports\n```typescript\nimport(\"lang/de.json\").then((m) =\u003e translator.addResource(\"de\", m.default));\nimport(\"lang/en.json\").then((m) =\u003e translator.addResource(\"en\", m.default));\n```\n\nc) Adding with fetch\n```typescript\nfetch(\"lang/de.json\").then(r =\u003e r.json())\n    .then((r) =\u003e translator.addResource(\"de\", r));\n    \nfetch(\"lang/en.json\").then(r =\u003e r.json())\n    .then((r) =\u003e translator.addResource(\"en\", r));\n```\n\n##### Step 3 - Translate something\n\n*lang/de.json*\n```json\n{\n  \"hello\": \"Hallo Welt\",\n  \"car\": \"Auto\",\n  \"car_other\": \"Autos\",\n  \"employee_male_0\": \"Kein Mitarbeiter\",\n  \"employee_male_one\": \"Der Mitarbeiter\",\n  \"employee_male_other\": \"Die Mitarbeiter\",\n  \"employee_female_0\": \"Keine Mitarbeiterinnen\",\n  \"employee_female_one\": \"Die Mitarbeiterin\",\n  \"employee_female_other\": \"Die Mitarbeiterinnen\",\n  \"dashboard\": {\n    \"button\": \"Ok\"\n  },\n  \"contact\": {\n    \"button\": \"Senden\"\n  }\n}\n```\n\n```typescript\ntranslate.t(\"hello\"); // output: \"Hallo Welt\"\ntranslate.t(\"car\", {count: 2}); // output: \"Autos\"\ntranslate.t(\"car\", {count: 1}); // output: \"Auto\"\ntranslate.t(\"employee\", {count: 0, context: \"male\"}); // output: \"Kein Mitarbeiter\"\ntranslate.t(\"employee\", {count: 1, context: \"male\"}); // output: \"Der Mitarbeiter\"\ntranslate.t(\"employee\", {count: 2, context: \"male\"}); // output: \"Die Mitarbeiter\"\ntranslate.t(\"employee\", {count: 0, context: \"female\"}); // output: \"Keine Mitarbeiterinnen\"\ntranslate.t(\"employee\", {count: 1, context: \"female\"}); // output: \"Die Mitarbeiterin\"\ntranslate.t(\"employee\", {count: 2, context: \"female\"}); // output: \"Die Mitarbeiterinnen\"\ntranslate.t(\"dashboard.button\"}); // output: \"Ok\"\ntranslate.t(\"contact.button\"}); // output: \"Senden\"\n```\n\n`Intl.PluralRules` is used under the hood to get the rule for the current set locale.\n\nFor example this is in german and english:\n\n* **-1** is `one`\n* **1** is `one`\n* **everything else** is `other`\n\n...and in arabic:\n\n* **less than -10** is `many`\n* **-3 to -10** is `few`\n* **-2** is `two`\n* **-1** is `one`\n* **0** is `zero`\n* **1** is `one`\n* **2** is `two`\n* **3 to 10** is `few`\n* **greater than 10** is `many`\n\n##### Setting the Language and Listening\n\nSetting the language:\n```typescript\ntranslate.locale(\"de\");                          // sets only the language and is guessing the region which will result in DE in this case\ntranslate.locale(\"de-DE\");                       // sets language and region\ntranslate.locale(new Intl.Locale(\"de-DE\"));      // sets language and region too\ntranslate.locale(\"zh-Hant-HK\");                  // sets language, script and region\ntranslate.locale(new Intl.Locale(\"zh-Hant-HK\")); // sets language, script and region too\n```\nGetting the language:\n```typescript\ntranslate.short();   // short locale (language) like \"en\" or like \"zh-Hant\" if script was set\ntranslate.long();    // long locale like \"en-GB\" or like \"zh-Hant-HK\" if script was set\ntranslate.script();  // long script like \"Hant\" if script was set else it returns undefined\ntranslate.region();  // region of the current locale like \"DE\" if \"de\" or \"de-DE\" was set\n```\n\nListening to language change and unsubscribe:\n```typescript\n// subscribe\nconst unsubscribe = translate.listen(() =\u003e alert(\"language was changed\"));\n\n// and this will unsubscribe the listener\nunsubscribe();\n```\n\u003e Note: The callback will get triggered on some other changes too,\nlike new translation resources or plugins got added.\n\n### Inspiration\n\nThis library is made with inspiration of the well known [i18next](https://github.com/i18next/i18next) framework.\n\n### License\n\n**MIT**\n\nCopyright © 2019 - 2020 Hauke Broer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowja%2Fi18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fowja%2Fi18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowja%2Fi18n/lists"}