@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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-03-13
3
- updatedAt: 2025-12-13
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
- ## Szybki start
65
+ ## Plugins
63
66
 
64
- Dodaj wtyczkę do swojego pliku `intlayer.config.ts` i wskaż ją na istniejącą strukturę JSON.
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
- plugins: [
92
- syncJSON({
93
- source: ({ locale }) => `./locales/${locale}.json`,
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
- ### Jak to działa
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
- ## Wiele źródeł JSON i priorytet
210
+ #### `splitKeys` (boolean)
137
211
 
138
- Możesz dodać wiele wtyczek `syncJSON`, aby synchronizować różne źródła JSON. Jest to przydatne, gdy masz wiele bibliotek i18n lub różne struktury JSON w swoim projekcie.
212
+ Kontroluje, czy pojedynczy plik JSON, którego **klucze pierwszego poziomu 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
- ### System priorytetów
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
- ### Rozwiązywanie konfliktów
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
- Gdy ten sam klucz tłumaczenia występuje w wielu źródłach JSON:
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: 2025-12-13
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
- ## Início rápido
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
- plugins: [
95
- syncJSON({
96
- source: ({ locale }) => `./locales/${locale}.json`,
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
- ### Como funciona
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
- ## Múltiplas fontes JSON e prioridade
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
- ### Sistema de prioridade
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 arquivos de conteúdo dos plugins é `-1`
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
- ### Resolução de conflitos
298
+ ## Load JSON plugin
193
299
 
194
- Quando a mesma chave de tradução existe em múltiplas fontes JSON:
300
+ ### Início rápido
195
301
 
196
- 1. O plugin com a maior prioridade determina o valor final
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
- ## Integrações
304
+ ```ts fileName="intlayer.config.ts"
305
+ import { Locales, type IntlayerConfig } from "intlayer";
306
+ import { loadJSON } from "@intlayer/sync-json-plugin";
201
307
 
202
- Abaixo estão mapeamentos comuns. Mantenha seu runtime intacto; apenas adicione o plugin.
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
- ### i18next
325
+ export default config;
326
+ ```
205
327
 
206
- Layout típico de arquivo: `./public/locales/{locale}/{namespace}.json` ou `./locales/{locale}/{namespace}.json`.
328
+ Alternativa: layout por localidade, ainda somente leitura (apenas a localidade selecionada é carregada):
207
329
 
208
330
  ```ts fileName="intlayer.config.ts"
209
- import { syncJSON } from "@intlayer/sync-json-plugin";
331
+ import { Locales, type IntlayerConfig } from "intlayer";
332
+ import { loadJSON } from "@intlayer/sync-json-plugin";
210
333
 
211
- export default {
334
+ const config: IntlayerConfig = {
335
+ internationalization: {
336
+ locales: [Locales.ENGLISH, Locales.FRENCH],
337
+ defaultLocale: Locales.ENGLISH,
338
+ },
212
339
  plugins: [
213
- syncJSON({
214
- format: "i18next",
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
- ### next-intl
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
- Mensagens JSON por localidade (frequentemente `./messages/{locale}.json`) ou por namespace.
358
+ ### API
224
359
 
225
- ```ts fileName="intlayer.config.ts"
226
- plugins: [
227
- syncJSON({
228
- source: ({ locale, key }) => `./messages/${locale}/${key}.json`,
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
- Veja também: `docs/pt/intlayer_with_next-intl.md`.
383
+ #### `format` ('intlayer' | 'icu' | 'i18next')
234
384
 
235
- ### react-intl
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
- JSON único por localidade é comum:
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
- ```ts fileName="intlayer.config.ts"
240
- plugins: [
241
- syncJSON({
242
- source: ({ locale }) => `./locales/${locale}.json`,
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
- ### vue-i18n
401
+ #### `splitKeys` (boolean)
248
402
 
249
- Pode ser um único arquivo por localidade ou por namespace:
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
- ```ts fileName="intlayer.config.ts"
252
- plugins: [
253
- syncJSON({
254
- source: ({ key, locale }) => `./src/locales/${locale}/${key}.json`,
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: