Skip to content

robisim74/qwik-speak

Repository files navigation

Qwik Speak

Node.js CI Playwright

Internationalization (i18n) library to translate texts, dates and numbers in Qwik apps

npm install qwik-speak --save-dev

Getting Started

Live example on Cloudflare pages and playground on CodeSandbox

Overview

Getting the translation

import { inlineTranslate } from 'qwik-speak';

export default component$(() => {
  const t = inlineTranslate();

  return (
    <>
      <h1>{t('title@@Qwik Speak')}</h1> {/* Qwik Speak */}
      <p>{t('greeting@@Hi! I am {{name}}', { name: 'Qwik Speak' })}</p> {/* Hi! I am Qwik Speak */}
    </>
  );
});

You can pass only the default values by enabling the automatic key generation option:

import { inlineTranslate } from 'qwik-speak';

export default component$(() => {
  const t = inlineTranslate();

  return (
    <>
      <h1>{t('Qwik Speak')}</h1> {/* Qwik Speak */}
      <p>{t('Hi! I am {{name}}', { name: 'Qwik Speak' })}</p> {/* Hi! I am Qwik Speak */}
    </>
  );
});

See Translate and Automatic key generation for more details.

Getting dates, relative time & numbers

import { useFormatDate, useRelativeTime, useFormatNumber } from 'qwik-speak';

export default component$(() => {
  const fd = useFormatDate();
  const rt = useRelativeTime();
  const fn = useFormatNumber();

  return (
    <>
      <p>{fd(Date.now(), { dateStyle: 'full', timeStyle: 'short' })}</p> {/* Wednesday, July 20, 2022 at 7:09 AM */}
      <p>{rt(-1, 'second')}</p> {/* 1 second ago */}
      <p>{fn(1000000, { style: 'currency' })}</p> {/* $1,000,000.00 */}
    </>
  );
});

See Localize for more details.

Static translations

Translation are loaded and inlined in chunks sent to the browser during the build.

See Qwik Speak Inline Vite plugin for more information on how it works and how to use it.

Extraction of translations

To extract translations directly from the components, a command is available that automatically generates the files with the keys and default values.

See Qwik Speak Extract for more information on how to use it.

Automatic translation

To automatically translate files, the following external packages are available:

Speak context

stateDiagram-v2
    State1: SpeakState
    State2: SpeakConfig
    State3: SpeakLocale
    State4: TranslationFn
    State5: Translation
    State1 --> State2
    State1 --> State3
    State1 --> State4
    State1 --> State5
    note right of State2: configuration
    note right of State3
        - lang
        - extension (Intl)
        - currency
        - timezone
        - unit
        - dir
        - domain
    end note 
    note right of State4
        - loadTranslation$
    end note
    note right of State5
        runtime assets
    end note
Loading

SpeakState is immutable: it cannot be updated after it is created and is not reactive

Speak config

  • defaultLocale The default locale to use as fallback
  • supportedLocales List of locales supported by the app
  • assets Translation file names. Each asset is passed to the loadTranslation$ function to obtain data according to the language
  • runtimeAssets Assets available at runtime
  • keySeparator Separator of nested keys. Default is .
  • keyValueSeparator Key-value separator. Default is @@
  • rewriteRoutes Rewrite routes as specified in Vite config for qwikCity plugin
  • domainBasedRouting Domain-based routing options
  • showDebugMessagesLocally Whether to enable local debugging mode. Default is true

SpeakLocale

The SpeakLocale object contains the lang, in the format language[-script][-region], where:

  • language ISO 639 two-letter or three-letter code
  • script ISO 15924 four-letter script code
  • region ISO 3166 two-letter, uppercase code

and optionally contains:

  • 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
  • currency ISO 4217 three-letter code
  • timeZone From the IANA time zone database
  • units Key value pairs of unit identifiers
  • dir Text direction: 'ltr' | 'rtl' | 'auto'
  • domain In domain-based routing, set the default domain for the locale
  • withDomain In domain-based routing, set another domain for the locale

Translation functions

TranslationFn interface can be implemented to change the behavior of the library:

  • loadTranslation$ QRL function to load translation data

Translation

Translation contains only the key value pairs of the translation data provided with the runtimeAssets

APIs

Providers

useQwikSpeak(props: QwikSpeakProps) provides the Speak context to the app. QwikSpeakProps:

  • config Speak config
  • translationFn Optional functions to use
  • langs Optional additional languages to preload data for (multilingual)
  • currency Optional currency if different from the current one
  • timeZone Optional time zone if different from the current one

useSpeak(props: SpeakProps) can be used for lazy loading translation. SpeakProps:

  • assets Assets to load
  • runtimeAssets Assets to load available at runtime
  • langs Optional additional languages to preload data for (multilingual)

Context

  • useSpeakContext() Returns the Speak state
  • useSpeakConfig() Returns the configuration in Speak context
  • useSpeakLocale() Returns the locale in Speak context

Translate

  • inlineTranslate: () => (keys: string | string[], params?: Record<string, any>, lang?: string) Translates a key or an array of keys. The syntax of the string is key@@[default value]

  • inlinePlural: () => (value: number | string, key?: string, params?: Record<string, any>, options?: Intl.PluralRulesOptions, lang?: string) Gets the plural by a number using Intl.PluralRules API

Localize

  • useFormatDate: () => (value: Date | number | string, options?: Intl.DateTimeFormatOptions, lang?: string, timeZone?: string) Formats a date using Intl.DateTimeFormat API

  • useRelativeTime: () => (value: number | string, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions, lang?: string) Formats a relative time using Intl.RelativeTimeFormat API

  • useFormatNumber: () => (value: number | string, options?: Intl.NumberFormatOptions, lang?: string, currency?: string) Formats a number using Intl.NumberFormat API

  • useDisplayName: () => (code: string, options: Intl.DisplayNamesOptions, lang?: string) Returns the translation of language, region, script or currency display names using Intl.DisplayNames API

Routing

  • localizePath: () => (route: (string | URL) | string[], lang?: string) Localize a path, an URL or an array of paths with the language

  • translatePath: () => (route: (string | URL) | string[], lang?: string) Translates 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

  • validateLocale(lang: string) Validate language[-script][-region]

  • extractFromUrl(route: URL) Extract prefix from url

  • extractFromDomain(route: URL, domains: SpeakLocale[] | RewriteRouteOption[]) Extract lang/prefix from domain

Testing

  • QwikSpeakMockProvider component provides the Speak context to test enviroments

Development Builds

Library & tools

Build

cd packages/qwik-speak
npm install
npm run build

Test

npm test

Sample app

Run

npm install
npm start

Preview

npm run preview

Test

npm test
npm run test.e2e

Watch mode

npm run dev

License

MIT