### 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 ( <>

{t('app.title@@{{name}} demo', { name: 'Qwik Speak' })}

); }); ``` -------------------------------- ### 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 ( <>

{t('app.title@@{{name}} demo', { name: 'Qwik Speak' })}

{t('New strings without existing keys')}

{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. ```