Skip to content

Commit f29d2ee

Browse files
committed
Update docs
1 parent 0312563 commit f29d2ee

12 files changed

+220
-109
lines changed

README.md

+17-11
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ Live example on [Cloudflare pages](https://qwik-speak.pages.dev/) and playground
2020
## Overview
2121
### Getting the translation
2222
```tsx
23-
import { $translate as t } from 'qwik-speak';
23+
import { useTranslate } from 'qwik-speak';
2424

2525
export default component$(() => {
26+
const t = useTranslate();
27+
2628
return (
2729
<>
2830
<h1>{t('app.title@@Qwik Speak')}</h1> {/* Qwik Speak */}
@@ -33,9 +35,13 @@ export default component$(() => {
3335
```
3436
### Getting dates, relative time & numbers
3537
```tsx
36-
import { formatDate as fd, relativeTime as rt, formatNumber as fn } from 'qwik-speak';
38+
import { useFormatDate, useRelativeTime, useFormatNumber } from 'qwik-speak';
3739

3840
export default component$(() => {
41+
const fd = useFormatDate();
42+
const rt = useRelativeTime();
43+
const fn = useFormatNumber();
44+
3945
return (
4046
<>
4147
<p>{fd(Date.now(), { dateStyle: 'full', timeStyle: 'short' })}</p> {/* Wednesday, July 20, 2022 at 7:09 AM */}
@@ -84,7 +90,7 @@ stateDiagram-v2
8490
of translation data
8591
end note
8692
```
87-
> `SpeakState` is immutable: it cannot be updated after it is created and is not reactive.
93+
> `SpeakState` is immutable: it cannot be updated after it is created and is not reactive
8894
8995
- `useSpeakContext()` Returns the Speak state
9096
- `useSpeakConfig()` Returns the configuration in Speak context
@@ -112,7 +118,7 @@ and optionally contains:
112118

113119
### Translation functions
114120
`TranslationFn` interface can be implemented to change the behavior of the library:
115-
- `loadTranslation$` Function to load translation data
121+
- `loadTranslation$` QRL function to load translation data
116122

117123
## APIs
118124
### Components
@@ -131,26 +137,26 @@ and optionally contains:
131137

132138
### Functions
133139
#### Translate
134-
- `$translate(keys: string | string[], params?: Record<string, any>, lang?: string)`
140+
- `useTranslate: () => (keys: string | string[], params?: Record<string, any>, lang?: string)`
135141
Translates a key or an array of keys. The syntax of the string is `key@@[default value]`
136142

137-
- `$inlineTranslate(keys: string | string[], ctx: SpeakState, params?: Record<string, any>, lang?: string)`
143+
- `inlineTranslate(keys: string | string[], ctx: SpeakState, params?: Record<string, any>, lang?: string)`
138144
Translates a key or an array of keys outside the component$. The syntax of the string is `key@@[default value]`
139145

140-
- `$plural(value: number | string, key?: string, params?: Record<string, any>, options?: Intl.PluralRulesOptions, lang?: string)`
146+
- `usePlural: () => (value: number | string, key?: string, params?: Record<string, any>, options?: Intl.PluralRulesOptions, lang?: string)`
141147
Gets the plural by a number using [Intl.PluralRules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules) API
142148

143149
#### Localize
144-
- `formatDate(value: Date | number | string, options?: Intl.DateTimeFormatOptions, lang?: string, timeZone?: string)`
150+
- `useFormatDate: () => (value: Date | number | string, options?: Intl.DateTimeFormatOptions, lang?: string, timeZone?: string)`
145151
Formats a date using [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) API
146152

147-
- `relativeTime(value: number | string, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions, lang?: string)`
153+
- `useRelativeTime: () => (value: number | string, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions, lang?: string)`
148154
Formats a relative time using [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat) API
149155

150-
- `formatNumber(value: number | string, options?: Intl.NumberFormatOptions, lang?: string, currency?: string)`
156+
- `useFormatNumber: () => (value: number | string, options?: Intl.NumberFormatOptions, lang?: string, currency?: string)`
151157
Formats a number using [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) API
152158

153-
- `displayName(code: string, options: Intl.DisplayNamesOptions, lang?: string)`
159+
- `useDisplayName: () => (code: string, options: Intl.DisplayNamesOptions, lang?: string)`
154160
Returns the translation of language, region, script or currency display names using [Intl.DisplayNames](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames) API
155161

156162
## Development Builds

docs/inline.md

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Qwik Speak Inline Vite plugin
22

3-
> Inline Qwik Speak `$translate`, `$inlineTranslate` and `$plural` functions at compile time
3+
> Inline Qwik Speak `useTranslate`, `inlineTranslate` and `usePNrlural` functions at compile time
44
55
## How it works
6-
In development mode, using Qwik Speak translation happens _at runtime_: `assets` are loaded during SSR or on client, and the lookup also happens at runtime.
6+
In development mode, translation happens _at runtime_: `assets` are loaded during SSR or on client, and the lookup also happens at runtime.
77

88
In production mode, `assets` are loaded only during SSR, and to get the translations on the client as well you have to use _Qwik Speak Inline_ Vite plugin.
99

@@ -80,11 +80,11 @@ Each contains only its own translation:
8080

8181
_dist/build/en-US/q-*.js_
8282
```javascript
83-
/* @__PURE__ */ pr("h2", null, null, `Translate your Qwik apps into any language`, 1, null)
83+
/* @__PURE__ */ Nr("h2", null, null, `Translate your Qwik apps into any language`, 1, null)
8484
```
8585
_dist/build/it-IT/q-*.js_
8686
```javascript
87-
/* @__PURE__ */ pr("h2", null, null, `Traduci le tue app Qwik in qualsiasi lingua`, 1, null)
87+
/* @__PURE__ */ Nr("h2", null, null, `Traduci le tue app Qwik in qualsiasi lingua`, 1, null)
8888
```
8989

9090
At the end of the build, in root folder a `qwik-speak-inline.log` file is generated which contains:
@@ -95,7 +95,7 @@ At the end of the build, in root folder a `qwik-speak-inline.log` file is genera
9595
> Note. Currently, only `json` files are supported as assets
9696
9797
## Qwik Speak Inline Vite plugin & runtime
98-
When there are translations with dynamic keys or params, that is, they use an identifier, you can manage them in separate files, and add them to `runtimeAssets`:
98+
When there are translations with dynamic keys or params, you have to use separate files, and add them to `runtimeAssets`:
9999

100100
```typescript
101101
export const config: SpeakConfig = {
@@ -108,5 +108,15 @@ export const config: SpeakConfig = {
108108
]
109109
};
110110
```
111-
Likewise, you can also create scoped runtime files for different pages and pass them to `Speak` components.
111+
Likewise, you can also create scoped runtime files for different pages and pass them to `Speak` components:
112+
```tsx
113+
export default component$(() => {
114+
return (
115+
<Speak assets={['home']} runtimeAssets={['runtimeHome']}>
116+
<Page />
117+
</Speak>
118+
);
119+
});
120+
```
121+
> `runtimeAssets` are serialized and sent to the client, and loaded when required
112122

docs/quick-start.md

+97-10
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ export const translationFn: TranslationFn = {
4545
loadTranslation$: loadTranslation$
4646
};
4747
```
48-
We have added the Speak config and the implementation of the `loadTranslation$` function. `loadTranslation$` is a customizable function, with which you can load the translation files in the way you prefer.
48+
We have added the Speak config and the implementation of the `loadTranslation$` function to load translation files.
49+
50+
> `loadTranslation$` is a customizable QRL function: you can load the translation files in the way you prefer
4951
5052
## Adding Qwik Speak
5153
Just wrap Qwik City provider with `QwikSpeakProvider` component in `root.tsx` and pass it the configuration and the translation functions:
@@ -78,13 +80,17 @@ Finally we add an `index.tsx` with some translation:
7880
_src/routes/index.tsx_
7981
```tsx
8082
import {
81-
$translate as t,
82-
formatDate as fd,
83-
formatNumber as fn,
83+
useTranslate,
84+
useFormatDate,
85+
useFormatNumber,
8486
Speak,
8587
} from 'qwik-speak';
8688

8789
export const Home = component$(() => {
90+
const t = useTranslate();
91+
const fd = useFormatDate();
92+
const fn = useFormatNumber();
93+
8894
return (
8995
<>
9096
<h1>{t('app.title@@{{name}} demo', { name: 'Qwik Speak' })}</h1>
@@ -108,13 +114,48 @@ export default component$(() => {
108114
</Speak>
109115
);
110116
});
117+
118+
export const head: DocumentHead = {
119+
title: 'home.head.title@@Qwik Speak',
120+
meta: [{ name: 'description', content: 'home.head.description@@Quick start' }]
121+
};
111122
```
112-
Here we have used the `Speak` component to add scoped translations to the home page. This means that in addition to the `app` asset that comes with the configuration, the home page will also use the `home` asset. To distinguish them, `app` asset keys start with `app` and home asset keys start with `home`.
123+
Here we have used the `Speak` component to add scoped translations to the `Home` component:
124+
- `Home` component will use the `home` asset, in addition to the `app` asset that comes with the configuration
125+
- `home` asset keys start with `home`
113126

114127
We are also providing default values for each translation: `key@@[default value]`.
115128

116-
> `Speak` component is a `Slot` component: because Qwik renders `Slot` components and direct children in isolation, translations are not immediately available in direct children, and we need to use a component for the `Home` page. It is generally not necessary to use more than one `Speak` component per page
129+
> `Speak` component is a `Slot` component: because Qwik renders `Slot` components and direct children in isolation, translations are not immediately available in direct children, and we need to use a component for the `Home` page. It is not necessary to use more than one `Speak` component per page
130+
131+
## Head metas
132+
You may have noticed, that in `index.tsx` we have provided the meta title and description with only the keys. Since the Qwik City `DocumentHead` is out of context, we need to do the translations directly in `router-head.tsx`:
117133

134+
_src/components/router-head/router-head.tsx_
135+
```tsx
136+
<title>{t(head.title)}</title>
137+
138+
{head.meta.map((m) => (
139+
<meta key={m.key} name={m.name} content={m.name === 'description' ? t(m.content!) : m.content} />
140+
))}
141+
```
142+
143+
We can also pass the `lang` attribute in the html tag:
144+
145+
_src/entry.ssr.tsx_
146+
```typescript
147+
export default function (opts: RenderToStreamOptions) {
148+
return renderToStream(<Root />, {
149+
manifest,
150+
...opts,
151+
// Use container attributes to set attributes on the html tag
152+
containerAttributes: {
153+
lang: opts.serverData?.locale || config.defaultLocale.lang,
154+
...opts.containerAttributes,
155+
},
156+
});
157+
}
158+
```
118159

119160
## Resolve locale
120161
We can resolve the locale to use in two ways: passing the `locale` parameter to the `QwikSpeakProvider` component, or assigning it to the `locale` handled by Qwik. Create `plugin.ts` in the root of the `src/routes` directory:
@@ -151,9 +192,11 @@ Now we want to change locale. Let's create a `ChangeLocale` component:
151192

152193
_src/components/change-locale.tsx_
153194
```tsx
154-
import { $translate as t, useSpeakConfig, SpeakLocale } from 'qwik-speak';
195+
import { useTranslate, useSpeakConfig, SpeakLocale } from 'qwik-speak';
155196

156197
export const ChangeLocale = component$(() => {
198+
const t = useTranslate();
199+
157200
const config = useSpeakConfig();
158201

159202
const changeLocale$ = $((newLocale: SpeakLocale) => {
@@ -187,7 +230,7 @@ export default component$(() => {
187230
```
188231
In `changeLocale$` we set the locale in a cookie, before reloading the page.
189232

190-
## Extraction: [Qwik Speak Extract](./extract.md)
233+
## Extraction
191234
We can now extract the translations and generate the `assets` as json. In `package.json` add the following command to the scripts:
192235
```json
193236
"qwik-speak-extract": "qwik-speak-extract --supportedLangs=en-US,it-IT --assetsPath=i18n"
@@ -203,16 +246,51 @@ i18n/en-US/app.json
203246
i18n/en-US/home.json
204247
i18n/it-IT/app.json
205248
i18n/it-IT/home.json
249+
translations skipped due to dynamic keys: 2
206250
extracted keys: 4
207251
```
208252
`app` asset and `home` asset for each language, initialized with the default values we provided.
209253

254+
_translations skipped due to dynamic keys_ are meta title and description keys, because those keys are passed as dynamic parameters. We have to add them manually in a new file that we will call `runtime`:
255+
256+
_i18n/[lang]/runtime.json_
257+
```json
258+
{
259+
"runtime": {
260+
"home": {
261+
"head": {
262+
"title": "Qwik Speak",
263+
"description": "Quick start"
264+
}
265+
}
266+
}
267+
}
268+
```
269+
Update the keys in `DocumentHead` of `index.tsx`:
270+
```tsx
271+
export const head: DocumentHead = {
272+
title: 'runtime.home.head.title@@Qwik Speak',
273+
meta: [{ name: 'description', content: 'runtime.home.head.description@@Quick start' }]
274+
};
275+
```
276+
and add `runtime` asset in Speak config:
277+
```typescript
278+
assets: [
279+
'app' // Translations shared by the pages
280+
],
281+
runtimeAssets: [
282+
'runtime' // Translations with dynamic keys or parameters
283+
]
284+
```
285+
210286
We can translate the `it-IT` files, and run the app:
211287
```shell
212288
npm start
213289
```
214290

215-
## Production: [Qwik Speak Inline Vite plugin](./inline.md)
291+
See [Qwik Speak Extract](./extract.md) for more details.
292+
293+
## Production
216294
In production mode, `assets` are loaded only during SSR, and to get the translations on the client as well it is required to inline the translations in chucks sent to the browser.
217295

218296
Add `qwikSpeakInline` Vite plugin in `vite.config.ts`:
@@ -253,10 +331,19 @@ export default function (opts: RenderToStreamOptions) {
253331
});
254332
}
255333
```
256-
257334
Build the production app in preview mode:
258335
```shell
259336
npm run preview
260337
```
338+
Inspect the `qwik-speak-inline.log` file in root folder:
339+
340+
```
341+
client: root.tsx
342+
dynamic key: t(head.title) - skip
343+
dynamic key: t(m.content) - skip
344+
```
345+
It contains the non-inlined dynamic keys that we added in the `runtime.json` file.
261346

262347
> The app will have the same behavior as you saw in dev mode, but now the translations are inlined as you can verify by inspecting the production files, reducing resource usage at runtime
348+
349+
See [Qwik Speak Inline Vite plugin](./inline.md) for more details.

docs/testing.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ Given the `config` object and a component to test like in [Quick Start](./quick-
99
_src/routes/index.tsx_
1010
```tsx
1111
import {
12-
$translate as t,
13-
formatDate as fd,
14-
formatNumber as fn,
12+
useTranslate,
13+
useFormatDate,
14+
useFormatNumber,
1515
Speak,
1616
} from 'qwik-speak';
1717

1818
export const Home = component$(() => {
19+
const t = useTranslate();
20+
const fd = useFormatDate();
21+
const fn = useFormatNumber();
22+
1923
return (
2024
<>
2125
<h1>{t('app.title@@{{name}} demo', { name: 'Qwik Speak' })}</h1>
@@ -57,7 +61,7 @@ test(`[Home Component]: Should render the component`, async () => {
5761
});
5862
```
5963

60-
Optionally, if you need to test the translated texts in different languages, you have to provide `loadTranslation$` to ensure translations are loaded in test environment and the locale to use:
64+
Optionally, if you need to test the translated texts in different languages, you have to provide `loadTranslation$` to ensure translations are loaded in test environment, and the locale to use:
6165

6266
```tsx
6367
test(`[Home Component]: Should render translated texts in Italian`, async () => {

0 commit comments

Comments
 (0)