@juit/vue-i18n 0.4.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +187 -0
- package/NOTICE.md +13 -0
- package/README.md +232 -93
- package/dist/index.d.ts +235 -174
- package/dist/index.js +147 -90
- package/dist/index.js.map +1 -1
- package/lib/index.ts +386 -0
- package/lib/iso-3166.ts +272 -0
- package/lib/iso-4217.ts +176 -0
- package/lib/iso-639.ts +205 -0
- package/lib/translator.ts +539 -0
- package/package.json +14 -12
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
Juit I18n for Vue
|
|
2
2
|
=================
|
|
3
3
|
|
|
4
|
-
The `@juit/vue-i18n` package provides a
|
|
5
|
-
to support basic internationalization (translations,
|
|
4
|
+
The `@juit/vue-i18n` package provides a _minimal_ plugin for Vue 3
|
|
5
|
+
to support basic internationalization (translations, number formatting, and
|
|
6
|
+
date formatting).
|
|
6
7
|
|
|
7
|
-
It heavily
|
|
8
|
-
[`Intl.DateTimeFormat`][3] global objects widely supported by modern
|
|
8
|
+
It relies heavily on the [`Intl.Locale`][1], [`Intl.NumberFormat`][2], and
|
|
9
|
+
[`Intl.DateTimeFormat`][3] global objects, which are widely supported by modern
|
|
10
|
+
browsers.
|
|
9
11
|
|
|
10
|
-
It also
|
|
12
|
+
It also integrates with TypeScript to provide compile-time checks for
|
|
11
13
|
required translation languages and translation keys.
|
|
12
14
|
|
|
13
15
|
|
|
@@ -15,6 +17,8 @@ required translation languages and translation keys.
|
|
|
15
17
|
|
|
16
18
|
- [Installation](#installation)
|
|
17
19
|
- [Configuration](#configuration)
|
|
20
|
+
- [Date and Time Format Aliases](#date-and-time-format-aliases)
|
|
21
|
+
- [Number Format Aliases](#number-format-aliases)
|
|
18
22
|
- [Usage](#usage)
|
|
19
23
|
- [Switching language](#switching-language)
|
|
20
24
|
- [Translating messages](#translating-messages)
|
|
@@ -23,18 +27,21 @@ required translation languages and translation keys.
|
|
|
23
27
|
- [Formatting numbers](#formatting-numbers)
|
|
24
28
|
- [Formatting dates](#formatting-dates)
|
|
25
29
|
- [Configuring Types](#configuring-types)
|
|
30
|
+
- [Updating Translations](#updating-translations)
|
|
31
|
+
- [Language Matching](#language-matching)
|
|
32
|
+
- [Remarks](#remarks)
|
|
26
33
|
- [Legal Stuff](#legal-stuff)
|
|
27
34
|
|
|
28
35
|
|
|
29
36
|
## Installation
|
|
30
37
|
|
|
31
|
-
As usual, install with
|
|
38
|
+
As usual, install with npm (or the cool package manager du jour):
|
|
32
39
|
|
|
33
40
|
```bash
|
|
34
41
|
npm install '@juit/vue-i18n'
|
|
35
42
|
```
|
|
36
43
|
|
|
37
|
-
|
|
44
|
+
Then add the plugin to your Vue app:
|
|
38
45
|
|
|
39
46
|
```typescript
|
|
40
47
|
import { createApp } from 'vue'
|
|
@@ -55,23 +62,23 @@ const app = createApp(MyApp).use(i18n, {
|
|
|
55
62
|
|
|
56
63
|
## Configuration
|
|
57
64
|
|
|
58
|
-
The plugin can be configured with a
|
|
59
|
-
|
|
65
|
+
The plugin can be configured with a language code string (the default
|
|
66
|
+
language) or an object containing the following options:
|
|
60
67
|
|
|
61
68
|
* `defaultLanguage`: **(required)** the default language to use; all
|
|
62
69
|
translations should be available in this language.
|
|
63
70
|
* `defaultTimeZone`: the default time zone to use when formatting dates
|
|
64
71
|
(defaults to the _local_ time zone).
|
|
65
72
|
* `translations`: an object containing the translations for the messages to
|
|
66
|
-
translate, keyed by
|
|
67
|
-
* `dateTimeFormats`: date and time format aliases used formatting dates.
|
|
68
|
-
* `numberFormats`: number format aliases used formatting numbers.
|
|
73
|
+
translate, keyed by message identifier.
|
|
74
|
+
* `dateTimeFormats`: date and time format aliases used when formatting dates.
|
|
75
|
+
* `numberFormats`: number format aliases used when formatting numbers.
|
|
69
76
|
|
|
70
77
|
|
|
71
|
-
### Date Time Format Aliases
|
|
78
|
+
### Date and Time Format Aliases
|
|
72
79
|
|
|
73
|
-
Date time
|
|
74
|
-
|
|
80
|
+
Date and time format aliases can be configured using string keys and
|
|
81
|
+
[`Intl.DateTimeFormatOptions`][5] values:
|
|
75
82
|
|
|
76
83
|
```typescript
|
|
77
84
|
import { createApp } from 'vue'
|
|
@@ -93,37 +100,37 @@ const app = createApp(MyApp).use(i18n, {
|
|
|
93
100
|
The default (overridable) formats are as follows:
|
|
94
101
|
|
|
95
102
|
```typescript
|
|
96
|
-
{
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
103
|
+
const dateTimeFormats = {
|
|
104
|
+
// used when no alias or date and time format is specified
|
|
105
|
+
default: { dateStyle: 'medium', timeStyle: 'medium' },
|
|
106
|
+
|
|
107
|
+
// generic formats
|
|
108
|
+
short: { dateStyle: 'short', timeStyle: 'short' },
|
|
109
|
+
medium: { dateStyle: 'medium', timeStyle: 'medium' },
|
|
110
|
+
long: { dateStyle: 'long', timeStyle: 'long' },
|
|
111
|
+
full: { dateStyle: 'full', timeStyle: 'full' },
|
|
112
|
+
|
|
113
|
+
// date only formats
|
|
114
|
+
date: { dateStyle: 'medium' },
|
|
115
|
+
shortDate: { dateStyle: 'short' },
|
|
116
|
+
mediumDate: { dateStyle: 'medium' },
|
|
117
|
+
longDate: { dateStyle: 'long' },
|
|
118
|
+
fullDate: { dateStyle: 'full' },
|
|
119
|
+
|
|
120
|
+
// time only formats
|
|
121
|
+
time: { timeStyle: 'medium' },
|
|
122
|
+
shortTime: { timeStyle: 'short' },
|
|
123
|
+
mediumTime: { timeStyle: 'medium' },
|
|
124
|
+
longTime: { timeStyle: 'long' },
|
|
125
|
+
fullTime: { timeStyle: 'full' },
|
|
119
126
|
}
|
|
120
127
|
```
|
|
121
128
|
|
|
122
129
|
|
|
123
130
|
### Number Format Aliases
|
|
124
131
|
|
|
125
|
-
Similarly
|
|
126
|
-
|
|
132
|
+
Similarly, number format aliases can be configured using string keys and
|
|
133
|
+
[`Intl.NumberFormatOptions`][4] values:
|
|
127
134
|
|
|
128
135
|
```typescript
|
|
129
136
|
import { createApp } from 'vue'
|
|
@@ -141,16 +148,16 @@ const app = createApp(MyApp).use(i18n, {
|
|
|
141
148
|
})
|
|
142
149
|
```
|
|
143
150
|
|
|
144
|
-
|
|
145
|
-
(e.g. `EUR`, `USD`, ...) can be used as an alias.
|
|
151
|
+
By default, numbers use the locale's standard formatting. Each valid ISO 4217
|
|
152
|
+
currency code (e.g. `EUR`, `USD`, ...) can be used as an alias.
|
|
146
153
|
|
|
147
|
-
To configure the default number format use the `default` key.
|
|
154
|
+
To configure the default number format, use the `default` key.
|
|
148
155
|
|
|
149
156
|
|
|
150
157
|
## Usage
|
|
151
158
|
|
|
152
|
-
In any component `setup()` method, you can use the `useTranslator()` function
|
|
153
|
-
to
|
|
159
|
+
In any component's `setup()` method, you can use the `useTranslator()` function
|
|
160
|
+
to retrieve the `Translator` configured for the current app.
|
|
154
161
|
|
|
155
162
|
```typescript
|
|
156
163
|
import { useTranslator } from '@juit/vue-i18n'
|
|
@@ -160,7 +167,7 @@ const translator = useTranslator()
|
|
|
160
167
|
|
|
161
168
|
### Switching language
|
|
162
169
|
|
|
163
|
-
To switch
|
|
170
|
+
To switch languages, simply set the `language`, `region`, or `locale` property
|
|
164
171
|
on the translator instance:
|
|
165
172
|
|
|
166
173
|
```typescript
|
|
@@ -168,8 +175,8 @@ import { useTranslator } from '@juit/vue-i18n'
|
|
|
168
175
|
|
|
169
176
|
const translator = useTranslator() // assuming the default locale is "en-US"
|
|
170
177
|
|
|
171
|
-
translator.region = 'CA' // we have switched to Canada, and locale is now "en-CA"
|
|
172
|
-
translator.language = 'fr' // we have switched to French, and locale is now "fr-CA"
|
|
178
|
+
translator.region = 'CA' // we have switched to Canada, and the locale is now "en-CA"
|
|
179
|
+
translator.language = 'fr' // we have switched to French, and the locale is now "fr-CA"
|
|
173
180
|
|
|
174
181
|
// or set the full `locale`
|
|
175
182
|
translator.locale = new Intl.Locale('de-AT')
|
|
@@ -180,11 +187,11 @@ Because of reactivity, all translations will be updated to the new locale.
|
|
|
180
187
|
|
|
181
188
|
## Translating messages
|
|
182
189
|
|
|
183
|
-
The
|
|
190
|
+
The function for translating messages is exposed as `translator.t(...)` or
|
|
184
191
|
(within components) the `$t(...)` function.
|
|
185
192
|
|
|
186
|
-
This function takes a translation _key_
|
|
187
|
-
|
|
193
|
+
This function takes a translation _key_ specified during configuration
|
|
194
|
+
(see above).
|
|
188
195
|
|
|
189
196
|
```typescript
|
|
190
197
|
import { useTranslator } from '@juit/vue-i18n'
|
|
@@ -202,8 +209,8 @@ import { useTranslator } from '@juit/vue-i18n'
|
|
|
202
209
|
|
|
203
210
|
const translator = useTranslator()
|
|
204
211
|
|
|
205
|
-
const
|
|
206
|
-
en: 'The quick fox
|
|
212
|
+
const pangram = translator.t({
|
|
213
|
+
en: 'The quick brown fox jumps over the lazy dog',
|
|
207
214
|
de: 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'
|
|
208
215
|
})
|
|
209
216
|
```
|
|
@@ -212,25 +219,40 @@ const panagram = translator.t({
|
|
|
212
219
|
### Parameterizing translations
|
|
213
220
|
|
|
214
221
|
Translations can include parameters by enclosing them in curly braces `{param}`.
|
|
222
|
+
Parameter names are case-sensitive: `{name}` and `{NAME}` refer to different parameters.
|
|
223
|
+
|
|
224
|
+
Whitespace around parameter names is ignored. If a parameter is missing,
|
|
225
|
+
its placeholder is kept in normalized form: `{ name }` becomes `{name}`.
|
|
226
|
+
|
|
227
|
+
Escape a placeholder's opening brace with a backslash to display it literally:
|
|
228
|
+
`\{ name }` becomes `{ name }`, even when no parameter is supplied. In a normal
|
|
229
|
+
JavaScript string, write the backslash as `\\`, or use a `String.raw` template.
|
|
230
|
+
Inserted parameter values are treated as literal text and are never parsed again.
|
|
231
|
+
|
|
232
|
+
Backslashes before placeholders follow the same rule as those before pipes:
|
|
233
|
+
each pair produces one literal backslash, and an odd remaining backslash
|
|
234
|
+
escapes the placeholder. With two actual backslashes before `{name}`, one
|
|
235
|
+
backslash is displayed and `name` is substituted; with three, one backslash
|
|
236
|
+
is displayed and `{name}` stays literal.
|
|
215
237
|
|
|
216
238
|
For example:
|
|
217
239
|
|
|
218
240
|
```typescript
|
|
219
241
|
const name = 'John Doe'
|
|
220
242
|
|
|
221
|
-
const string
|
|
222
|
-
en: 'Your name is {name}'
|
|
243
|
+
const string = translator.t({
|
|
244
|
+
en: 'Your name is {name}',
|
|
223
245
|
de: 'Ihr Name ist {name}'
|
|
224
246
|
}, { name })
|
|
225
247
|
// This will result in either "Your name is John Doe" or "Ihr Name ist John Doe"
|
|
226
248
|
```
|
|
227
249
|
|
|
228
|
-
|
|
250
|
+
Numeric parameters are formatted according to the current locale:
|
|
229
251
|
|
|
230
252
|
```typescript
|
|
231
|
-
const string
|
|
232
|
-
en: 'Score {points} points'
|
|
233
|
-
de: 'Punktestand {points} Punkte'
|
|
253
|
+
const string = translator.t({
|
|
254
|
+
en: 'Score { points } points',
|
|
255
|
+
de: 'Punktestand { points } Punkte'
|
|
234
256
|
}, { points: 1234.56 })
|
|
235
257
|
// This will result in "Score 1,234.56 points" or "Punktestand 1.234,56 Punkte"
|
|
236
258
|
```
|
|
@@ -238,38 +260,62 @@ const string: translator.t({
|
|
|
238
260
|
|
|
239
261
|
### Pluralization
|
|
240
262
|
|
|
241
|
-
The translator supports
|
|
263
|
+
The translator supports basic pluralization rules by separating
|
|
242
264
|
translation messages with the `|` (pipe) character.
|
|
243
265
|
|
|
244
|
-
Messages can contain two variants `singular|plural
|
|
245
|
-
`zero|singular|plural
|
|
246
|
-
|
|
266
|
+
Messages can contain two variants, `singular|plural`, or three variants,
|
|
267
|
+
`zero|singular|plural`. The singular variant is used for one, and the plural
|
|
268
|
+
variant for other numbers. If a zero variant is provided, it is used for zero
|
|
269
|
+
instead of the plural variant.
|
|
247
270
|
|
|
248
|
-
To
|
|
249
|
-
|
|
271
|
+
To specify the number used for pluralization, either use the `n` parameter
|
|
272
|
+
or pass the number as the second argument to `tc(...)`.
|
|
250
273
|
|
|
251
274
|
For example:
|
|
252
275
|
|
|
253
276
|
```typescript
|
|
254
|
-
const string
|
|
255
|
-
en: 'no cats | one cat | {n} cats'
|
|
277
|
+
const string = translator.t({
|
|
278
|
+
en: 'no cats | one cat | {n} cats',
|
|
256
279
|
de: 'keine Katzen | eine Katze | {n} Katzen'
|
|
257
280
|
}, { n })
|
|
258
|
-
// This will result in "no cats" or "keine
|
|
281
|
+
// This will result in "no cats" or "keine Katzen" when "n" is zero,
|
|
259
282
|
// "one cat" or "eine Katze" when "n" is 1, or
|
|
260
283
|
// "1,234.56 cats" or "1.234,56 Katzen" when "n" is 1234.56
|
|
261
284
|
```
|
|
262
285
|
|
|
263
|
-
|
|
286
|
+
This is equivalent to:
|
|
264
287
|
|
|
265
288
|
```typescript
|
|
266
|
-
const string
|
|
267
|
-
en: 'no cats | one cat | {n} cats'
|
|
289
|
+
const string = translator.tc({
|
|
290
|
+
en: 'no cats | one cat | {n} cats',
|
|
268
291
|
de: 'keine Katzen | eine Katze | {n} Katzen'
|
|
269
292
|
}, n)
|
|
270
293
|
```
|
|
271
294
|
|
|
272
295
|
|
|
296
|
+
Messages can also use explicit tuples instead of pipe-delimited strings:
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
const message = {
|
|
300
|
+
en: ['no cats', 'one cat', '{n} cats'],
|
|
301
|
+
de: ['keine Katzen', 'eine Katze', '{n} Katzen'],
|
|
302
|
+
} as const
|
|
303
|
+
|
|
304
|
+
translator.tc(message, 2) // '2 cats' or '2 Katzen'
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
A tuple with one element is used for every count. Two elements mean
|
|
308
|
+
`[singular, plural]`, with zero using the plural variant. Three elements mean
|
|
309
|
+
`[zero, singular, plural]`.
|
|
310
|
+
|
|
311
|
+
Tuple elements still support placeholders and escaped placeholders, but skip
|
|
312
|
+
pipe splitting and pipe unescaping entirely: `['A | B']` displays `A | B`.
|
|
313
|
+
|
|
314
|
+
Tuples work in base and regional translations, inline messages, and
|
|
315
|
+
`updateTranslations(...)`. They are copied when stored, so changing the
|
|
316
|
+
original array later cannot change stored messages or cached results.
|
|
317
|
+
|
|
318
|
+
|
|
273
319
|
## Formatting numbers
|
|
274
320
|
|
|
275
321
|
The `n(...)` function can be used to format numbers in the current locale:
|
|
@@ -280,7 +326,7 @@ import { useTranslator } from '@juit/vue-i18n'
|
|
|
280
326
|
const translator = useTranslator()
|
|
281
327
|
|
|
282
328
|
const number = translator.n(1234.5)
|
|
283
|
-
// the "number" string will be "1,234.5", "1.234,5"
|
|
329
|
+
// the "number" string will be "1,234.5", "1.234,5", etc., depending on the locale
|
|
284
330
|
```
|
|
285
331
|
|
|
286
332
|
A currency can be specified as a second parameter for quick formatting:
|
|
@@ -291,23 +337,23 @@ import { useTranslator } from '@juit/vue-i18n'
|
|
|
291
337
|
const translator = useTranslator()
|
|
292
338
|
|
|
293
339
|
const amount = translator.n(1234.5, 'USD')
|
|
294
|
-
// the "amount" will be "$1,234.
|
|
340
|
+
// the "amount" string will be "$1,234.50" in en-US
|
|
295
341
|
```
|
|
296
342
|
|
|
297
|
-
|
|
343
|
+
An [`Intl.NumberFormatOptions`][4] object can also be specified
|
|
298
344
|
as a second parameter to fine-tune the formatting.
|
|
299
345
|
|
|
300
|
-
The default format can be specified
|
|
301
|
-
|
|
346
|
+
The default format can be specified using `numberFormats.default` when
|
|
347
|
+
configuring the plugin.
|
|
302
348
|
|
|
303
349
|
|
|
304
350
|
## Formatting dates
|
|
305
351
|
|
|
306
|
-
The `d(...)` function can be used to format date
|
|
352
|
+
The `d(...)` function can be used to format date and time values in the current
|
|
307
353
|
locale.
|
|
308
354
|
|
|
309
355
|
When the second parameter is a string, it is considered to be one of the
|
|
310
|
-
_aliases_ configured when the plugin is
|
|
356
|
+
_aliases_ configured when the plugin is set up.
|
|
311
357
|
|
|
312
358
|
```typescript
|
|
313
359
|
import { useTranslator } from '@juit/vue-i18n'
|
|
@@ -316,15 +362,15 @@ const translator = useTranslator()
|
|
|
316
362
|
|
|
317
363
|
const dateTime = translator.d(new Date()) // e.g. '03.02.2025, 18:08:05' in de-DE
|
|
318
364
|
const dateOnly = translator.d(new Date(), 'date') // e.g. '03.02.2025' in de-DE
|
|
319
|
-
const
|
|
365
|
+
const timeOnly = translator.d(new Date(), 'time') // e.g. '18:08:05' in de-DE
|
|
320
366
|
```
|
|
321
367
|
|
|
322
|
-
|
|
368
|
+
An [`Intl.DateTimeFormatOptions`][5] object can also be specified
|
|
323
369
|
as a second parameter to fine-tune the formatting.
|
|
324
370
|
|
|
325
|
-
The third parameter, if specified, can be used to
|
|
371
|
+
The third parameter, if specified, can be used to override the time zone used
|
|
326
372
|
when formatting the date. This is useful when time zones are specified in
|
|
327
|
-
the
|
|
373
|
+
the definitions of date and time format _aliases_ (see above):
|
|
328
374
|
|
|
329
375
|
```typescript
|
|
330
376
|
import { useTranslator } from '@juit/vue-i18n'
|
|
@@ -336,17 +382,16 @@ translator.d(new Date(), 'full', 'Europe/Berlin')
|
|
|
336
382
|
```
|
|
337
383
|
|
|
338
384
|
|
|
339
|
-
|
|
340
385
|
## Configuring Types
|
|
341
386
|
|
|
342
|
-
One of the
|
|
343
|
-
translation languages (we don't want to forget to translate a message
|
|
387
|
+
One of the key features of this package is compile-time safety for all
|
|
388
|
+
translation languages (we don't want to forget to translate a message into
|
|
344
389
|
a new language) and translation keys (we don't want to mistype a translation
|
|
345
390
|
key by accident).
|
|
346
391
|
|
|
347
392
|
To do so, we can _merge_ the `I18nConfiguration` interface of this package
|
|
348
|
-
with our specific
|
|
349
|
-
|
|
393
|
+
with our application-specific configuration. The following properties can
|
|
394
|
+
be defined:
|
|
350
395
|
|
|
351
396
|
* `languages`: the list of supported languages for the application. These
|
|
352
397
|
are ISO 639-1 language codes, and when specified, _every_
|
|
@@ -355,9 +400,9 @@ in the configuration:
|
|
|
355
400
|
These are the arbitrary keys used to identify the
|
|
356
401
|
messages to be translated with the `t` and `tc`
|
|
357
402
|
methods of `Translator`.
|
|
358
|
-
* `dateTimeFormats`: the date and time
|
|
403
|
+
* `dateTimeFormats`: the date and time format _aliases_ used by the
|
|
359
404
|
application.
|
|
360
|
-
* `numberFormats`: the number
|
|
405
|
+
* `numberFormats`: the number format _aliases_ used by the application.
|
|
361
406
|
|
|
362
407
|
To configure the types, follow the example below:
|
|
363
408
|
|
|
@@ -403,11 +448,105 @@ const app = createApp(MyApp).use(i18n, {
|
|
|
403
448
|
In the example above, if any of the translation objects in our app is missing
|
|
404
449
|
a language (either `en` or `de`), TypeScript will complain.
|
|
405
450
|
|
|
406
|
-
In the same way, if we pass any other
|
|
407
|
-
`tc(...)`, TypeScript will report
|
|
451
|
+
In the same way, if we pass any string other than `hello` to `t(...)` or
|
|
452
|
+
`tc(...)`, TypeScript will report an invalid key.
|
|
453
|
+
|
|
454
|
+
Date, time, and number format alias types will also be augmented using the
|
|
455
|
+
customizations specified in `dateTimeFormats` and `numberFormats`.
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
## Updating Translations
|
|
459
|
+
|
|
460
|
+
Use `translator.utils.updateTranslations(...)` to add or change translations
|
|
461
|
+
after the plugin has been configured, for example when loading messages from
|
|
462
|
+
a server. Pass an object keyed by translation key, with language codes and
|
|
463
|
+
their translated messages as values:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import { useTranslator } from '@juit/vue-i18n'
|
|
467
|
+
|
|
468
|
+
const translator = useTranslator()
|
|
469
|
+
|
|
470
|
+
translator.utils.updateTranslations({
|
|
471
|
+
hello: {
|
|
472
|
+
en: 'Hello again!',
|
|
473
|
+
},
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
translator.language = 'en'
|
|
477
|
+
translator.t('hello') // 'Hello again!'
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Updates are merged into the existing translations: only the supplied
|
|
481
|
+
key-language pairs are overwritten. In this example, the German translation
|
|
482
|
+
of `hello` is preserved. New keys and language variants can also be added.
|
|
483
|
+
|
|
484
|
+
Both translation keys and languages are optional in an update, so you do not
|
|
485
|
+
need to supply every configured language. If you have configured
|
|
486
|
+
`I18nConfiguration`, TypeScript checks the supplied keys and languages against
|
|
487
|
+
those types.
|
|
488
|
+
|
|
489
|
+
Empty strings and `undefined` values are ignored; they cannot be used to
|
|
490
|
+
delete an existing translation. The method returns nothing and clears the
|
|
491
|
+
translation cache when an update is applied, so subsequent calls to `t(...)`
|
|
492
|
+
and `tc(...)` use the updated messages. Updating translations alone does not
|
|
493
|
+
trigger a Vue component re-render.
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
## Language Matching
|
|
497
|
+
|
|
498
|
+
The `LanguageMatcher` class selects a supported language from a user's
|
|
499
|
+
preferences. It can be used independently of the Vue plugin, for example to
|
|
500
|
+
choose the initial language from the browser's `navigator.languages`:
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
import { LanguageMatcher } from '@juit/vue-i18n'
|
|
504
|
+
|
|
505
|
+
const matcher = new LanguageMatcher([ 'en', 'de', 'ja' ])
|
|
506
|
+
|
|
507
|
+
matcher.defaultLanguage // 'en'
|
|
508
|
+
matcher.availableLanguages // [ 'en', 'de', 'ja' ]
|
|
509
|
+
|
|
510
|
+
const app = createApp(MyApp).use(i18n, {
|
|
511
|
+
defaultLanguage: matcher.match([ ...navigator.languages ]),
|
|
512
|
+
translations,
|
|
513
|
+
})
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
The constructor accepts a single ISO 639-1 language code (such as `'en'`) or
|
|
517
|
+
a non-empty array of codes. The first valid language is the default, used
|
|
518
|
+
whenever no preference matches.
|
|
519
|
+
|
|
520
|
+
The `match(...)` method accepts a string, an array of strings in preference
|
|
521
|
+
order, `null`, or `undefined`. It returns the **first supported preference**,
|
|
522
|
+
regardless of the order of the available languages:
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
matcher.match('de') // 'de'
|
|
526
|
+
matcher.match('JA-JP') // 'ja'
|
|
527
|
+
matcher.match('de_AT') // 'de'
|
|
528
|
+
matcher.match([ 'fr', 'ja-JP', 'de' ]) // 'ja'
|
|
529
|
+
matcher.match('fr') // 'en' (default)
|
|
530
|
+
matcher.match([]) // 'en' (default)
|
|
531
|
+
matcher.match(null) // 'en' (default)
|
|
532
|
+
matcher.match(undefined) // 'en' (default)
|
|
533
|
+
|
|
534
|
+
const englishOnly = new LanguageMatcher('en')
|
|
535
|
+
englishOnly.match('de') // 'en'
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
## Remarks
|
|
540
|
+
|
|
541
|
+
To keep the package small, the translator supports only the **language** and
|
|
542
|
+
optional **region** of a locale. Both `defaultLanguage` and assignments to
|
|
543
|
+
`translator.locale` discard script subtags and Unicode extensions, including
|
|
544
|
+
calendar and numbering-system preferences. For example,
|
|
545
|
+
`zh-Hant-TW-u-nu-hanidec` becomes `zh-TW`.
|
|
408
546
|
|
|
409
|
-
|
|
410
|
-
|
|
547
|
+
Changing `translator.language` preserves the current region: switching from
|
|
548
|
+
`en-CA` to `fr` produces `fr-CA`. Changing `translator.region` preserves the
|
|
549
|
+
language; setting it to `undefined` removes the region.
|
|
411
550
|
|
|
412
551
|
|
|
413
552
|
## Legal Stuff
|