{"id":13469626,"url":"https://github.com/schummar/schummar-translate","last_synced_at":"2025-05-16T02:07:22.775Z","repository":{"id":40791298,"uuid":"310055825","full_name":"schummar/schummar-translate","owner":"schummar","description":"TypeScript powered translation library for React and Node.js.","archived":false,"fork":false,"pushed_at":"2025-03-19T07:55:16.000Z","size":1653,"stargazers_count":133,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-12T04:17:48.810Z","etag":null,"topics":["i18n","internationalization","localization","translation"],"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/schummar.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-04T16:21:12.000Z","updated_at":"2025-03-19T07:55:20.000Z","dependencies_parsed_at":"2024-04-24T09:57:36.191Z","dependency_job_id":"768c078d-7fd7-4f3d-97af-d41f0810337a","html_url":"https://github.com/schummar/schummar-translate","commit_stats":{"total_commits":94,"total_committers":4,"mean_commits":23.5,"dds":0.2021276595744681,"last_synced_commit":"c99716cb22137a38e8148805e60f87c8ed87d508"},"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schummar%2Fschummar-translate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schummar%2Fschummar-translate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schummar%2Fschummar-translate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schummar%2Fschummar-translate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schummar","download_url":"https://codeload.github.com/schummar/schummar-translate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453652,"owners_count":22073617,"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","localization","translation"],"created_at":"2024-07-31T15:01:47.413Z","updated_at":"2025-05-16T02:07:22.753Z","avatar_url":"https://github.com/schummar.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","📦 Libraries"],"sub_categories":["JavaScript / TypeScript"],"readme":"# schummar-translate\n\nTypeScript powered translation library for React and Node.js.\n\n[![](https://badgen.net/npm/v/schummar-translate)](https://www.npmjs.com/package/schummar-translate)\n[![](https://badgen.net/bundlephobia/minzip/schummar-translate)](https://bundlephobia.com/package/schummar-translate)\n\n# Example\n\nGiven a translation file like this:\n\n```ts\n// en.ts\nexport default {\n  welcomeMessage: 'Hi, {name}',\n  currentTime: 'It is now {time, time, short}',\n} as const;\n```\n\nschummar-translate is able to provide type checking and autocomplete/IntelliSense for both translation keys and parameters in ICU format:\n![example](https://user-images.githubusercontent.com/2988557/123524539-45a3cd00-d6cb-11eb-9f02-6884b405dc75.gif)\n\n# Getting started\n\nInstall `schummar-translate`.\n\n```bash\nnpm install schummar-translate\n```\n\n## Create and export a translator instance\n\n```ts\n// translate.ts\nimport { createTranslator, TranslationContextProvider } from 'schummar-translate/react';\nimport en from './en.ts';\nimport de from './de.ts';\n\nexport const { t, useTranslator, getTranslator } = createTranslator({\n  sourceDictionary: en,\n  sourceLocale: 'en',\n  dicts: { de },\n});\n```\n\n## Use it everywhere in your app\n\n```tsx\nimport { t } from './translate';\n\nexport App() {\n  const [locale, setLocale] = useState('en');\n\n  const toggleLocale = () =\u003e {\n    setLocale((locale) =\u003e (locale === 'en' ? 'de' : 'en'));\n  }\n\n  return (\n    \u003cTranslationContextProvider locale={locale}\u003e\n      \u003cdiv onClick={toggleLocale}\u003e\n        {t('welcomeMessage', { name: 'schummar' })}\n      \u003c/div\u003e\n    \u003c/TranslationContextProvider\u003e\n  )\n}\n```\n\n# API\n\n### createTranslator\n\n```ts\nfunction createTranslator(options: Options): ReturnValue;\n\ntype Options = {\n  sourceDictionary?: { [id: string]: Dict | string };\n  sourceLocale: string;\n  fallbackLocale?: string | readonly string[] | ((locale: string) =\u003e string | readonly string[]);\n  dicts?:\n    | { [locale: string]: PartialDict\u003cD\u003e | (() =\u003e MaybePromise\u003cPartialDict\u003cD\u003e\u003e) }\n    | ((locale: string) =\u003e MaybePromise\u003cPartialDict\u003cD\u003e | null\u003e);\n  warn?: (locale: string, id: string) =\u003e void;\n  fallback?: string | ((id: string, sourceTranslation: string) =\u003e string);\n  placeholder?: string | ((id: string, sourceTranslation: string) =\u003e string);\n  cacheOptions?: CacheOptions;\n  dateTimeFormatOptions?: Intl.DateTimeFormatOptions;\n  displayNamesOptions?: Intl.DisplayNamesOptions;\n  listFormatOptions?: Intl.ListFormatOptions;\n  numberFormatOptions?: Intl.NumberFormatOptions;\n  pluralRulesOptions?: Intl.PluralRulesOptions;\n  relativeTimeFormatOptions?: Intl.RelativeTimeFormatOptions;\n};\n\ntype CacheOptions = {\n  maxEntries?: number;\n  ttl?: number;\n};\n\ntype ReturnValue = {\n  getTranslator: GetTranslator;\n  useTranslator: UseTranslator;\n  t: ReactTranslator;\n  clearDicts: () =\u003e void;\n};\n```\n\nThe are two versions of this function, depending on the used import. When importing `'schummar-translate'`, it creates a translator without React support (and therefore without the dependency on React). Then the last three parameters do not apply and the return value only contains `getTranslator`. When importing `'schummar-translate/react'` React support and the last three parameters are included.\n\n- `createTranslator` creates and provides all the other functions and uses the passed in `sourceDictionary` to type them.\n- `sourceDictionary` takes the source dictionary as seen above. If not provided, the dictionary for the source language will be loaded as any other. Also, if not provided, you will have to explicitly set the dictionary type: `createTranslator\u003ctypeof mySourceDict\u003e(...)`.\n- `sourceLocale` is the locale of the source dictionary as [ISO-639-1 code](https://de.wikipedia.org/wiki/Liste_der_ISO-639-1-Codes).\n- `fallbackLocale` provides a locale that will be used as fallback if a translation key is not available for some locale.\n- `dicts` provides all languages except the source language. It can either be an object with the locales as key and a dictionary or promise of a dictionary as value. Or it can be a function returning a dictionary or promise of a dictionary for a given locale. The last can be used to lazy load locales (expect source locale), for example with dynamic imports: `` dicts: (locale: string) =\u003e import(`./langs/${locale}`).then(mod =\u003e mod.default) `` or getting it from a cdn via `fetch`.\n- `warn` lets you display warnings (e.g. to `console.warn`) when a translation key is missing in the active locale and no fallback is used.\n- `fallback` lets you define you a static or dynamic string that will be displayed whenever a translation key is missing for the active locale.\n- `fallbackElement` the same as `fallback` but also allows to pass a `ReactNode` to display more complex (e.g styled) fallbacks for translations embedded in JSX.\n- `placeholder` lets you define a string that will be displayed in place of a translated string while the active locale is loading (when using promises)\n- `placeholderElement` the same as `placeholder` but also allows to pass a `ReactNode` to display more complex (e.g styled) placeholders for translations embedded in JSX.\n- `cacheOptions.maxEntries` the maximum amount of entries that are kept in cache. The cache is currently used to memoize Intl instances, since creating them is quite expensive.\n- `cacheOptions.ttl` how long cache entries are kept, in milliseconds. Cleanup happens on next cache miss.\n- `dateTimeFormatOptions` default options for `dateTimeFormat` calls.\n- `displayNamesOptions` default options for `dateTimeFormat` calls.\n- `listFormatOptions` default options for `dateTimeFormat` calls.\n- `numberFormatOptions` default options for `dateTimeFormat` calls.\n- `pluralRulesOptions` default options for `dateTimeFormat` calls.\n- `relativeTimeFormatOptions` default options for `dateTimeFormat` calls.\n\nThe return value is meant to be exported so the provided functions can be used everywhere in your app: `export const { getTranslator, useTranslator, t } = createTranslator({ ... })`\n\n### t\n\n```ts\nfunction t(id: K, values: V, options?: Options): ReactNode;\n\ntype Options = {\n  locale?: string;\n  fallback?: React.ReactNode;\n  placeholder?: React.ReactNode;\n  component?: React.ElementType;\n};\n```\n\n- `locale` allows to override the active locale. If not defined, the active locale is used as provided with `TranslationContextProvider`.\n- `fallback` allows to override the fallback that was passed to `createTranslator` for just this instance.\n- `placeholder` allows to override the placeholder that was passed to `createTranslator` for just this instance.\n- `component` let's you define a component that will wrap the translated string. E.g. `component: 'div'` will result in `\u003cdiv\u003eYOUR TEXT\u003c/div\u003e`\n\n`t` can be used to translate string withing JSX: `\u003cdiv\u003e{t('foo', { value: 42 })}\u003c/div\u003e`. `id` has to be a flattened key from the source dictionary. `values` has to be an object containing the ICU paramters used in the string in the source dictionary. If there are no parameters, `values` is optional.\n\nOf course if you don't like the minimally named `t` you can rename it in the export: `export const { getTranslator, useTranslator, t: translate } = ...`\n\n### t.unknown\n\n```ts\nfunction t.unknown(id: string, values?: Record\u003cstring, unknown\u003e, options?: Options): ReactNode;\n\ntype Options = {\n  locale?: string;\n  fallback?: React.ReactNode;\n  placeholder?: React.ReactNode;\n}\n```\n\n- `locale` allows to override the active locale. If not defined, the active locale is used as provided with `TranslationContextProvider`.\n- `fallback` allows to override the fallback that was passed to `createTranslator` for just this instance.\n- `placeholder` allows to override the placeholder that was passed to `createTranslator` for just this instance.\n\n`t.unknown` does exactly the same as `t` but without type checking. This can be useful if if the translation is not necessarily available. E.g. `` t.unknown(`types.${currentType`, undefined, { fallback: currentType }) ``.\n\n### t.format\n\n```ts\nfunction t.format(template: string, values: V): ReactNode;\n```\n\n`t.format` can be used to format something using ICU. E.g. `t.format('{d, date, short}', { d: new Date() })`.\n\n### t.render\n\n```ts\nfunction t.render(renderFn: (t: HookTranslator\u003cD\u003e) =\u003e ReactNode, dependencies?: any[]): ReactNode;\n```\n\n`t.render` can be used to get access to a translator instance as you would get from `useTranslator`. That is useful e.g. when working on a class component, where the hook is otherwise not available: `\u003cdiv\u003e{t.render(t =\u003e \u003cComponentThatUsesStringProperty placeholder={t('key1')} /\u003e)}\u003c/div\u003e`\n\n- `renderFn` will be executed to render\n- `dependencies` if provided, will memoize the result of renderFn as long as dependencies stay the same (shallow compare)\n  A common example will be to use the Intl api like: `t.render(locale =\u003e new Intl.DateTimeFormat(locale).format(date), [date])`.\n\n### t.locale\n\n```ts\nfunction f.locale: ReactNode;\n```\n\n`t.locale` returns the currently active locale. Mostly useful for `useTranslator`, to pass into another function.\n\n### t.{dateTimeFormat, displayNames, listFormat, numberFormat, pluralRules, relativeTimeFormat}\n\nE.g.\n\n```ts\nfunction f.dateTimeFormat(date?: Date | number | string, options?: Intl.DateTimeFormatOptions): ReactNode;\n```\n\n`t.dateTimeFormat` formats dates and times. It proxies Intl.DateTimeFormat.format but adds caching and inject the active locale. The same is true for displayNames, listFormat, numberFormat, pluralRules and relativeTimeFormat.\nSee [MDN: Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)\n\n### useTranslator\n\n```ts\nfunction useTranslator(locale?: string): HookTranslator;\n\ntype HookTranslator = {\n  (id: K, values: V, options?: Options): string | string[];\n  unknow: (id: string, values?: Record\u003cstring, unknown\u003e, options?: Options): string | string[];\n  format: (template: string, values: V): string;\n  locale: string;\n}\n\ntype Options = {\n  fallback?: string;\n  placeholder?: string;\n}\n```\n\nReact hook that returns a translator that works very similarly to `t`, but being a hook itself, it does not need internal hooks and therefore returns a string instead of a ReactNode. That is useful in case you need to pass strings somewhere, e.g. as options to a select component etc.\nIf the dictionary value is an array, an array of translated string will be returned.\nFor more details see [t](#t), [t.unknown](#tunknown) and [t.format](#tformat).\n\n### getTranslator\n\n```ts\nfunction getTranslator(locale: string): Promise\u003cTranslator\u003e;\n\ntype Translator = {\n  (id: K, values: V, options?: Options): string | string[];\n  unknow: (id: string, values?: Record\u003cstring, unknown\u003e, options?: Options): string | string[];\n  format: (template: string, values: V): string;\n  locale: string;\n}\n\ntype Options = {\n  fallback?: string;\n}\n```\n\nReturns a promise of a translator object. That method can be used in the backend or in the frontend outside of React components. It loads the necessary locales first then resolves the promise. The resulting translator is again very similar to `t` but obviously returning string and not ReactNode.\nIf the dictionary value is an array, an array of translated string will be returned.\nFor more details see [t](#t), [t.unknown](#tunknown) and [t.format](#tformat).\n\n### clearDicts\n\n```ts\nfunction clearDicts(): void;\n```\n\nClears all dictionary and cache data. This will result in dictionaries being reloaded, as soon as they are used again. This allows loading new dictionary versions from a server, for example.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschummar%2Fschummar-translate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschummar%2Fschummar-translate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschummar%2Fschummar-translate/lists"}