{"id":13567062,"url":"https://github.com/robisim74/qwik-speak","last_synced_at":"2025-04-06T08:14:36.459Z","repository":{"id":44414307,"uuid":"512525948","full_name":"robisim74/qwik-speak","owner":"robisim74","description":"Translate your Qwik apps into any language","archived":false,"fork":false,"pushed_at":"2024-05-16T06:43:08.000Z","size":2958,"stargazers_count":127,"open_issues_count":0,"forks_count":14,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-05-16T20:23:58.927Z","etag":null,"topics":["i18n","qwik","translate"],"latest_commit_sha":null,"homepage":"https://robisim74.gitbook.io/qwik-speak/","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/robisim74.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":"2022-07-10T19:50:54.000Z","updated_at":"2024-06-01T17:42:06.649Z","dependencies_parsed_at":"2023-12-23T22:06:52.139Z","dependency_job_id":"e670abdf-f8a0-4204-a60a-e193192ecb3f","html_url":"https://github.com/robisim74/qwik-speak","commit_stats":{"total_commits":225,"total_committers":2,"mean_commits":112.5,"dds":0.004444444444444473,"last_synced_commit":"bd8cbae3cdb9925f6237e4addb9f0ee7b7542612"},"previous_names":[],"tags_count":60,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robisim74%2Fqwik-speak","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robisim74%2Fqwik-speak/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robisim74%2Fqwik-speak/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robisim74%2Fqwik-speak/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robisim74","download_url":"https://codeload.github.com/robisim74/qwik-speak/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247451667,"owners_count":20940944,"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","qwik","translate"],"created_at":"2024-08-01T13:02:22.727Z","updated_at":"2025-04-06T08:14:36.428Z","avatar_url":"https://github.com/robisim74.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Library"],"sub_categories":["External Resources"],"readme":"# Qwik Speak\n[![Node.js CI](https://github.com/robisim74/qwik-speak/actions/workflows/node.js.yml/badge.svg)](https://github.com/robisim74/qwik-speak/actions/workflows/node.js.yml) [![Playwright](https://github.com/robisim74/qwik-speak/actions/workflows/playwright.yml/badge.svg)](https://github.com/robisim74/qwik-speak/actions/workflows/playwright.yml)\n\n\u003e Internationalization (i18n) library to translate texts, dates and numbers in Qwik apps\n\n```shell\nnpm install qwik-speak --save-dev\n```\n\n## Getting Started\n- [Quick Start](./docs/quick-start.md)\n- [Tutorial: localized routing with the language](./docs/tutorial-routing.md)\n- [Tutorial: translated routing with url rewriting](./docs/tutorial-routing-rewrite.md)\n- [Translate](./docs/translate.md)\n- [Translation functions](./docs/translation-functions.md)\n- [Lazy loading translation](./docs/lazy-loading.md)\n- [Qwik Speak and Adapters](./docs/adapters.md)\n- [Testing](./docs/testing.md)\n\nLive example on [Cloudflare pages](https://qwik-speak.pages.dev/) and playground on [CodeSandbox](https://codesandbox.io/p/github/robisim74/qwik-speak)\n\n## Overview\n### Getting the translation\n```tsx\nimport { inlineTranslate } from 'qwik-speak';\n\nexport default component$(() =\u003e {\n  const t = inlineTranslate();\n\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{t('title@@Qwik Speak')}\u003c/h1\u003e {/* Qwik Speak */}\n      \u003cp\u003e{t('greeting@@Hi! I am {{name}}', { name: 'Qwik Speak' })}\u003c/p\u003e {/* Hi! I am Qwik Speak */}\n    \u003c/\u003e\n  );\n});\n```\nYou can pass only the default values by enabling the automatic key generation option:\n```tsx\nimport { inlineTranslate } from 'qwik-speak';\n\nexport default component$(() =\u003e {\n  const t = inlineTranslate();\n\n  return (\n    \u003c\u003e\n      \u003ch1\u003e{t('Qwik Speak')}\u003c/h1\u003e {/* Qwik Speak */}\n      \u003cp\u003e{t('Hi! I am {{name}}', { name: 'Qwik Speak' })}\u003c/p\u003e {/* Hi! I am Qwik Speak */}\n    \u003c/\u003e\n  );\n});\n```\nSee [Translate](./docs/translate.md) and [Automatic key generation](./docs/translate.md#automatic-key-generation) for more details.\n\n### Getting dates, relative time \u0026 numbers\n```tsx\nimport { useFormatDate, useRelativeTime, useFormatNumber } from 'qwik-speak';\n\nexport default component$(() =\u003e {\n  const fd = useFormatDate();\n  const rt = useRelativeTime();\n  const fn = useFormatNumber();\n\n  return (\n    \u003c\u003e\n      \u003cp\u003e{fd(Date.now(), { dateStyle: 'full', timeStyle: 'short' })}\u003c/p\u003e {/* Wednesday, July 20, 2022 at 7:09 AM */}\n      \u003cp\u003e{rt(-1, 'second')}\u003c/p\u003e {/* 1 second ago */}\n      \u003cp\u003e{fn(1000000, { style: 'currency' })}\u003c/p\u003e {/* $1,000,000.00 */}\n    \u003c/\u003e\n  );\n});\n```\nSee [Localize](./docs/translate.md#localize) for more details.\n\n## Static translations\nTranslation are loaded and inlined in chunks sent to the browser during the build.\n\nSee [Qwik Speak Inline Vite plugin](./docs/inline.md) for more information on how it works and how to use it.\n\n## Extraction of translations\nTo extract translations directly from the components, a command is available that automatically generates the files with the keys and default values.\n\nSee [Qwik Speak Extract](./docs/extract.md) for more information on how to use it.\n\n## Automatic translation\nTo automatically translate files, the following external packages are available:\n- [GPT Translate JSON](https://github.com/robisim74/gpt-translate-json)\n- [Qwik Speak DeepL](https://www.npmjs.com/package/@tegonal/qwik-speak-deepl)\n\n## Speak context\n```mermaid\nstateDiagram-v2\n    State1: SpeakState\n    State2: SpeakConfig\n    State3: SpeakLocale\n    State4: TranslationFn\n    State5: Translation\n    State1 --\u003e State2\n    State1 --\u003e State3\n    State1 --\u003e State4\n    State1 --\u003e State5\n    note right of State2: configuration\n    note right of State3\n        - lang\n        - extension (Intl)\n        - currency\n        - timezone\n        - unit\n        - dir\n        - domain\n    end note \n    note right of State4\n        - loadTranslation$\n    end note\n    note right of State5\n        runtime assets\n    end note\n```\n\u003e `SpeakState` is immutable: it cannot be updated after it is created and is not reactive\n\n### Speak config\n- `defaultLocale` The default locale to use as fallback\n- `supportedLocales` List of locales supported by the app\n- `assets` Translation file names. Each asset is passed to the `loadTranslation$` function to obtain data according to the language\n- `runtimeAssets` Assets available at runtime\n- `keySeparator` Separator of nested keys. Default is `.`\n- `keyValueSeparator` Key-value separator. Default is `@@`\n- `rewriteRoutes` Rewrite routes as specified in Vite config for `qwikCity` plugin\n- `domainBasedRouting` Domain-based routing options\n- `showDebugMessagesLocally` Whether to enable local debugging mode. Default is true\n\n### SpeakLocale\nThe `SpeakLocale` object contains the `lang`, in the format `language[-script][-region]`, where:\n- `language` ISO 639 two-letter or three-letter code\n- `script` ISO 15924 four-letter script code\n- `region` ISO 3166 two-letter, uppercase code\n\nand optionally contains:\n- `extension` Language with Intl extensions, in the format `language[-script][-region][-extensions]` like `en-US-u-ca-gregory-nu-latn` to format dates and numbers\n- `currency` ISO 4217 three-letter code\n- `timeZone` From the IANA time zone database\n- `units` Key value pairs of unit identifiers\n- `dir` Text direction: `'ltr' | 'rtl' | 'auto'`\n- `domain` In domain-based routing, set the default domain for the locale\n- `withDomain` In domain-based routing, set another domain for the locale\n\n### Translation functions\n`TranslationFn` interface can be implemented to change the behavior of the library:\n- `loadTranslation$` QRL function to load translation data\n\n### Translation\n`Translation` contains only the key value pairs of the translation data provided with the `runtimeAssets`\n\n## APIs\n### Providers\n`useQwikSpeak(props: QwikSpeakProps)` provides the Speak context to the app. `QwikSpeakProps`:\n  - `config` Speak config\n  - `translationFn` Optional functions to use\n  - `langs` Optional additional languages to preload data for (multilingual)\n  - `currency` Optional currency if different from the current one\n  - `timeZone` Optional time zone if different from the current one\n\n`useSpeak(props: SpeakProps) ` can be used for lazy loading translation. `SpeakProps`:\n  - `assets` Assets to load\n  - `runtimeAssets` Assets to load available at runtime\n  - `langs` Optional additional languages to preload data for (multilingual)\n\n### Context\n- `useSpeakContext()` Returns the Speak state\n- `useSpeakConfig()` Returns the configuration in Speak context\n- `useSpeakLocale()` Returns the locale in Speak context\n\n### Translate\n- `inlineTranslate: () =\u003e (keys: string | string[], params?: Record\u003cstring, any\u003e, lang?: string)`\nTranslates a key or an array of keys. The syntax of the string is `key@@[default value]`\n\n- `inlinePlural: () =\u003e (value: number | string, key?: string, params?: Record\u003cstring, any\u003e, options?: Intl.PluralRulesOptions, lang?: string)`\nGets the plural by a number using [Intl.PluralRules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules) API\n\n### Localize\n- `useFormatDate: () =\u003e (value: Date | number | string, options?: Intl.DateTimeFormatOptions, lang?: string, timeZone?: string)`\nFormats a date using [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) API\n\n- `useRelativeTime: () =\u003e (value: number | string, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions, lang?: string)`\nFormats a relative time using [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat) API\n\n- `useFormatNumber: () =\u003e (value: number | string, options?: Intl.NumberFormatOptions, lang?: string, currency?: string)`\nFormats a number using [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) API\n\n- `useDisplayName: () =\u003e (code: string, options: Intl.DisplayNamesOptions, lang?: string)`\nReturns the translation of language, region, script or currency display names using [Intl.DisplayNames](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames) API\n\n### Routing\n- `localizePath: () =\u003e (route: (string | URL) | string[], lang?: string)`\nLocalize a path, an URL or an array of paths with the language\n\n- `translatePath: () =\u003e (route: (string | URL) | string[], lang?: string)`\nTranslates a path, an URL or an array of paths. The translating string can be in any language. If not specified the target lang is the current one\n\n- `validateLocale(lang: string)`\nValidate `language[-script][-region]`\n\n- `extractFromUrl(route: URL)`\nExtract prefix from url\n\n- `extractFromDomain(route: URL, domains: SpeakLocale[] | RewriteRouteOption[])`\nExtract lang/prefix from domain\n\n### Testing\n- `QwikSpeakMockProvider` component provides the Speak context to test enviroments\n\n## Development Builds\n### Library \u0026 tools\n#### Build\n```shell\ncd packages/qwik-speak\nnpm install\nnpm run build\n```\n#### Test\n```shell\nnpm test\n```\n### Sample app\n#### Run\n```shell\nnpm install\nnpm start\n```\n#### Preview\n```shell\nnpm run preview\n```\n#### Test\n```shell\nnpm test\nnpm run test.e2e\n```\n### Watch mode\n```shell\nnpm run dev\n```\n\n## License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobisim74%2Fqwik-speak","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobisim74%2Fqwik-speak","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobisim74%2Fqwik-speak/lists"}