### Run Sample App
Source: https://github.com/robisim74/qwik-speak/blob/main/README.md
Commands to install dependencies, start the sample application, and preview it.
```shell
npm install
npm start
```
```shell
npm run preview
```
--------------------------------
### Shell Command to Start Qwik App
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Starts the Qwik development server for testing translations.
```shell
npm start
```
--------------------------------
### Install Qwik Speak
Source: https://github.com/robisim74/qwik-speak/blob/main/packages/qwik-speak/README.md
Install the qwik-speak library using npm. This is a development dependency.
```shell
npm install qwik-speak --save-dev
```
--------------------------------
### Run Development and Production Scripts
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing.md
Commands to start the development server or build for production.
```shell
npm start
```
```shell
npm run preview
```
--------------------------------
### Build Qwik Speak Package
Source: https://github.com/robisim74/qwik-speak/blob/main/README.md
Commands to install dependencies, build the Qwik Speak package, and run tests.
```shell
cd packages/qwik-speak
npm install
npm run build
```
```shell
npm test
```
--------------------------------
### Dynamic Translation Example
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Using a variable as a translation key. This requires runtime translation setup.
```typescript
const key = 'dynamic';
t(key)
```
--------------------------------
### Component Using Qwik Speak Translation
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/testing.md
Example of a Qwik component using `inlineTranslate` to display translated text. Ensure `qwik-speak` is installed and configured.
```tsx
import { inlineTranslate, useFormatDate, useFormatNumber } from 'qwik-speak';
export default component$(() => {
const t = inlineTranslate();
return (
<>
>
);
});
```
--------------------------------
### Qwik Speak Runtime JSON Configuration
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Example of a runtime JSON asset file for Qwik Speak, used to store dynamic translation keys that are not extracted during the build process.
```json
{
"runtime": {
"dynamic": "I'm a dynamic value"
}
}
```
--------------------------------
### Inlined translation output examples
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/inline.md
Examples of generated JavaScript chunks containing inlined translations for different locales.
```javascript
/* @__PURE__ */ Nr("h2", null, null, `Translate your Qwik apps into any language`, 1, null)
```
```javascript
/* @__PURE__ */ Nr("h2", null, null, `Traduci le tue app Qwik in qualsiasi lingua`, 1, null)
```
--------------------------------
### Runtime Translation Configuration
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Example of a runtime.json file to define translations that are not available at compile time. This file needs to be added to `runtimeAssets`.
```json
{
"dynamic": "I'm a dynamic value"
}
```
--------------------------------
### Implement Translation Loading Functions
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/quick-start.md
Create speak-functions.ts to define how translation files are loaded. This example uses dynamic imports with glob patterns and a server$ function for server-side loading.
```typescript
import { server$ } from '@builder.io/qwik-city';
import type { LoadTranslationFn, Translation, TranslationFn } from 'qwik-speak';
/**
* Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build.
* Assets names and keys must be valid variable names
*/
const translationData = import.meta.glob('/i18n/**/*.json');
/**
* Using server$, translation data is always accessed on the server
*/
const loadTranslation$: LoadTranslationFn = server$(async (lang: string, asset: string) =>
await translationData[`/i18n/${lang}/${asset}.json`]?.()
);
export const translationFn: TranslationFn = {
loadTranslation$: loadTranslation$
};
```
--------------------------------
### Handle Locale Errors and Redirects in Layouts
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Use layout files to manage locale-related errors or redirects. This example shows how to throw a 404 error if no locale is found or how to implement a redirect.
```typescript
import type { RequestHandler } from "@builder.io/qwik-city";
// import { translatePath } from 'qwik-speak'; // Uncomment if using translatePath for redirects
export const onRequest: RequestHandler = ({ locale, error, redirect }) => {
// E.g. 404 error page
if (!locale()) throw error(404, 'Page not found for requested locale');
// E.g. Redirect
// if (!locale()) {
// const getPath = translatePath();
// throw redirect(302, getPath('/page', 'en-US')); // Let the server know the language to use
// }
};
```
--------------------------------
### JSON Structure for Arrays and Objects
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Example JSON structure for defining arrays and objects as translation values.
```json
{
"array": [
"one",
"two",
"three"
],
"obj": {
"one": "one",
"two": "two"
}
}
```
--------------------------------
### Generated JSON with Automatic Keys
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Example of JSON output generated by the extraction tool when automatic key generation is enabled. Keys are automatically created for new strings.
```json
{
"app": {
"title": "Qwik Speak demo"
},
"autoKey_3c909eb27a10640be9495cff142f601c": {
"one": "{{ value }} {{ color }} zebra",
"other": "{{ value }} {{ color }} zebras"
},
"autoKey_8e4c0598319b3b04541df2fc36cb6fc5": "New strings without existing keys",
"autoKey_cbe370e60f10f92d4dd8b3e9c267b1fa": "black and white"
}
```
--------------------------------
### Component Using Server-Side Translation
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
A Qwik component that fetches a translation from the server using `serverFn` and displays it. It uses `useSpeakLocale` to get the current language and `useTask$` to perform the async operation.
```typescript
export default component$(() => {
const locale = useSpeakLocale();
const s = useSignal('');
useTask$(async () => {
s.value = await serverFn(locale.lang)
});
return (
{s.value}
);
});
```
--------------------------------
### JSON Structure for Plural Rules
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Example JSON structure for defining pluralization rules for a given key. The extraction tool generates this structure.
```json
{
"devs": {
"one": "",
"other": ""
}
}
```
--------------------------------
### QRL Function with Inline Translation
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Example of using `inlineTranslate` within a QRL function. The `inlineTranslate` function must be re-invoked inside the QRL.
```typescript
const fn$ = $((() => {
const t = inlineTranslate();
console.log(t('title@@Qwik Speak'));
}));
```
--------------------------------
### Define URL Rewrite Rules for Translations
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Specify translation paths for different locales. This example defines a rewrite rule for the 'it-IT' locale, mapping 'page' to 'pagina'.
```typescript
import type { RewriteRouteOption } from 'qwik-speak';
/**
* Translation paths
*/
export const rewriteRoutes: RewriteRouteOption[] = [
// No prefix/paths for default locale
{
prefix: 'it-IT',
paths: {
'page': 'pagina'
}
}
];
```
--------------------------------
### Run build preview
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/inline.md
Execute the preview command to generate language-specific chunks.
```shell
npm run preview
```
--------------------------------
### Build Project with npm
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/adapters.md
Run this command in your terminal to build the Qwik project for production. Inspect the 'dist' folder afterwards.
```shell
npm run build
```
--------------------------------
### Command Line Usage
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/extract.md
Instructions on how to use the qwik-speak-extract command-line tool, including configuration in package.json and running the command.
```APIDOC
## Command Line Usage
### Get the code ready
Optionally, you can use a default value for the keys. The syntax is `key@@[default value]`:
```html
{t('title@@Qwik Speak'}
{t('greeting@@Hi! I am {{name}}', { name: 'Qwik Speak' })}
```
When you use a default value, it will be used as initial value for the key in every translation.
> Note that it is not necessary to provide the default value of a key every time: it is sufficient and not mandatory to provide it once in the app
### Naming conventions
If you use scoped translations, the first property will be used as filename:
```html
{t('app.title)}
{t('home.greeting)}
```
will generate two files for each language:
```
i18n/
│
└───en-US/
│ app.json
│ home.json
└───it-IT/
app.json
home.json
```
Not scoped translations will be placed in a single file, called `app.json`
### Configuration
Add the command in `package.json`, and provide at least the supported languages:
```json
"scripts": {
"qwik-speak-extract": "qwik-speak-extract --supportedLangs=en-US,it-IT --assetsPath=i18n"
}
```
Available options:
- `supportedLangs` Supported langs. Required
- `basePath` The base path. Default to `'./'`
- `sourceFilesPaths` Paths to files to search for translations. Default to `'src'`
- `excludedPaths` Paths to exclude
- `assetsPath` Path to translation files: `[basePath]/[assetsPath]/[lang]/*.json`. Default to `'i18n'`
- `format` The format of the translation files. Default to `'json'`
- `filename` Filename for not scoped translations. Default is `'app'`
- `fallback` Optional function to implement a fallback strategy
- `autoKeys` Automatically handle keys for each string. Default is false
- `unusedKeys` Automatically remove unused keys from assets, except in runtime assets
- `runtimeAssets` Comma-separated list of runtime assets to preserve
- `keySeparator` Separator of nested keys. Default is `'.'`
- `keyValueSeparator` Key-value separator. Default is `'@@'`
> Note. Currently, only `json` is supported as format
### Running
```shell
npm run qwik-speak-extract
```
### Updating
If you add new translations in the components, or a new language, they will be merged into the existing files without losing the translations already made.
### Automatic removal of unused keys
To remove unused keys from json files, you need to enable the option and provide a comma-separated list of runtime file names:
```json
"scripts": {
"qwik-speak-extract": "qwik-speak-extract --supportedLangs=en-US,it-IT --unusedKeys=true --runtimeAssets=runtime"
}
```
```
--------------------------------
### Rendered Pluralization Example
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
The output of the inlinePlural function when used with a count and defined plural rules.
```json
{
"devs": {
"one": "{{ value }} software developer",
"other": "{{ value }} software developers"
}
}
```
--------------------------------
### JSON Structure with HTML Content
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Example JSON structure where a translation value contains HTML markup.
```json
{
"description": "Internationalization (i18n) library to translate texts, dates and numbers in Qwik apps"
}
```
--------------------------------
### Initialize Speak Context with useQwikSpeak
Source: https://context7.com/robisim74/qwik-speak/llms.txt
Initializes the Qwik Speak context at the application root. Requires configuration and translation functions.
```typescript
// src/speak-config.ts
import type { SpeakConfig } from 'qwik-speak';
export const config: SpeakConfig = {
defaultLocale: { lang: 'en-US', currency: 'USD', timeZone: 'America\/Los_Angeles' },
supportedLocales: [
{ lang: 'en-US', currency: 'USD', timeZone: 'America\/Los_Angeles' },
{ lang: 'it-IT', currency: 'EUR', timeZone: 'Europe\/Rome' },
{ lang: 'de-DE', currency: 'EUR', timeZone: 'Europe\/Berlin' }
],
assets: ['app'], // Static translations inlined at build
runtimeAssets: ['runtime'] // Dynamic translations loaded at runtime
};
```
```typescript
// src/speak-functions.ts
import { server$ } from '@builder.io/qwik-city';
import type { LoadTranslationFn, Translation, TranslationFn } from 'qwik-speak';
const translationData = import.meta.glob('/i18n/**/*.json');
const loadTranslation$: LoadTranslationFn = server$(async (lang: string, asset: string) =>
await translationData[`/i18n/${lang}/${asset}.json`]?.()
);
export const translationFn: TranslationFn = {
loadTranslation$: loadTranslation$
};
```
```tsx
// src/root.tsx
import { component$ } from '@builder.io/qwik';
import { QwikCityProvider } from '@builder.io/qwik-city';
import { useQwikSpeak } from 'qwik-speak';
import { config } from './speak-config';
import { translationFn } from './speak-functions';
export default component$(() => {
useQwikSpeak({ config, translationFn });
return (
);
});
```
--------------------------------
### Testing Components with QwikSpeakMockProvider
Source: https://context7.com/robisim74/qwik-speak/llms.txt
Demonstrates unit testing Qwik components by providing a mock Speak context with various configurations and locale settings.
```tsx
// src/routes/index.spec.tsx
import { createDOM } from '@builder.io/qwik/testing';
import { QwikSpeakMockProvider } from 'qwik-speak';
import { test, expect } from 'vitest';
import Home from './index';
import { config } from '../speak-config';
import { translationFn } from '../speak-functions';
// Basic test with mock provider (uses default values)
test('Should render component with default translations', async () => {
const { screen, render } = await createDOM();
await render(
);
// Uses default values from key@@default syntax
expect(screen.outerHTML).toContain('Qwik Speak demo');
});
// Test with actual translations loaded
test('Should render translated texts in Italian', async () => {
const { screen, render } = await createDOM();
await render(
);
expect(screen.outerHTML).toContain('Qwik Speak dimostrazione');
});
// Test formatting functions
test('Should format date in German locale', async () => {
const { screen, render } = await createDOM();
await render(
);
expect(screen.outerHTML).toContain('März');
});
// Test with custom config
test('Should use custom configuration', async () => {
const customConfig = {
defaultLocale: { lang: 'fr-FR', currency: 'EUR', timeZone: 'Europe/Paris' },
supportedLocales: [{ lang: 'fr-FR', currency: 'EUR', timeZone: 'Europe/Paris' }],
assets: ['app']
};
const { screen, render } = await createDOM();
await render(
);
// Renders with French locale
expect(screen.outerHTML).toBeDefined();
});
```
--------------------------------
### Test Sample App
Source: https://github.com/robisim74/qwik-speak/blob/main/README.md
Commands to run unit tests and end-to-end tests for the sample application.
```shell
npm test
```
```shell
npm run test.e2e
```
--------------------------------
### Handle locale errors in layout.tsx
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing.md
Example of handling locale-related errors or redirects within a layout component.
```typescript
export const onRequest: RequestHandler = ({ locale, error, redirect }) => {
// E.g. 404 error page
if (!locale()) throw error(404, 'Page not found for requested locale');
// E.g. Redirect
// if (!locale()) {
// const getPath = localizePath();
// throw redirect(302, getPath('/page', 'en-US')); // Let the server know the language to use
// }
};
```
--------------------------------
### Configure As-Needed Prefix Strategy
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Use the 'as-needed' strategy and wrap rewriteRoutes with toPrefixAsNeeded in both config and Vite plugin.
```typescript
import { toPrefixAsNeeded } from 'qwik-speak';
import { rewriteRoutes } from './speak-routes';
export const config: SpeakConfig = {
rewriteRoutes: toPrefixAsNeeded(rewriteRoutes),
defaultLocale: { lang: 'en' },
supportedLocales: [
{ lang: 'en' },
{ lang: 'it' },
{ lang: 'de' }
],
domainBasedRouting: {
prefix: 'as-needed'
},
};
```
```typescript
import { qwikSpeakInline, toPrefixAsNeeded } from 'qwik-speak/inline';
import { rewriteRoutes } from './src/speak-routes';
export default defineConfig(({ mode }) => {
return {
plugins: [
qwikCity({ rewriteRoutes: toPrefixAsNeeded(rewriteRoutes, mode) }),
/* */
],
};
});
```
--------------------------------
### Get Translation Function
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Initialize the inlineTranslate function to retrieve translations using key-value pairs. The value after @@ is the optional default value.
```typescript
const t = inlineTranslate();
t('title@@Qwik Speak')
```
--------------------------------
### Initialize Qwik Speak Provider
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/quick-start.md
In your root.tsx file, use the useQwikSpeak hook to initialize Qwik Speak with your configuration and translation functions. This makes Qwik Speak available throughout your application.
```tsx
import { useQwikSpeak } from 'qwik-speak';
import { config } from "./speak-config";
import { translationFn } from "./speak-functions";
export default component$(() => {
/**
* Init Qwik Speak
*/
useQwikSpeak({ config, translationFn });
return (
{/* ... */}
);
});
```
--------------------------------
### Configure Speak with Rewrite Routes and Locales
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Set up the Qwik Speak configuration, including the rewrite routes, default locale, supported locales, and asset paths for translations.
```typescript
import type { SpeakConfig } from 'qwik-speak';
import { rewriteRoutes } from './speak-routes';
export const config: SpeakConfig = {
rewriteRoutes,
defaultLocale: { lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles' },
supportedLocales: [
{ lang: 'it-IT', currency: 'EUR', timeZone: 'Europe/Rome' },
{ lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles' }
],
// Translations available in the whole app
assets: [
'app'
],
// Translations with dynamic keys available in the whole app
runtimeAssets: [
'runtime'
]
};
```
--------------------------------
### Watch Mode for Development
Source: https://github.com/robisim74/qwik-speak/blob/main/README.md
Command to run Qwik Speak in watch mode for continuous development.
```shell
npm run dev
```
--------------------------------
### Get Display Name with useDisplayName
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Uses Intl.DisplayNames API to translate display names for languages, regions, scripts, or currencies. The second parameter specifies the type.
```tsx
const dn = useDisplayName();
dn('en-US', { type: 'language' })
```
--------------------------------
### Use dynamic translation keys
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing.md
Demonstrates how to use dynamic keys for translations that are resolved at runtime.
```tsx
import { inlineTranslate } from 'qwik-speak';
export default component$(() => {
const t = inlineTranslate();
const key = 'dynamic';
return (
<>
{t('app.title', { name: 'Qwik Speak' })}
{t(`runtime.${key}`)}
>
);
});
```
--------------------------------
### Configure Static Site Generation Routes in TypeScript
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/adapters.md
This code configures the dynamic routes for Static Site Generation (SSG) in Qwik, ensuring each supported locale is generated.
```typescript
export const onStaticGenerate: StaticGenerateHandler = () => {
return {
params: config.supportedLocales.map(locale => {
return { lang: locale.lang !== config.defaultLocale.lang ? locale.lang : '.' };
})
};
};
```
--------------------------------
### Configure Qwik City Vite Plugin with Rewrite Routes
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Integrate the defined rewrite routes into the Qwik City Vite plugin configuration. This ensures that URL rewriting is applied during the build process.
```typescript
import { qwikCity } from '@builder.io/qwik-city/vite';
import { qwikSpeakInline } from 'qwik-speak/inline';
import { rewriteRoutes } from './src/speak-routes';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import { qwikVite } from '@builder.io/qwik/vite';
export default defineConfig(() => {
return {
plugins: [
qwikCity({ rewriteRoutes }),
qwikVite(),
qwikSpeakInline({
supportedLangs: ['en-US', 'it-IT'],
defaultLang: 'en-US',
assetsPath: 'i18n'
}),
tsconfigPaths(),
],
};
});
```
--------------------------------
### Run the extraction command
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/extract.md
Execute the configured extraction script via npm.
```shell
npm run qwik-speak-extract
```
--------------------------------
### Configure qwikSpeakInline in vite.config.ts
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/inline.md
Register the plugin in the Vite configuration with required language settings.
```typescript
import { qwikSpeakInline } from 'qwik-speak/inline';
export default defineConfig(() => {
return {
plugins: [
qwikCity(),
qwikVite(),
qwikSpeakInline({
basePath: './',
assetsPath: 'i18n',
supportedLangs: ['en-US', 'it-IT'],
defaultLang: 'en-US'
}),
],
};
});
```
--------------------------------
### Inline Translation in Qwik Component
Source: https://github.com/robisim74/qwik-speak/blob/main/README.md
Use the inlineTranslate function to get a translation function 't' within a Qwik component. Pass the translation key and optional parameters for dynamic values.
```tsx
import { inlineTranslate } from 'qwik-speak';
export default component$(() => {
const t = inlineTranslate();
return (
<>
{t('title@@Qwik Speak')}
{/* Qwik Speak */}
{t('greeting@@Hi! I am {{name}}', { name: 'Qwik Speak' })}
{/* Hi! I am Qwik Speak */}
>
);
});
```
--------------------------------
### Configure extraction script in package.json
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/extract.md
Add the qwik-speak-extract command to your scripts with required supported languages and assets path.
```json
"scripts": {
"qwik-speak-extract": "qwik-speak-extract --supportedLangs=en-US,it-IT --assetsPath=i18n"
}
```
--------------------------------
### Programmatic API
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/extract.md
How to use the qwikSpeakExtract function programmatically within your JavaScript or TypeScript code.
```APIDOC
## Using it programmatically
Rather than using the command, you can invoke `qwikSpeakExtract` function:
```javascript
import { qwikSpeakExtract } from 'qwik-speak/extract';
await qwikSpeakExtract({
supportedLangs: ['en-US', 'it-IT']
});
```
### Translations fallback
By default, the extract command uses the default value of translations as the initial value when provided.
You can extend this behavior, to complete the missing translations by taking them from another language, by implementing a custom function with this signature:
```typescript
(translation: Translation) => Translation
```
and pass the function to `fallback` option:
```typescript
await qwikSpeakExtract({
supportedLangs: supportedLangs,
fallback: fallback
});
```
For example, if you want to use the default language translations for missing values in other languages:
```typescript
import { qwikSpeakExtract, deepMergeMissing } from 'qwik-speak/extract';
const defaultLang = 'en-US';
const supportedLangs = ['en-US', 'it-IT', 'de-DE'];
/**
* Fallback missing values to default lang
*/
const fallback = (translation) => {
const defaultTranslation = translation[defaultLang];
for (const lang of supportedLangs) {
if (lang !== defaultLang) {
deepMergeMissing(translation[lang], defaultTranslation);
}
}
return translation;
};
```
```
--------------------------------
### Define Qwik Speak Configuration
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/quick-start.md
Create a speak-config.ts file to define the default locale, supported locales, and asset paths for translations. This configuration is used throughout the application.
```typescript
import type { SpeakConfig } from 'qwik-speak';
export const config: SpeakConfig = {
defaultLocale: { lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles' },
supportedLocales: [
{ lang: 'it-IT', currency: 'EUR', timeZone: 'Europe/Rome' },
{ lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles' }
],
// Translations available in the whole app
assets: [
'app'
],
// Translations with dynamic keys available in the whole app
runtimeAssets: [
'runtime'
]
};
```
--------------------------------
### Providers API
Source: https://github.com/robisim74/qwik-speak/blob/main/README.md
Hooks for initializing the Speak context and managing translation assets.
```APIDOC
## useQwikSpeak
### Description
Provides the Speak context to the application.
### Parameters
- **props** (QwikSpeakProps) - Required
- **config** (SpeakConfig) - Required - Speak configuration
- **translationFn** (TranslationFn) - Optional - Functions to use
- **langs** (string[]) - Optional - Additional languages to preload
- **currency** (string) - Optional - Currency if different from current
- **timeZone** (string) - Optional - Time zone if different from current
## useSpeak
### Description
Used for lazy loading translation assets.
### Parameters
- **props** (SpeakProps) - Required
- **assets** (any) - Required - Assets to load
- **runtimeAssets** (any) - Required - Assets available at runtime
- **langs** (string[]) - Optional - Additional languages to preload
```
--------------------------------
### Configure qwikSpeakInline Vite Plugin
Source: https://context7.com/robisim74/qwik-speak/llms.txt
Configure the `qwikSpeakInline` Vite plugin in `vite.config.ts` to inline translations at build time. This generates language-specific JavaScript chunks for static content, eliminating runtime lookups. Options include supported languages, default language, asset paths, and custom asset loading.
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import { qwikCity } from '@builder.io/qwik-city/vite';
import { qwikVite } from '@builder.io/qwik/optimizer';
import { qwikSpeakInline } from 'qwik-speak/inline';
export default defineConfig(() => {
return {
plugins: [
qwikCity(),
qwikVite(),
qwikSpeakInline({
// Required options
supportedLangs: ['en-US', 'it-IT', 'de-DE'],
defaultLang: 'en-US',
// Optional options
basePath: './',
assetsPath: 'i18n',
outDir: 'dist',
autoKeys: false, // Enable automatic key generation
keySeparator: '.', // Separator for nested keys
keyValueSeparator: '@@', // Separator for default values
}),
],
};
});
```
```typescript
// With URL rewriting
import { qwikSpeakInline, toPrefixAsNeeded } from 'qwik-speak/inline';
import { rewriteRoutes } from './src/speak-routes';
export default defineConfig(({ mode }) => {
return {
plugins: [
qwikCity({
rewriteRoutes: toPrefixAsNeeded(rewriteRoutes, mode)
}),
qwikVite(),
qwikSpeakInline({
supportedLangs: ['en-US', 'it-IT'],
defaultLang: 'en-US',
assetsPath: 'i18n'
}),
],
};
});
```
```typescript
// Custom asset loading from external source
export default defineConfig(() => {
const loadAssets = async (lang: string) => {
const response = await fetch(`https://api.example.com/translations/${lang}`);
return response.json();
};
return {
plugins: [
qwikCity(),
qwikVite(),
qwikSpeakInline({
supportedLangs: ['en-US', 'it-IT'],
defaultLang: 'en-US',
loadAssets: loadAssets // Custom loader replaces file-based loading
}),
],
};
});
// Build output structure:
// dist/build/
// ├── en-US/
// │ └── q-*.js (contains: "Translate your Qwik apps")
// └── it-IT/
// └── q-*.js (contains: "Traduci le tue app Qwik")
```
--------------------------------
### Localized Navigation Links with Qwik Speak
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Integrates localized navigation links and the `ChangeLocale` component into the header. Uses `inlineTranslate` and `translatePath` to generate correct URLs for different locales.
```tsx
import { Link, useLocation } from '@builder.io/qwik-city';
import { inlineTranslate, translatePath } from 'qwik-speak';
import { ChangeLocale } from '../../change-locale/change-locale';
export default component$(() => {
const t = inlineTranslate();
const pathname = useLocation().url.pathname;
const getPath = translatePath();
const [homePath, pagePath] = getPath(['/', '/page/']);
return (
<>
{t('app.nav.home@@Home')}
{t('app.nav.page@@Page')}
>
);
});
```
--------------------------------
### Invoke extraction programmatically
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/extract.md
Use the qwikSpeakExtract function directly in your code instead of the CLI command.
```javascript
import { qwikSpeakExtract } from 'qwik-speak/extract';
await qwikSpeakExtract({
supportedLangs: ['en-US', 'it-IT']
});
```
--------------------------------
### Define translation keys with default values
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/extract.md
Use the key@@[default value] syntax to provide initial translation values directly in components.
```html
{t('title@@Qwik Speak'}
{t('greeting@@Hi! I am {{name}}', { name: 'Qwik Speak' })}
```
--------------------------------
### Unit Test Qwik Component with Qwik Speak
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/testing.md
Unit test a Qwik component using `QwikSpeakMockProvider` to provide the `SpeakContext`. This is suitable for basic rendering tests.
```tsx
import Home from './index';
test(`[Home Component]: Should render the component`, async () => {
const { screen, render } = await createDOM();
await render(
);
expect(screen.outerHTML).toContain('Qwik Speak demo');
});
```
--------------------------------
### Load Translation with Dynamic Import
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translation-functions.md
Loads translation files using dynamic import, recommended for performance. Files are split into separate chunks during build. Assets names and keys must be valid variable names. Uses `server$` to ensure data is accessed on the server.
```typescript
const translationData = import.meta.glob('/i18n/**/*.json');
const loadTranslation$: LoadTranslationFn = server$((lang: string, asset: string) =>
translationData[`/i18n/${lang}/${asset}.json`]?.()
);
```
--------------------------------
### Extract Translations with qwikSpeakExtract CLI
Source: https://context7.com/robisim74/qwik-speak/llms.txt
Use the `qwik-speak-extract` CLI command to extract translation keys and default values from components. This command automatically generates and maintains translation JSON files. Configure supported languages and asset paths in `package.json` scripts.
```bash
# package.json scripts
{
"scripts": {
"qwik-speak-extract": "qwik-speak-extract --supportedLangs=en-US,it-IT,de-DE --assetsPath=i18n"
}
}
# Run extraction
npm run qwik-speak-extract
# Output:
# i18n/en-US/app.json
# i18n/it-IT/app.json
# i18n/de-DE/app.json
# extracted keys: 15
```
--------------------------------
### Server-Side Locale Detection and Context Setting
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Implement a server-side request handler to extract the locale from the URL, validate it, and set the Qwik Speak context. This ensures the correct locale is used for each request.
```typescript
import type { RequestHandler } from "@builder.io/qwik-city";
import { extractFromUrl, setSpeakContext, validateLocale } from 'qwik-speak';
import { config } from '../speak-config';
/**
* This middleware function must only contain the logic to set the locale,
* because it is invoked on every request to the server.
* Avoid redirecting or throwing errors here, and prefer layouts or pages
*/
export const onRequest: RequestHandler = ({ locale, url }) => {
let lang: string | undefined = undefined;
const prefix = extractFromUrl(url);
if (prefix && validateLocale(prefix)) {
// Check supported locales
lang = config.supportedLocales.find(value => value.lang === prefix)?.lang;
} else {
lang = config.defaultLocale.lang;
}
// Set Speak context (optional: set the configuration on the server)
setSpeakContext(config);
// Set Qwik locale
locale(lang);
};
```
--------------------------------
### Configure Always Prefix Strategy
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Set the domainBasedRouting prefix to 'always' in your speak-config.ts file.
```typescript
import { rewriteRoutes } from './speak-routes';
export const config: SpeakConfig = {
rewriteRoutes,
defaultLocale: { lang: 'en' },
supportedLocales: [
{ lang: 'en' },
{ lang: 'it' },
{ lang: 'de' }
],
domainBasedRouting: {
prefix: 'always'
},
};
```
--------------------------------
### Configure Provider for Multiple Languages
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Configures the Qwik Speak provider to support multiple languages, including 'it-IT', by specifying them in the 'langs' array.
```tsx
useQwikSpeak({ config, translationFn, langs: ['it-IT'] });
```
--------------------------------
### Load Translation by Fetching from Public Folder
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translation-functions.md
Fetches translation files from the public folder using the `fetch` API. This function is executed on the server. Logs an error if the fetch request is not successful.
```typescript
const loadTranslation$ = server$(async function (lang: string, asset: string) {
// Absolute urls on server
const url = `${this.url.origin}/i18n/${lang}/${asset}.json`;
const response = await fetch(url);
if (response.ok) {
return response.json();
}
else {
console.error(`loadTranslation$: ${url}`, response);
}
});
```
--------------------------------
### Configure Vite Plugin for Qwik Speak Inline
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/quick-start.md
Add the Qwik Speak Inline Vite plugin to your vite.config.ts file to enable inline translation features. Configure supported languages, default language, and asset paths.
```typescript
import { qwikSpeakInline } from 'qwik-speak/inline';
export default defineConfig(() => {
return {
plugins: [
qwikCity(),
qwikVite(),
qwikSpeakInline({
supportedLangs: ['en-US', 'it-IT'],
defaultLang: 'en-US',
assetsPath: 'i18n'
}),
tsconfigPaths(),
],
};
});
```
--------------------------------
### Implement Server-side Translation with server$
Source: https://context7.com/robisim74/qwik-speak/llms.txt
Use server$ to perform translations on the server, either by passing the language explicitly or extracting it from the request headers.
```tsx
import { component$, useSignal } from '@builder.io/qwik';
import { routeLoader$, server$ } from '@builder.io/qwik-city';
import { inlineTranslate, useSpeakLocale } from 'qwik-speak';
// server$ function with explicit language parameter
const getServerMessage = server$(function (lang: string) {
const t = inlineTranslate();
return {
title: t('server.title@@Server Message', undefined, lang),
description: t('server.description@@This was translated on the server', undefined, lang)
};
});
// Alternative: Extract language from request inside server$
const getMessageFromRequest = server$(function () {
const t = inlineTranslate();
// Access request headers, cookies, or URL params for language
const acceptLanguage = this.request.headers.get('accept-language');
const lang = acceptLanguage?.split(',')[0] || 'en-US';
return t('server.message@@Hello from server', undefined, lang);
});
export default component$(() => {
const locale = useSpeakLocale();
const serverData = useSignal<{ title: string; description: string } | null>(null);
// Call server function with current language
const loadServerData = $(async () => {
serverData.value = await getServerMessage(locale.lang);
});
return (
{serverData.value && (
{serverData.value.title}
{serverData.value.description}
)}
);
});
// For routeLoader$, use a middleware approach
// src/routes/plugin.ts - sets locale for all routes
export const onRequest: RequestHandler = ({ request, locale }) => {
const acceptLanguage = request.headers?.get('accept-language');
let lang = acceptLanguage?.split(';')[0]?.split(',')[0] || 'en-US';
locale(lang);
};
```
--------------------------------
### Load Translation with Dynamic Import as Raw String
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translation-functions.md
Loads translation files as raw strings using dynamic import, suitable when keys are not valid variable names. Files are split into separate chunks during build. Uses `server$` to ensure data is accessed on the server.
```typescript
const translationData = import.meta.glob('/i18n/**/*.json', { as: 'raw' });
const loadTranslation$: LoadTranslationFn = server$((lang: string, asset: string) =>
JSON.parse(translationData[`/i18n/${lang}/${asset}.json`])
);
```
--------------------------------
### Enable automatic removal of unused keys
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/extract.md
Configure the extraction script to remove unused keys and specify runtime assets to preserve.
```json
"scripts": {
"qwik-speak-extract": "qwik-speak-extract --supportedLangs=en-US,it-IT --unusedKeys=true --runtimeAssets=runtime"
}
```
--------------------------------
### Implement Domain-Based Locale Extraction
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/tutorial-routing-rewrite.md
Update your request handler to extract the language from the domain or URL and set the Qwik locale.
```typescript
import type { RequestHandler } from '@builder.io/qwik-city';
import { extractFromDomain, extractFromUrl, setSpeakContext, validateLocale } from 'qwik-speak';
import { config } from '../speak-config';
import { rewriteRoutes } from '../speak-routes';
export const onRequest: RequestHandler = ({ locale, url }) => {
let lang: string | undefined = undefined;
const prefix = extractFromUrl(url);
if (prefix && validateLocale(prefix)) {
// Check supported locales
lang = config.supportedLocales.find(value => value.lang === prefix)?.lang;
} else {
// Extract from domain
lang = extractFromDomain(url, rewriteRoutes) || config.defaultLocale.lang;
}
// Set Speak context (optional: set the configuration on the server)
setSpeakContext(config);
// Set Qwik locale
locale(lang);
};
```
--------------------------------
### Implement lazy loading in a layout
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/lazy-loading.md
Use the useSpeak hook within a layout component to load specific assets and runtime assets for that section.
```tsx
import { useSpeak } from 'qwik-speak';
export default component$(() => {
useSpeak({assets:['admin'], runtimeAssets: ['runtimeAdmin']});
return (
<>
>
);
});
```
--------------------------------
### Implement lazy loading in a page
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/lazy-loading.md
Apply the useSpeak hook directly in a page component to load required runtime assets.
```tsx
export default component$(() => {
useSpeak({runtimeAssets: ['runtimePage']});
return ;
});
```
--------------------------------
### Format Numbers and Currency with useFormatNumber
Source: https://context7.com/robisim74/qwik-speak/llms.txt
Use `useFormatNumber` to format numbers, currencies, percentages, and units according to locale. It automatically uses currency from locale configuration and allows overriding it. Supports various formatting styles and notations.
```typescript
import { component$ } from '@builder.io/qwik';
import { useFormatNumber, useSpeakLocale } from 'qwik-speak';
export default component$(() => {
const fn = useFormatNumber();
const locale = useSpeakLocale();
// Basic number formatting with locale grouping
const number = fn(1000000);
// Output (en-US): "1,000,000"
// Output (de-DE): "1.000.000"
// Currency formatting (uses currency from SpeakLocale)
const price = fn(1234.56, { style: 'currency' });
// Output (en-US, USD): "$1,234.56"
// Output (it-IT, EUR): "1.234,56 €"
// Override currency
const euros = fn(99.99, { style: 'currency' }, undefined, 'EUR');
// Output (en-US): "€99.99"
// Percentage
const percentage = fn(0.85, { style: 'percent' });
// Output: "85%"
// Decimal places
const precise = fn(3.14159, {
minimumFractionDigits: 2,
maximumFractionDigits: 4
});
// Output: "3.1416"
// Unit formatting (requires units in SpeakLocale config)
// Config: { lang: 'en-US', units: { 'length': 'mile' } }
const distance = fn(5, { style: 'unit', unit: locale.units?.['length'] || 'mile' });
// Output: "5 mi"
// Compact notation for large numbers
const compact = fn(1500000, { notation: 'compact' });
// Output (en-US): "1.5M"
// Scientific notation
const scientific = fn(123456, { notation: 'scientific' });
// Output: "1.235E5"
// Accounting format (negative in parentheses)
const accounting = fn(-1234.56, {
style: 'currency',
currencySign: 'accounting'
});
// Output (en-US): "($1,234.56)"
return (
Total: {number}
Price: {price}
Discount: {percentage}
Distance: {distance}
);
});
```
--------------------------------
### Automatic Key Generation with Inline Translate
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translate.md
Demonstrates passing only default values to translation functions when automatic key generation is enabled. The extractor tool or inline Vite plugin handles key creation.
```tsx
export default component$(() => {
const t = inlineTranslate();
const p = inlinePlural();
return (
<>
{p(
1,
'{"one": "{{ value }} {{ color }} zebra","other": "{{ value }} {{ color }} zebras"}',
{
color: t('black and white')
}
)}
>
);
});
```
--------------------------------
### Unit Test Translated Texts in Different Languages
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/testing.md
Test translated texts in a specific locale by using `QwikSpeakProvider` and providing `loadTranslation$` and the desired `locale`. This ensures translations are loaded correctly for the test environment.
```tsx
test(`[Home Component]: Should render translated texts in Italian`, async () => {
const { screen, render } = await createDOM();
await render(
);
expect(screen.outerHTML).toContain('Qwik Speak dimostrazione');
});
```
--------------------------------
### Load Translation with Dynamic Import and Error Handling
Source: https://github.com/robisim74/qwik-speak/blob/main/docs/translation-functions.md
Loads translation files using dynamic import with added error handling for development. Logs a warning if a translation asset is not found. Uses `server$` to ensure data is accessed on the server.
```typescript
const loadTranslation$: LoadTranslationFn = server$((lang: string, asset: string) => {
const langAsset = `/i18n/${lang}/${asset}.json`;
if (langAsset in translationData) {
return translationData[langAsset]();
}
if (isDev) {
console.warn(`loadTranslation$: ${langAsset} not found`);
}
return null;
});
```
--------------------------------
### Localize API
Source: https://github.com/robisim74/qwik-speak/blob/main/README.md
Hooks for formatting dates, relative times, numbers, and display names.
```APIDOC
## useFormatDate
### Description
Formats a date using Intl.DateTimeFormat.
## useRelativeTime
### Description
Formats a relative time using Intl.RelativeTimeFormat.
## useFormatNumber
### Description
Formats a number using Intl.NumberFormat.
## useDisplayName
### Description
Returns the translation of language, region, script or currency display names using Intl.DisplayNames.
```