@intlayer/docs 9.0.0-canary.2 → 9.0.0-canary.3
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/docs/ar/plugins/sync-json.md +222 -49
- package/docs/de/plugins/sync-json.md +222 -49
- package/docs/en/plugins/sync-json.md +56 -2
- package/docs/en-GB/plugins/sync-json.md +245 -13
- package/docs/es/plugins/sync-json.md +222 -49
- package/docs/fr/plugins/sync-json.md +244 -12
- package/docs/hi/plugins/sync-json.md +221 -48
- package/docs/id/plugins/sync-json.md +222 -49
- package/docs/it/plugins/sync-json.md +224 -51
- package/docs/ja/plugins/sync-json.md +222 -49
- package/docs/ko/plugins/sync-json.md +223 -50
- package/docs/pl/plugins/sync-json.md +246 -14
- package/docs/pt/plugins/sync-json.md +222 -49
- package/docs/ru/plugins/sync-json.md +269 -95
- package/docs/tr/plugins/sync-json.md +222 -50
- package/docs/uk/plugins/sync-json.md +56 -2
- package/docs/vi/plugins/sync-json.md +230 -57
- package/docs/zh/plugins/sync-json.md +223 -50
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-06-21
|
|
4
4
|
title: Wtyczka Sync JSON
|
|
5
5
|
description: Synchronizuj słowniki Intlayer z zewnętrznymi plikami JSON i18n (i18next, next-intl, react-intl, vue-i18n i inne). Zachowaj istniejące i18n, korzystając z Intlayer do zarządzania, tłumaczenia i testowania swoich komunikatów.
|
|
6
6
|
keywords:
|
|
@@ -24,6 +24,9 @@ slugs:
|
|
|
24
24
|
- sync-json
|
|
25
25
|
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
26
26
|
history:
|
|
27
|
+
- version: 9.0.0
|
|
28
|
+
date: 2026-06-21
|
|
29
|
+
changes: "Dodano opcję splitKeys (jeden słownik na klucz przestrzeni nazw najwyższego poziomu) dla układów jednoplikowych next-intl / react-intl"
|
|
27
30
|
- version: 6.1.6
|
|
28
31
|
date: 2025-10-05
|
|
29
32
|
changes: "Pierwsza dokumentacja wtyczki Sync JSON"
|
|
@@ -59,9 +62,65 @@ pnpm add -D @intlayer/sync-json-plugin
|
|
|
59
62
|
npm i -D @intlayer/sync-json-plugin
|
|
60
63
|
```
|
|
61
64
|
|
|
62
|
-
##
|
|
65
|
+
## Plugins
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
This package provides two plugins:
|
|
68
|
+
|
|
69
|
+
- `loadJSON`: Load JSON files into Intlayer dictionaries.
|
|
70
|
+
- This plugin is used to load JSON files from a source and will be loaded into Intlayer dictionaries. It can scan all the codebase and search for specific JSON files.
|
|
71
|
+
This plugin can be used
|
|
72
|
+
- if you use an i18n library that impose a specific location for your JSON to be loaded (ex: `next-intl`, `i18next`, `react-intl`, `vue-i18n`, etc.), but you want to place your content declaration where you want in your code base.
|
|
73
|
+
- It can also be used if you want to fetch your messages from a remote source (ex: a CMS, a API, etc.) and store your messages in JSON files.
|
|
74
|
+
|
|
75
|
+
> Under the hood, this plugin will scan all the codebase and search for specific JSON files and load them into Intlayer dictionaries.
|
|
76
|
+
> Note that this plugin will not write the output and translations back to the JSON files.
|
|
77
|
+
|
|
78
|
+
- `syncJSON`: Synchronize JSON files with Intlayer dictionaries.
|
|
79
|
+
- This plugin is used to synchronize JSON files with Intlayer dictionaries. It can scan the given location and load the JSON that match the pattern for specific JSON files. This plugin is useful if you want to get the benefits of Intlayer while using another i18n library.
|
|
80
|
+
|
|
81
|
+
## Using both plugins
|
|
82
|
+
|
|
83
|
+
```ts fileName="intlayer.config.ts"
|
|
84
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
85
|
+
import { loadJSON, syncJSON } from "@intlayer/sync-json-plugin";
|
|
86
|
+
|
|
87
|
+
const config: IntlayerConfig = {
|
|
88
|
+
internationalization: {
|
|
89
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
90
|
+
defaultLocale: Locales.ENGLISH,
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
// Keep your current JSON files in sync with Intlayer dictionaries
|
|
94
|
+
plugins: [
|
|
95
|
+
/**
|
|
96
|
+
* Will load all the JSON files in the src that match the pattern {key}.i18n json
|
|
97
|
+
*/
|
|
98
|
+
loadJSON({
|
|
99
|
+
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
100
|
+
locale: Locales.ENGLISH,
|
|
101
|
+
priority: 1, // Ensures these JSON files take precedence over files at `./locales/en/${key}.json`
|
|
102
|
+
format: "intlayer", // Format of the JSON content
|
|
103
|
+
}),
|
|
104
|
+
/**
|
|
105
|
+
* Will load, and write the output and translations back to the JSON files in the locales directory
|
|
106
|
+
*/
|
|
107
|
+
syncJSON({
|
|
108
|
+
format: "i18next",
|
|
109
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
110
|
+
priority: 0,
|
|
111
|
+
format: "i18next",
|
|
112
|
+
}),
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export default config;
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## `syncJSON` plugin
|
|
120
|
+
|
|
121
|
+
### Quick start
|
|
122
|
+
|
|
123
|
+
Add the plugin to your `intlayer.config.ts` and point it at your existing JSON structure.
|
|
65
124
|
|
|
66
125
|
```ts fileName="intlayer.config.ts"
|
|
67
126
|
import { Locales, type IntlayerConfig } from "intlayer";
|
|
@@ -78,6 +137,7 @@ const config: IntlayerConfig = {
|
|
|
78
137
|
syncJSON({
|
|
79
138
|
// Układ per-locale, per-namespace (np. next-intl, i18next z przestrzeniami nazw)
|
|
80
139
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
140
|
+
format: "icu",
|
|
81
141
|
}),
|
|
82
142
|
],
|
|
83
143
|
};
|
|
@@ -88,14 +148,27 @@ export default config;
|
|
|
88
148
|
Alternatywa: pojedynczy plik na locale (częste w konfiguracjach i18next/react-intl):
|
|
89
149
|
|
|
90
150
|
```ts fileName="intlayer.config.ts"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
151
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
152
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
153
|
+
|
|
154
|
+
const config: IntlayerConfig = {
|
|
155
|
+
internationalization: {
|
|
156
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
157
|
+
defaultLocale: Locales.ENGLISH,
|
|
158
|
+
},
|
|
159
|
+
plugins: [
|
|
160
|
+
syncJSON({
|
|
161
|
+
format: "i18next",
|
|
162
|
+
source: ({ locale }) => `./locales/${locale}.json`,
|
|
163
|
+
format: "i18next",
|
|
164
|
+
}),
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export default config;
|
|
96
169
|
```
|
|
97
170
|
|
|
98
|
-
|
|
171
|
+
#### How it works
|
|
99
172
|
|
|
100
173
|
- Odczyt: wtyczka wykrywa pliki JSON zdefiniowane przez twój builder `source` i ładuje je jako słowniki Intlayer.
|
|
101
174
|
- Zapis: po budowaniu i wypełnianiu, zapisuje zlokalizowane pliki JSON z powrotem pod te same ścieżki (z końcowym znakiem nowej linii, aby uniknąć problemów z formatowaniem).
|
|
@@ -109,6 +182,7 @@ syncJSON({
|
|
|
109
182
|
location?: string, // opcjonalna etykieta, domyślnie: "plugin"
|
|
110
183
|
priority?: number, // opcjonalny priorytet do rozstrzygania konfliktów, domyślnie: 0
|
|
111
184
|
format?: 'intlayer' | 'icu' | 'i18next', // opcjonalny formatator, używany dla kompatybilności z runtime Intlayer
|
|
185
|
+
splitKeys?: boolean, // opcjonalnie, dzieli pojedynczy plik na jeden słownik na klucz przestrzeni nazw najwyższego poziomu (automatycznie wykrywane)
|
|
112
186
|
});
|
|
113
187
|
```
|
|
114
188
|
|
|
@@ -133,11 +207,43 @@ syncJSON({
|
|
|
133
207
|
}),
|
|
134
208
|
```
|
|
135
209
|
|
|
136
|
-
|
|
210
|
+
#### `splitKeys` (boolean)
|
|
137
211
|
|
|
138
|
-
|
|
212
|
+
Kontroluje, czy pojedynczy plik JSON, którego **klucze pierwszego poziomu są przestrzeniami nazw**, powinien stać się jednym słownikiem na klucz najwyższego poziomu, zamiast pojedynczego słownika zawierającego cały plik.
|
|
139
213
|
|
|
140
|
-
|
|
214
|
+
Odpowiada to modelowi przestrzeni nazw bibliotek takich jak `next-intl` i `react-intl`, gdzie jeden plik `messages/{locale}.json` grupuje kilka przestrzeni nazw według kluczy pierwszego poziomu, z których każda jest adresowana niezależnie (np. `useTranslations('Hero')` rozwiązuje się do słownika `Hero`).
|
|
215
|
+
|
|
216
|
+
- `undefined` (domyślnie): **automatycznie wykrywane** — plik jest dzielony, gdy wzorzec `source` nie zawiera segmentu `{key}` (jeden plik zawiera każdą przestrzeń nazw), i zachowywany jako pojedynczy słownik w przeciwnym razie (jeden plik na klucz).
|
|
217
|
+
- `true`: zawsze dzieli każdy klucz najwyższego poziomu na własny słownik.
|
|
218
|
+
- `false`: nigdy nie dzieli; cały plik staje się pojedynczym słownikiem.
|
|
219
|
+
|
|
220
|
+
Biorąc pod uwagę pojedynczy plik `messages/{locale}.json`:
|
|
221
|
+
|
|
222
|
+
```json fileName="messages/en.json"
|
|
223
|
+
{
|
|
224
|
+
"Hero": { "title": "Full-stack developer" },
|
|
225
|
+
"Nav": { "work": "Work", "about": "About" },
|
|
226
|
+
"About": { "lead": "I build apps end to end." }
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```ts fileName="intlayer.config.ts"
|
|
231
|
+
syncJSON({
|
|
232
|
+
format: "icu",
|
|
233
|
+
source: ({ locale }) => `./messages/${locale}.json`,
|
|
234
|
+
// splitKeys: true, // domyślne, ponieważ wzorzec nie zawiera segmentu `{key}`
|
|
235
|
+
}),
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Tworzy to trzy słowniki — `Hero`, `Nav` i `About` — dzięki czemu `useTranslations('Hero')` (next-intl) rozwiązuje się poprawnie. Podczas zapisu zwrotnego wszystkie przestrzenie nazw są ponownie składane w ten sam plik dla danej lokalizacji.
|
|
239
|
+
|
|
240
|
+
> Kiedy zachowujesz jawny segment `{key}` w swoim `source` (np. `./locales/${locale}/${key}.json`), każdy plik jest już jedną przestrzenią nazw, więc dzielenie jest domyślnie wyłączone.
|
|
241
|
+
|
|
242
|
+
### Multiple JSON sources and priority
|
|
243
|
+
|
|
244
|
+
You can add multiple `syncJSON` plugins to synchronize different JSON sources. This is useful when you have multiple i18n libraries or different JSON structures in your project.
|
|
245
|
+
|
|
246
|
+
#### System priorytetów
|
|
141
247
|
|
|
142
248
|
Gdy wiele wtyczek celuje w ten sam klucz słownika, parametr `priority` decyduje, która wtyczka ma pierwszeństwo:
|
|
143
249
|
|
|
@@ -186,9 +292,135 @@ const config: IntlayerConfig = {
|
|
|
186
292
|
export default config;
|
|
187
293
|
```
|
|
188
294
|
|
|
189
|
-
|
|
295
|
+
## Load JSON plugin
|
|
296
|
+
|
|
297
|
+
### Quick start
|
|
298
|
+
|
|
299
|
+
Add the plugin to your `intlayer.config.ts` to ingest existing JSON files as Intlayer dictionaries. This plugin is read‑only (no writes to disk):
|
|
300
|
+
|
|
301
|
+
```ts fileName="intlayer.config.ts"
|
|
302
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
303
|
+
import { loadJSON } from "@intlayer/sync-json-plugin";
|
|
304
|
+
|
|
305
|
+
const config: IntlayerConfig = {
|
|
306
|
+
internationalization: {
|
|
307
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
308
|
+
defaultLocale: Locales.ENGLISH,
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
plugins: [
|
|
312
|
+
// Ingest JSON messages located anywhere in your source tree
|
|
313
|
+
loadJSON({
|
|
314
|
+
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
315
|
+
// Load a single locale per plugin instance (defaults to the config defaultLocale)
|
|
316
|
+
locale: Locales.ENGLISH,
|
|
317
|
+
priority: 0,
|
|
318
|
+
}),
|
|
319
|
+
],
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
export default config;
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Alternative: per‑locale layout, still read‑only (only the selected locale is loaded):
|
|
326
|
+
|
|
327
|
+
```ts fileName="intlayer.config.ts"
|
|
328
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
329
|
+
import { loadJSON } from "@intlayer/sync-json-plugin";
|
|
330
|
+
|
|
331
|
+
const config: IntlayerConfig = {
|
|
332
|
+
internationalization: {
|
|
333
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
334
|
+
defaultLocale: Locales.ENGLISH,
|
|
335
|
+
},
|
|
336
|
+
plugins: [
|
|
337
|
+
loadJSON({
|
|
338
|
+
// Only files for Locales.FRENCH will be loaded from this pattern
|
|
339
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
340
|
+
locale: Locales.FRENCH,
|
|
341
|
+
}),
|
|
342
|
+
],
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
export default config;
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### How it works
|
|
349
|
+
|
|
350
|
+
- Discover: builds a glob from your `source` builder and collects matching JSON files.
|
|
351
|
+
- Ingest: loads each JSON file as an Intlayer dictionary with the provided `locale`.
|
|
352
|
+
- Read‑only: does not write or format output files; use `syncJSON` if you need round‑trip sync.
|
|
353
|
+
- Auto‑fill ready: defines a `fill` pattern so `intlayer content fill` can populate missing keys.
|
|
354
|
+
|
|
355
|
+
### API
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
loadJSON({
|
|
359
|
+
// Build paths to your JSON. `locale` is optional if your structure has no locale segment
|
|
360
|
+
source: ({ key, locale }) => string,
|
|
361
|
+
|
|
362
|
+
// Target locale for the dictionaries loaded by this plugin instance
|
|
363
|
+
// Defaults to configuration.internationalization.defaultLocale
|
|
364
|
+
locale?: Locale,
|
|
365
|
+
|
|
366
|
+
// Optional label to identify the source
|
|
367
|
+
location?: string, // default: "plugin"
|
|
368
|
+
|
|
369
|
+
// Priority used for conflict resolution against other sources
|
|
370
|
+
priority?: number, // default: 0
|
|
371
|
+
|
|
372
|
+
// Optional formatter for the JSON content
|
|
373
|
+
format?: 'intlayer' | 'icu' | 'i18next', // default: 'intlayer'
|
|
374
|
+
|
|
375
|
+
// Split a single file into one dictionary per top-level key (auto-detected)
|
|
376
|
+
splitKeys?: boolean,
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
381
|
+
|
|
382
|
+
Specifies the formatter to use for the dictionary content when loading JSON files. This allows using different message formatting syntaxes compatible with various i18n libraries.
|
|
383
|
+
|
|
384
|
+
- `'intlayer'`: The default Intlayer formatter (default).
|
|
385
|
+
- `'icu'`: Uses ICU message formatting (compatible with libraries like react-intl, vue-i18n).
|
|
386
|
+
- `'i18next'`: Uses i18next message formatting (compatible with i18next, next-i18next, Solid-i18next).
|
|
387
|
+
|
|
388
|
+
**Example:**
|
|
389
|
+
|
|
390
|
+
```ts
|
|
391
|
+
loadJSON({
|
|
392
|
+
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
393
|
+
locale: Locales.ENGLISH,
|
|
394
|
+
format: "icu", // Use ICU formatting for compatibility
|
|
395
|
+
}),
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### `splitKeys` (boolean)
|
|
399
|
+
|
|
400
|
+
Takie samo zachowanie jak w [`syncJSON`](#splitkeys-boolean): gdy pojedynczy plik JSON grupuje kilka przestrzeni nazw według kluczy pierwszego poziomu, każdy klucz najwyższego poziomu staje się własnym słownikiem.
|
|
401
|
+
|
|
402
|
+
- `undefined` (domyślnie): **automatycznie wykrywane** — dzieli, gdy wzorzec `source` nie zawiera segmentu `{key}`, w przeciwnym razie pojedynczy słownik.
|
|
403
|
+
- `true` / `false`: wymusza lub wyłącza dzielenie.
|
|
404
|
+
|
|
405
|
+
```ts
|
|
406
|
+
loadJSON({
|
|
407
|
+
source: ({ locale }) => `./messages/${locale}.json`,
|
|
408
|
+
format: "icu",
|
|
409
|
+
// splitKeys auto-enabled: `Hero`, `Nav`, `About`, … each become a dictionary
|
|
410
|
+
}),
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Behavior and conventions
|
|
414
|
+
|
|
415
|
+
- If your `source` mask includes a locale placeholder, only files for the selected `locale` are ingested.
|
|
416
|
+
- Jeśli w masce nie ma segmentu `{key}`, każdy klucz najwyższego poziomu pliku staje się domyślnie własnym słownikiem (zobacz [`splitKeys`](#splitkeys-boolean)). Ustaw `splitKeys: false`, aby zamiast tego załadować cały plik jako pojedynczy słownik indeksowy.
|
|
417
|
+
- Keys are derived from file paths by substituting the `{key}` placeholder in your `source` builder.
|
|
418
|
+
- The plugin only uses discovered files and does not fabricate missing locales or keys.
|
|
419
|
+
- The `fill` path is inferred from your `source` and used to update missing values via CLI when you opt‑in.
|
|
420
|
+
|
|
421
|
+
## Conflict resolution
|
|
190
422
|
|
|
191
|
-
|
|
423
|
+
When the same translation key exists in multiple JSON sources:
|
|
192
424
|
|
|
193
425
|
1. Wtyczka o najwyższym priorytecie decyduje o ostatecznej wartości
|
|
194
426
|
2. Źródła o niższym priorytecie są używane jako zapasowe dla brakujących kluczy
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-06-21
|
|
4
4
|
title: Plugin Sync JSON
|
|
5
5
|
description: Sincronize os dicionários Intlayer com arquivos JSON i18n de terceiros (i18next, next-intl, react-intl, vue-i18n e mais). Mantenha seu i18n existente enquanto usa o Intlayer para gerenciar, traduzir e testar suas mensagens.
|
|
6
6
|
keywords:
|
|
@@ -24,6 +24,9 @@ slugs:
|
|
|
24
24
|
- sync-json
|
|
25
25
|
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
26
26
|
history:
|
|
27
|
+
- version: 9.0.0
|
|
28
|
+
date: 2026-06-21
|
|
29
|
+
changes: "Adiciona a opção splitKeys (um dicionário por chave de namespace de nível superior) para layouts de arquivo único next-intl / react-intl"
|
|
27
30
|
- version: 7.5.0
|
|
28
31
|
date: 2025-12-13
|
|
29
32
|
changes: "Adicionado suporte para formatos ICU e i18next"
|
|
@@ -62,7 +65,63 @@ pnpm add -D @intlayer/sync-json-plugin
|
|
|
62
65
|
npm i -D @intlayer/sync-json-plugin
|
|
63
66
|
```
|
|
64
67
|
|
|
65
|
-
##
|
|
68
|
+
## Plugins
|
|
69
|
+
|
|
70
|
+
Este pacote fornece dois plugins:
|
|
71
|
+
|
|
72
|
+
- `loadJSON`: Carrega arquivos JSON em dicionários Intlayer.
|
|
73
|
+
- Este plugin é usado para carregar arquivos JSON de uma fonte e será carregado em dicionários Intlayer. Ele pode escanear todo o codebase e procurar por arquivos JSON específicos.
|
|
74
|
+
Este plugin pode ser usado
|
|
75
|
+
- se você usa uma biblioteca i18n que impõe um local específico para seus JSONs serem carregados (ex: `next-intl`, `i18next`, `react-intl`, `vue-i18n`, etc.), mas você quer colocar sua declaração de conteúdo onde quiser em seu codebase.
|
|
76
|
+
- Também pode ser usado se você quiser buscar suas mensagens de uma fonte remota (ex: um CMS, uma API, etc.) e armazenar suas mensagens em arquivos JSON.
|
|
77
|
+
|
|
78
|
+
> Por baixo dos panos, este plugin escaneará todo o codebase e procurará por arquivos JSON específicos e os carregará em dicionários Intlayer.
|
|
79
|
+
> Note que este plugin não escreverá a saída e as traduções de volta para os arquivos JSON.
|
|
80
|
+
|
|
81
|
+
- `syncJSON`: Sincroniza arquivos JSON com dicionários Intlayer.
|
|
82
|
+
- Este plugin é usado para sincronizar arquivos JSON com dicionários Intlayer. Ele pode escanear o local fornecido e carregar o JSON que corresponde ao padrão para arquivos JSON específicos. Este plugin é útil se você quiser obter os benefícios do Intlayer enquanto usa outra biblioteca i18n.
|
|
83
|
+
|
|
84
|
+
## Usando ambos os plugins
|
|
85
|
+
|
|
86
|
+
```ts fileName="intlayer.config.ts"
|
|
87
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
88
|
+
import { loadJSON, syncJSON } from "@intlayer/sync-json-plugin";
|
|
89
|
+
|
|
90
|
+
const config: IntlayerConfig = {
|
|
91
|
+
internationalization: {
|
|
92
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
93
|
+
defaultLocale: Locales.ENGLISH,
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
// Mantenha seus arquivos JSON atuais sincronizados com os dicionários Intlayer
|
|
97
|
+
plugins: [
|
|
98
|
+
/**
|
|
99
|
+
* Irá carregar todos os arquivos JSON na src que correspondem ao padrão {key}.i18n json
|
|
100
|
+
*/
|
|
101
|
+
loadJSON({
|
|
102
|
+
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
103
|
+
locale: Locales.ENGLISH,
|
|
104
|
+
priority: 1, // Garante que esses arquivos JSON tenham precedência sobre os arquivos em `./locales/en/${key}.json`
|
|
105
|
+
format: "intlayer", // Formato do conteúdo JSON
|
|
106
|
+
}),
|
|
107
|
+
/**
|
|
108
|
+
* Irá carregar e escrever a saída e as traduções de volta para os arquivos JSON no diretório de localidades
|
|
109
|
+
*/
|
|
110
|
+
syncJSON({
|
|
111
|
+
format: "i18next",
|
|
112
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
113
|
+
priority: 0,
|
|
114
|
+
format: "i18next",
|
|
115
|
+
}),
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default config;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## `syncJSON` plugin
|
|
123
|
+
|
|
124
|
+
### Início rápido
|
|
66
125
|
|
|
67
126
|
Adicione o plugin ao seu `intlayer.config.ts` e aponte para sua estrutura JSON existente.
|
|
68
127
|
|
|
@@ -81,6 +140,7 @@ const config: IntlayerConfig = {
|
|
|
81
140
|
syncJSON({
|
|
82
141
|
// Layout por localidade, por namespace (por exemplo, next-intl, i18next com namespaces)
|
|
83
142
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
143
|
+
format: "icu",
|
|
84
144
|
}),
|
|
85
145
|
],
|
|
86
146
|
};
|
|
@@ -91,14 +151,27 @@ export default config;
|
|
|
91
151
|
Alternativa: arquivo único por localidade (comum em configurações i18next/react-intl):
|
|
92
152
|
|
|
93
153
|
```ts fileName="intlayer.config.ts"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
154
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
155
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
156
|
+
|
|
157
|
+
const config: IntlayerConfig = {
|
|
158
|
+
internationalization: {
|
|
159
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
160
|
+
defaultLocale: Locales.ENGLISH,
|
|
161
|
+
},
|
|
162
|
+
plugins: [
|
|
163
|
+
syncJSON({
|
|
164
|
+
format: "i18next",
|
|
165
|
+
source: ({ locale }) => `./locales/${locale}.json`,
|
|
166
|
+
format: "i18next",
|
|
167
|
+
}),
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export default config;
|
|
99
172
|
```
|
|
100
173
|
|
|
101
|
-
|
|
174
|
+
#### Como funciona
|
|
102
175
|
|
|
103
176
|
- Leitura: o plugin descobre arquivos JSON a partir do seu construtor `source` e os carrega como dicionários Intlayer.
|
|
104
177
|
- Escrita: após builds e preenchimentos, ele grava o JSON localizado de volta nos mesmos caminhos (com uma nova linha final para evitar problemas de formatação).
|
|
@@ -112,6 +185,7 @@ syncJSON({
|
|
|
112
185
|
location?: string, // rótulo opcional, padrão: "plugin"
|
|
113
186
|
priority?: number, // prioridade opcional para resolução de conflitos, padrão: 0
|
|
114
187
|
format?: 'intlayer' | 'icu' | 'i18next', // formatador opcional, usado para compatibilidade com o runtime Intlayer
|
|
188
|
+
splitKeys?: boolean, // opcional, divide um único arquivo em um dicionário por chave de nível superior (detecção automática)
|
|
115
189
|
});
|
|
116
190
|
```
|
|
117
191
|
|
|
@@ -136,17 +210,49 @@ syncJSON({
|
|
|
136
210
|
}),
|
|
137
211
|
```
|
|
138
212
|
|
|
139
|
-
|
|
213
|
+
#### `splitKeys` (boolean)
|
|
214
|
+
|
|
215
|
+
Controla se um único arquivo JSON cujas **chaves de primeiro nível são namespaces** deve se tornar um dicionário por chave de nível superior, em vez de um único dicionário contendo o arquivo inteiro.
|
|
216
|
+
|
|
217
|
+
Isso corresponde ao modelo de namespace de bibliotecas como `next-intl` e `react-intl`, onde um arquivo `messages/{locale}.json` agrupa vários namespaces por suas chaves de primeiro nível, cada um endereçado independentemente (por exemplo, `useTranslations('Hero')` resolve para o dicionário `Hero`).
|
|
218
|
+
|
|
219
|
+
- `undefined` (padrão): **detecção automática** — o arquivo é dividido quando o padrão `source` não possui um segmento `{key}` (um arquivo contém todos os namespaces), e mantido como um único dicionário caso contrário (um arquivo por chave).
|
|
220
|
+
- `true`: sempre divide cada chave de nível superior em seu próprio dicionário.
|
|
221
|
+
- `false`: nunca divide; o arquivo inteiro se torna um único dicionário.
|
|
222
|
+
|
|
223
|
+
Dado um único arquivo `messages/{locale}.json`:
|
|
224
|
+
|
|
225
|
+
```json fileName="messages/en.json"
|
|
226
|
+
{
|
|
227
|
+
"Hero": { "title": "Full-stack developer" },
|
|
228
|
+
"Nav": { "work": "Work", "about": "About" },
|
|
229
|
+
"About": { "lead": "I build apps end to end." }
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```ts fileName="intlayer.config.ts"
|
|
234
|
+
syncJSON({
|
|
235
|
+
format: "icu",
|
|
236
|
+
source: ({ locale }) => `./messages/${locale}.json`,
|
|
237
|
+
// splitKeys: true, // implícito porque o padrão não possui um segmento `{key}`
|
|
238
|
+
}),
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Isso produz três dicionários — `Hero`, `Nav` e `About` — de modo que `useTranslations('Hero')` (next-intl) resolve corretamente. Na gravação de volta, todos os namespaces são remontados no mesmo arquivo por localidade.
|
|
242
|
+
|
|
243
|
+
> Quando você mantém o segmento `{key}` explícito em sua `source` (por exemplo, `./locales/${locale}/${key}.json`), cada arquivo já é um namespace, então a divisão é desativada por padrão.
|
|
244
|
+
|
|
245
|
+
### Múltiplas fontes JSON e prioridade
|
|
140
246
|
|
|
141
247
|
Você pode adicionar múltiplos plugins `syncJSON` para sincronizar diferentes fontes JSON. Isso é útil quando você tem múltiplas bibliotecas i18n ou diferentes estruturas JSON no seu projeto.
|
|
142
248
|
|
|
143
|
-
|
|
249
|
+
#### Sistema de prioridade
|
|
144
250
|
|
|
145
251
|
Quando múltiplos plugins têm como alvo a mesma chave de dicionário, o parâmetro `priority` determina qual plugin tem precedência:
|
|
146
252
|
|
|
147
253
|
- Números de prioridade mais altos ganham sobre os mais baixos
|
|
148
254
|
- Prioridade padrão dos arquivos `.content` é `0`
|
|
149
|
-
- Prioridade padrão dos
|
|
255
|
+
- Prioridade padrão dos plugins é `0`
|
|
150
256
|
- Plugins com a mesma prioridade são processados na ordem em que aparecem na configuração
|
|
151
257
|
|
|
152
258
|
```ts fileName="intlayer.config.ts"
|
|
@@ -189,73 +295,140 @@ const config: IntlayerConfig = {
|
|
|
189
295
|
export default config;
|
|
190
296
|
```
|
|
191
297
|
|
|
192
|
-
|
|
298
|
+
## Load JSON plugin
|
|
193
299
|
|
|
194
|
-
|
|
300
|
+
### Início rápido
|
|
195
301
|
|
|
196
|
-
|
|
197
|
-
2. Fontes com prioridade menor são usadas como fallback para chaves ausentes
|
|
198
|
-
3. Isso permite manter traduções legadas enquanto migra gradualmente para novas estruturas
|
|
302
|
+
Adicione o plugin ao seu `intlayer.config.ts` para ingerir arquivos JSON existentes como dicionários Intlayer. Este plugin é somente leitura (não grava em disco):
|
|
199
303
|
|
|
200
|
-
|
|
304
|
+
```ts fileName="intlayer.config.ts"
|
|
305
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
306
|
+
import { loadJSON } from "@intlayer/sync-json-plugin";
|
|
201
307
|
|
|
202
|
-
|
|
308
|
+
const config: IntlayerConfig = {
|
|
309
|
+
internationalization: {
|
|
310
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
311
|
+
defaultLocale: Locales.ENGLISH,
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
plugins: [
|
|
315
|
+
// Ingerir mensagens JSON localizadas em qualquer lugar da sua árvore de origem
|
|
316
|
+
loadJSON({
|
|
317
|
+
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
318
|
+
// Carregar uma única localidade por instância de plugin (padrão para a defaultLocale da configuração)
|
|
319
|
+
locale: Locales.ENGLISH,
|
|
320
|
+
priority: 0,
|
|
321
|
+
}),
|
|
322
|
+
],
|
|
323
|
+
};
|
|
203
324
|
|
|
204
|
-
|
|
325
|
+
export default config;
|
|
326
|
+
```
|
|
205
327
|
|
|
206
|
-
|
|
328
|
+
Alternativa: layout por localidade, ainda somente leitura (apenas a localidade selecionada é carregada):
|
|
207
329
|
|
|
208
330
|
```ts fileName="intlayer.config.ts"
|
|
209
|
-
import {
|
|
331
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
332
|
+
import { loadJSON } from "@intlayer/sync-json-plugin";
|
|
210
333
|
|
|
211
|
-
|
|
334
|
+
const config: IntlayerConfig = {
|
|
335
|
+
internationalization: {
|
|
336
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
337
|
+
defaultLocale: Locales.ENGLISH,
|
|
338
|
+
},
|
|
212
339
|
plugins: [
|
|
213
|
-
|
|
214
|
-
|
|
340
|
+
loadJSON({
|
|
341
|
+
// Apenas arquivos para Locales.FRENCH serão carregados a partir deste padrão
|
|
215
342
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
343
|
+
locale: Locales.FRENCH,
|
|
216
344
|
}),
|
|
217
345
|
],
|
|
218
346
|
};
|
|
347
|
+
|
|
348
|
+
export default config;
|
|
219
349
|
```
|
|
220
350
|
|
|
221
|
-
###
|
|
351
|
+
### Como funciona
|
|
352
|
+
|
|
353
|
+
- Descobrir: constrói um glob a partir do seu construtor `source` e coleta arquivos JSON correspondentes.
|
|
354
|
+
- Ingerir: carrega cada arquivo JSON como um dicionário Intlayer com a `locale` fornecida.
|
|
355
|
+
- Somente leitura: não escreve ou formata arquivos de saída; use `syncJSON` se precisar de sincronização de ida e volta.
|
|
356
|
+
- Pronto para auto-preenchimento: define um padrão `fill` para que `intlayer content fill` possa preencher chaves ausentes.
|
|
222
357
|
|
|
223
|
-
|
|
358
|
+
### API
|
|
224
359
|
|
|
225
|
-
```ts
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
360
|
+
```ts
|
|
361
|
+
loadJSON({
|
|
362
|
+
// Constrói caminhos para o seu JSON. `locale` é opcional se sua estrutura não tiver um segmento de localidade
|
|
363
|
+
source: ({ key, locale }) => string,
|
|
364
|
+
|
|
365
|
+
// Localidade de destino para os dicionários carregados por esta instância de plugin
|
|
366
|
+
// Padrão para configuration.internationalization.defaultLocale
|
|
367
|
+
locale?: Locale,
|
|
368
|
+
|
|
369
|
+
// Rótulo opcional para identificar a fonte
|
|
370
|
+
location?: string, // padrão: "plugin"
|
|
371
|
+
|
|
372
|
+
// Prioridade usada para resolução de conflitos contra outras fontes
|
|
373
|
+
priority?: number, // padrão: 0
|
|
374
|
+
|
|
375
|
+
// Formatador opcional para o conteúdo JSON
|
|
376
|
+
format?: 'intlayer' | 'icu' | 'i18next', // padrão: 'intlayer'
|
|
377
|
+
|
|
378
|
+
// Divide um único arquivo em um dicionário por chave de nível superior (detecção automática)
|
|
379
|
+
splitKeys?: boolean,
|
|
380
|
+
});
|
|
231
381
|
```
|
|
232
382
|
|
|
233
|
-
|
|
383
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
234
384
|
|
|
235
|
-
|
|
385
|
+
Especifica o formatador a ser usado para o conteúdo do dicionário ao carregar arquivos JSON. Isso permite usar diferentes sintaxes de formatação de mensagens compatíveis com várias bibliotecas i18n.
|
|
236
386
|
|
|
237
|
-
|
|
387
|
+
- `'intlayer'`: O formatador Intlayer padrão (padrão).
|
|
388
|
+
- `'icu'`: Usa formatação de mensagens ICU (compatível com bibliotecas como react-intl, vue-i18n).
|
|
389
|
+
- `'i18next'`: Usa formatação de mensagens i18next (compatível com i18next, next-i18next, Solid-i18next).
|
|
238
390
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
})
|
|
244
|
-
|
|
391
|
+
**Exemplo:**
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
loadJSON({
|
|
395
|
+
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
396
|
+
locale: Locales.ENGLISH,
|
|
397
|
+
format: "icu", // Usar formatação ICU para compatibilidade
|
|
398
|
+
}),
|
|
245
399
|
```
|
|
246
400
|
|
|
247
|
-
|
|
401
|
+
#### `splitKeys` (boolean)
|
|
248
402
|
|
|
249
|
-
|
|
403
|
+
Mesmo comportamento que em [`syncJSON`](#splitkeys-boolean): quando um único arquivo JSON agrupa vários namespaces por suas chaves de primeiro nível, cada chave de nível superior se torna seu próprio dicionário.
|
|
250
404
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
405
|
+
- `undefined` (padrão): **detecção automática** — divide quando o padrão `source` não possui um segmento `{key}`, dicionário único caso contrário.
|
|
406
|
+
- `true` / `false`: força ou desabilita a divisão.
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
loadJSON({
|
|
410
|
+
source: ({ locale }) => `./messages/${locale}.json`,
|
|
411
|
+
format: "icu",
|
|
412
|
+
// splitKeys auto-enabled: `Hero`, `Nav`, `About`, … cada um se torna um dicionário
|
|
413
|
+
}),
|
|
257
414
|
```
|
|
258
415
|
|
|
416
|
+
### Comportamento e convenções
|
|
417
|
+
|
|
418
|
+
- Se sua máscara `source` incluir um placeholder de localidade, apenas os arquivos para a `locale` selecionada serão ingeridos.
|
|
419
|
+
- Se não houver um segmento `{key}` em sua máscara, cada chave de nível superior do arquivo se torna seu próprio dicionário por padrão (veja [`splitKeys`](#splitkeys-boolean)). Defina `splitKeys: false` para carregar o arquivo inteiro como um único dicionário `index`.
|
|
420
|
+
- As chaves são derivadas dos caminhos dos arquivos substituindo o placeholder `{key}` em seu construtor `source`.
|
|
421
|
+
- O plugin usa apenas arquivos descobertos e não fabrica localidades ou chaves ausentes.
|
|
422
|
+
- O caminho `fill` é inferido de sua `source` e usado para atualizar valores ausentes via CLI quando você opta por isso.
|
|
423
|
+
|
|
424
|
+
## Resolução de conflitos
|
|
425
|
+
|
|
426
|
+
Quando a mesma chave de tradução existe em múltiplas fontes JSON:
|
|
427
|
+
|
|
428
|
+
1. O plugin com a maior prioridade determina o valor final
|
|
429
|
+
2. Fontes com prioridade menor são usadas como fallbacks para chaves ausentes
|
|
430
|
+
3. Isso permite manter traduções legadas enquanto migra gradualmente para novas estruturas
|
|
431
|
+
|
|
259
432
|
## CLI
|
|
260
433
|
|
|
261
434
|
Os arquivos JSON sincronizados serão considerados como outros arquivos `.content`. Isso significa que todos os comandos do intlayer estarão disponíveis para os arquivos JSON sincronizados. Incluindo:
|