{"id":13746033,"url":"https://github.com/DoneDeal0/Talkr","last_synced_at":"2025-05-09T06:31:19.411Z","repository":{"id":43840533,"uuid":"304145636","full_name":"DoneDeal0/Talkr","owner":"DoneDeal0","description":"Talkr is the lightest i18n provider for React applications. It supports Typescript, provides autocompletion, has 0 dependencies, and is very easy to use.","archived":false,"fork":false,"pushed_at":"2024-09-29T09:14:35.000Z","size":432,"stargazers_count":252,"open_issues_count":0,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-08T20:19:23.736Z","etag":null,"topics":["i18n","react","react-context","reactjs","translation","translations"],"latest_commit_sha":null,"homepage":"https://talkr-documentation.netlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DoneDeal0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"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":{"github":["DoneDeal0"]}},"created_at":"2020-10-14T22:01:59.000Z","updated_at":"2025-02-11T09:54:21.000Z","dependencies_parsed_at":"2024-06-19T17:38:21.800Z","dependency_job_id":"93976b40-f919-4b26-86c7-8ae00266b850","html_url":"https://github.com/DoneDeal0/Talkr","commit_stats":{"total_commits":48,"total_committers":5,"mean_commits":9.6,"dds":"0.41666666666666663","last_synced_commit":"0e59998e6f7c0efd91e3914844dac49728ebe3e6"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoneDeal0%2FTalkr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoneDeal0%2FTalkr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoneDeal0%2FTalkr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoneDeal0%2FTalkr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DoneDeal0","download_url":"https://codeload.github.com/DoneDeal0/Talkr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253206067,"owners_count":21871158,"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","react","react-context","reactjs","translation","translations"],"created_at":"2024-08-03T06:00:43.605Z","updated_at":"2025-05-09T06:31:19.015Z","avatar_url":"https://github.com/DoneDeal0.png","language":"TypeScript","readme":"\u003cimg width=\"1015\" alt=\"Capture d’écran 2024-05-20 à 17 19 54\" src=\"https://github.com/DoneDeal0/Talkr/assets/43271780/55fb8790-13ee-4273-a113-8cc5478912da\"\u003e\u003c/img\u003e\n\n\u003chr/\u003e\n\n# TALKR\n\n**Talkr** is the lightest i18n provider for React applications. It supports **Typescript**, provides **autocompletion**, has **0 dependencies**, and is very easy to use.\n\n[![CI](https://github.com/DoneDeal0/Talkr/actions/workflows/ci.yml/badge.svg)](https://github.com/DoneDeal0/Talkr/actions/workflows/ci.yml)\n[![CD](https://github.com/DoneDeal0/Talkr/actions/workflows/cd.yml/badge.svg)](https://github.com/DoneDeal0/Talkr/actions/workflows/cd.yml)\n![NPM Downloads](https://img.shields.io/npm/dy/talkr?logo=npm)\n\n\u003chr/\u003e\n\n### FEATURES\n\n- Auto-detect browser language\n- Auto-detect plural rules based on any language\n- Dynamic translations with multiple keys\n- Access deeply nested keys in json translations files\n- Adapts syntax to gender\n- Supports lists\n- Supports React Native\n- Provides typescript autocompletion for your keys \n\n\n\u003chr/\u003e\n  \n### SCREENSHOT\n\n\u003cimg width=\"588\" alt=\"talkr autocomplete in action\" src=\"https://user-images.githubusercontent.com/43271780/154273252-f0818de8-66d1-4265-9e6f-bebe5bd8b73f.png\"\u003e\u003c/img\u003e\n\n\u003chr/\u003e\n\n## INSTALLATION\n\n```bash\n// with npm\nnpm install talkr\n// with yarn\nyarn add talkr\n```\n\n\u003chr/\u003e\n\n# ADD TRANSLATION FILES\n\n- Create your JSON translation files.\n- Surround dynamic values by double underscores: `__dynamicValue__`.\n- To allow automatic plural detection, you will need to pass a `count` parameter to **Talkr**'s translation function. **Talkr** will then chose the right word or sentence between `zero`, `one`, `two`, `few` and `many`.\n\n\u003e 🤓: Some languages have more complex plural rules, that may require these five options to offer a perfect user experience. For instance, Arabic handle `zero`, `one`, `two`, `numbers between 3 and 10` and `numbers over 10` as separate entities. If a language doesn't need all these subtleties - like english - you can only write `zero`, `one` and `many` in the JSON file.\n\n```json\n{\n  \"hello\": \"hello\",\n  \"feedback\": {\n    \"error\": \"The connection failed\",\n    \"success\": \"The connection succedeed\"\n  },\n  \"user\": {\n    \"describe\": {\n      \"simple\": \"You are __name__\",\n      \"complex\": \"You are __name__ and you like __hobby__\"\n    }\n  },\n  \"idiom\": {\n    \"sovereign\": {\n      \"female\": \"Long live the Queen!\",\n      \"male\": \"Long live the King!\"\n    }\n  },\n  \"message-count\": {\n    \"zero\": \"you don't have new messages\",\n    \"one\": \"you have 1 message\",\n    \"many\": \"you have __count__ messages\"\n  },\n  \"days\": [\"Monday\", \"Tuesday\", \"Wednesday\"],\n}\n```\n\n\u003chr/\u003e\n\n# SET UP\n\n- In your index file, import your JSON translations\n- Wrap your App with **Talkr**'s `Provider`\n- Pass it your available `languages` and your `defaultLanguage`.\n- You also have the option to let **Talkr** detect browser's language with the prop `detectBrowserLanguage` (see [props](#Available props)).\n\n```javascript\nimport * as React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { Talkr } from \"talkr\";\nimport App from \"./app\";\nimport en from \"./i18n/en.json\";\nimport fr from \"./i18n/fr.json\";\n\nconst root = createRoot(document.getElementById(\"root\"));\n\nroot.render(\n  \u003cTalkr languages={{ en, fr }} defaultLanguage=\"en\"\u003e\n    \u003cApp /\u003e\n  \u003c/Talkr\u003e,\n);\n```\n\n\u003chr/\u003e\n\n# SIMPLE USAGE\n\n- In any component, import **Talker**'s hook `useT`.\n- Destructure the translation function `T` from `useT`\n- Fetch the desired sentence as if you were directly accessing an object, by adding `.` between each key. Based on the JSON example [above](add-translation-files), we could print the sentence `The connection succedeed` by simply writing `T(\"feedback.success\")`\n\n```javascript\nimport React from \"react\";\nimport { useT } from \"talkr\";\n\nexport default function MyComponent() {\n  const { T } = useT();\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{T(\"hello\")}\u003c/h1\u003e\n      \u003cdiv\u003e{T(\"feedback.success\")}\u003c/div\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003chr/\u003e\n\n# DYNAMIC VALUES\n\n- To handle dynamic translations, just add an object with all necessary dynamic values\n- To make it work, you need to surround the dynamic values by double underscores in your [JSON files](Add translation files) (`__dynamicValue__`)\n\n```json\n\"user\": {\n    \"describe\": {\n      \"simple\": \"You are __name__\",\n      \"complex\": \"You are __name__ and you like __hobby__\"\n    }\n  }\n```\n\n```javascript\nimport React from \"react\";\nimport { useT } from \"talkr\";\n\nexport default function MyComponent() {\n  const { T } = useT();\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{T(\"user.describe.complex\", { name: \"joe\", hobby: \"coding\" })}\u003c/h1\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003chr/\u003e\n\n# PLURAL\n\n- To handle plural, just add a `count` property to the object\n- To make it work, you need to provide both `zero`, `one` and `many` values to your JSON files.\n\n```json\n\"message-count\": {\n    \"zero\": \"you don't have new messages\",\n    \"one\": \"you have 1 message\",\n    \"many\": \"you have __count__ messages\"\n  }\n```\n\n```javascript\nimport React, { useState } from \"react\";\nimport { useT } from \"talkr\";\n\nexport default function MyComponent() {\n  const { T } = useT();\n  const [count, setCount] = useState(0);\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{T(\"message-count\", { count })}\u003c/h1\u003e\n      \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e+1\u003c/button\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003chr/\u003e\n\n# GENDER\n\n- Some languages have different syntax for masculine and feminine genders.\n- To adapt your sentence accordingly, just pass the param `gender: m` for `male`, or `gender: f` for `female`.\n- To make it work, you need to provide both `male` and `female` values to your JSON files.\n\n```json\n\"idiom\": {\n    \"sovereign\": {\n      \"female\": \"Long live the Queen!\",\n      \"male\": \"Long live the King!\"\n    }\n  }\n```\n\n```javascript\nimport React from \"react\";\nimport { useT } from \"talkr\";\n\nexport default function MyComponent() {\n  const { T } = useT();\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{T(\"idiom.sovereign\", { gender: \"m\" })}\u003c/h1\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n# LIST\n\n- You can render a list of string\n- The last junction can be styled thanks to the following parameters:\n\n```ts\n  listType?: \"conjunction\" | \"disjunction\"; // \"\"conjunction\" by default\n  listStyle?: \"long\" | \"narrow\"; // \"narrow\" by default\n```\n\n```json\n  \"days\": [\"Monday\", \"Tuesday\", \"Wednesday\"],\n```\n\n```javascript\nimport React from \"react\";\nimport { useT } from \"talkr\";\n\nexport default function MyComponent() {\n  const { T } = useT();\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{T(\"days\", { listType: \"conjunction\" })}\u003c/h1\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003chr/\u003e\n\n# LOCALE\n\n- Access and update the locale by using the hook `useT()`\n- If the provided locale doesn't match any JSON translation files, **Talkr** will use the `defaultLanguage` sent to the provider.\n\n```javascript\nimport React, { useState } from \"react\";\nimport { useT } from \"talkr\";\n\nexport default function MyComponent() {\n  const { T, setLocale, locale } = useT();\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{T(\"hello\")}\u003c/h1\u003e\n      \u003cp\u003e{locale}\u003c/p\u003e\n      \u003cbutton onClick={() =\u003e setLocale(\"fr\")}\u003espeak french\u003c/button\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003chr/\u003e\n\n\u003ca name='autocomplete'\u003e\u003c/a\u003e\n\n# AUTOCOMPLETION\n\nAutocompletion for translation keys is available in Typescript projects. Because json must be parsed at **compile time**, you will need to create your own `useAutocompleteT` hook with **Talkr**'s `Autocomplete` type wrapper.\n\nHere's how to do it:\n\n- Make sure you use `Typescript \u003e=4.5.5` (we don't guarantee it will work on older versions)\n- Create a `translate.tsx` file anywhere in your app(`translate.tsx` can be named as you want)\n- Import your main language JSON translation (ex: `en.json`)\n- Instantiate autocompletion with **Talkr's** `Autocomplete`\n- Export a `useAutocompleteT` hook around **Talkr**'s `useT()`\n\n```javascript\nimport { useT, Autocomplete, TParams, tr } from \"talkr\";\nimport en from \"./en.json\";\n\ntype Key = Autocomplete\u003ctypeof en\u003e;\n\nexport const useAutocompleteT = () =\u003e {\n  const { locale, languages, defaultLanguage } = useT();\n  return {\n    T: (key: Key, params?: TParams) =\u003e\n      tr({ locale, languages, defaultLanguage }, key, params),\n  };\n};\n```\n\nIf you prefer to keep the `useT` naming, just write:\n\n```js\nimport { useT as useTr, Autocomplete, TParams, tr } from \"talkr\";\nimport en from \"./en.json\";\n\ntype Key = Autocomplete\u003ctypeof en\u003e;\n\nexport const useT = () =\u003e {\n  const { locale, languages, defaultLanguage } = useTr();\n  return {\n    T: (key: Key, params?: TParams) =\u003e\n      tr({ locale, languages, defaultLanguage }, key, params),\n  };\n};\n```\n\n# Autocomplete usage\n\nYou now have the choice between using your own `useAutocompleteT` hook - which provides real-time autocompletion - or using **Talkr**'s `useT` - which doesn't provide autocompletion - in your app.\n\n```js\nimport { useAutocompleteT } from \"./translate\";\n\nfunction App() {\n  const { T } = useAutocompleteT();\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{T(\"feedback.success\")}\u003c/h1\u003e\n      \u003ch4\u003e{T(\"user.describe.complex\", { name: \"joe\", hobby: \"coding\" })}\u003c/h4\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003e 🤓 Pro-tip: since you will need to import `useAutocompleteT` from `translate.tsx`, it is highly recommended to add an alias `translate` to your builder's config and `tsconfig.json`.\n\nThis will allow you to write\n\n```js\nimport { useAutocompleteT } from \"translate\" 👍\n```\n\ninstead of\n\n```js\nimport { useAutocompleteT } from \"../../translate\" 👎\n```\n\n\u003e **Exemples:**\n\u003e webpack\n\u003e\n\u003e ```\n\u003e resolve: {\n\u003e   extensions: [\".ts\", \".tsx\", \".js\", \"jsx\", \".json\"],\n\u003e   alias: {\n\u003e       translate: path.resolve(__dirname, \"src/translate/\"),\n\u003e  }\n\u003e ```\n\u003e\n\u003e tsconfig\n\u003e\n\u003e ```\n\u003e { \"compilerOptions\": {\n\u003e   \"paths\": {\n\u003e   \"translate/*\": [\"src/translate/*\"]\n\u003e   }\n\u003e }}\n\u003e ```\n\u003e\n\u003e for other bundlers, please refer to their respective documentations.\n\n\u003chr/\u003e\n\n# REACT NATIVE\n\n- Add your provider directly in App.(js|tsx)\n\n```javascript\nimport { StyleSheet, Text, View } from \"react-native\";\nimport { Talkr } from \"talkr\";\nimport en from \"./src/i18n/en.json\";\nimport fr from \"./src/i18n/fr.json\";\nimport MyComponent from \"./src/MyComponent\";\n\nexport default function App() {\n  return (\n    \u003cTalkr languages={{ en, fr }} defaultLanguage=\"en\"\u003e\n      \u003cView style={styles.container}\u003e\n        \u003cMyComponent /\u003e\n      \u003c/View\u003e\n    \u003c/Talkr\u003e\n  );\n}\n```\n\n- All the exemples above are valid in React Native. You only have to replace html tags (`div`, `h1`, etc.) by `Text`.\n- Since `Intl` api is not available in React Native, the `count` param will only return three types of plural keys: `zero`, `one` and `many`. Please adjust your json files accordingly.\n\n```javascript\nimport React, { Text, Button } from \"react-native\";\nimport { useState } from \"react\";\nimport { useT } from \"talkr\";\n\nexport default function MyComponent() {\n  const { T } = useT();\n  const [count, setCount] = useState(0);\n\n  return (\n    \u003c\u003e\n      \u003cText\u003e{T(\"hello\")}\u003c/Text\u003e\n      \u003cText\u003e\n        {T(\"user.describe.complex\", { name: \"joe\", hobby: \"coding\" })}\n      \u003c/Text\u003e\n      \u003cText\u003e{T(\"message-count\", { count })}\u003c/Text\u003e\n      \u003cButton onPress={() =\u003e setCount(count + 1)} title=\"+1\" /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003chr/\u003e\n\n# AVAILABLE PROPS\n\nYou can pass these props to **Talkr**'s provider\n| |Type |Role |\n|----------------|-------------------------------|-----------------------------|\n|languages |`object` |object containing all your json files. Typical format: `{en: {...}, fr: {...}}` |\n|defaultLanguage |`string` |default language of your app (a similar key must be included in the `language` prop) |\n|detectBrowserLanguage |`boolean`|if `true`, **Talkr** will automatically use browser language and override the `defaultLanguage`. If the browser language is not included in your available translations, it will switch back to `defaultLanguage`. Not available in React Native. Use `expo-localization` to fetch the default user locale instead.|\n\n\u003e 🤓: The auto-detect language feature will always return a simple key such as 'fr' instead of 'fr_FR'. Keep things simple and always declare your languages with 2 letters.\n\n\u003chr/\u003e\n\n## CREDITS\n\nDoneDeal0\n\n\u003chr/\u003e\n\n## SUPPORT\n\nIf you or your company uses **Talkr**, please show your support by becoming a sponsor! Your name and company logo will be displayed on the `README.md`.\nhttps://github.com/sponsors/DoneDeal0\n\n\u003cbr/\u003e\n\u003ca href=\"https://github.com/sponsors/DoneDeal0\" target=\"_blank\"\u003e\n\u003cimg alt=\"sponsor\" src=\"https://github.com/DoneDeal0/superdiff/assets/43271780/21deb4f3-fee3-4bf9-a945-ed0b77c6f82f\"/\u003e\n\u003c/a\u003e\n\u003cbr/\u003e\n\n\u003chr/\u003e\n\n\u003chr/\u003e\n\nAlso see our \u003ca href=\"https://talkr-documentation.netlify.app/\"\u003ewebsite\u003c/a\u003e\n","funding_links":["https://github.com/sponsors/DoneDeal0"],"categories":["Internationalization \u0026 Localization","📦 Libraries"],"sub_categories":["React / React Native"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDoneDeal0%2FTalkr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDoneDeal0%2FTalkr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDoneDeal0%2FTalkr/lists"}