@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: Plugin Sync JSON
5
5
  description: Sincronizza i dizionari Intlayer con file JSON i18n di terze parti (i18next, next-intl, react-intl, vue-i18n e altri). Mantieni il tuo i18n esistente mentre usi Intlayer per gestire, tradurre e testare i tuoi messaggi.
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: "Aggiunta l'opzione splitKeys (un dizionario per chiave namespace di primo livello) per layout a file singolo di next-intl / react-intl"
27
30
  - version: 7.5.0
28
31
  date: 2025-12-13
29
32
  changes: "Aggiunto supporto per i formati 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
- ## Avvio rapido
68
+ ## Plugins
69
+
70
+ Questo pacchetto fornisce due plugin:
71
+
72
+ - `loadJSON`: Carica file JSON nei dizionari Intlayer.
73
+ - Questo plugin viene utilizzato per caricare file JSON da una sorgente e verrà caricato nei dizionari Intlayer. Può scansionare l'intera codebase e cercare file JSON specifici.
74
+ Questo plugin può essere utilizzato
75
+ - se utilizzi una libreria i18n che impone una posizione specifica per il caricamento dei tuoi JSON (es: `next-intl`, `i18next`, `react-intl`, `vue-i18n`, ecc.), ma vuoi posizionare la dichiarazione del tuo contenuto dove vuoi nella tua codebase.
76
+ - Può anche essere utilizzato se vuoi recuperare i tuoi messaggi da una sorgente remota (es: un CMS, un'API, ecc.) e memorizzare i tuoi messaggi in file JSON.
77
+
78
+ > Sotto il cofano, questo plugin scansionerà l'intera codebase e cercherà file JSON specifici e li caricherà nei dizionari Intlayer.
79
+ > Nota che questo plugin non scriverà l'output e le traduzioni nei file JSON.
80
+
81
+ - `syncJSON`: Sincronizza i file JSON con i dizionari Intlayer.
82
+ - Questo plugin viene utilizzato per sincronizzare i file JSON con i dizionari Intlayer. Può scansionare la posizione data e caricare i JSON che corrispondono al pattern per file JSON specifici. Questo plugin è utile se vuoi ottenere i benefici di Intlayer mentre usi un'altra libreria i18n.
83
+
84
+ ## Usare entrambi i plugin
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
+ // Mantieni i tuoi file JSON attuali sincronizzati con i dizionari Intlayer
97
+ plugins: [
98
+ /**
99
+ * Caricherà tutti i file JSON in src che corrispondono al pattern {key}.i18n json
100
+ */
101
+ loadJSON({
102
+ source: ({ key }) => `./src/**/${key}.i18n.json`,
103
+ locale: Locales.ENGLISH,
104
+ priority: 1, // Assicura che questi file JSON abbiano la precedenza sui file in `./locales/en/${key}.json`
105
+ format: "intlayer", // Formato del contenuto JSON
106
+ }),
107
+ /**
108
+ * Caricherà e scriverà l'output e le traduzioni nei file JSON nella directory locales
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
+ ### Avvio rapido
66
125
 
67
126
  Aggiungi il plugin al tuo `intlayer.config.ts` e indirizzalo alla tua struttura JSON esistente.
68
127
 
@@ -81,6 +140,7 @@ const config: IntlayerConfig = {
81
140
  syncJSON({
82
141
  // Layout per locale, per namespace (es. next-intl, i18next con 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: file singolo per locale (comune con configurazioni 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
- ### Come funziona
174
+ #### Come funziona
102
175
 
103
176
  - Lettura: il plugin individua i file JSON dal tuo builder `source` e li carica come dizionari Intlayer.
104
177
  - Scrittura: dopo le build e i riempimenti, scrive i JSON localizzati negli stessi percorsi (con una newline finale per evitare problemi di formattazione).
@@ -112,6 +185,7 @@ syncJSON({
112
185
  location?: string, // etichetta opzionale, predefinito: "plugin"
113
186
  priority?: number, // priorità opzionale per la risoluzione dei conflitti, predefinito: 0
114
187
  format?: 'intlayer' | 'icu' | 'i18next', // formattatore opzionale, usato per la compatibilità con il runtime Intlayer
188
+ splitKeys?: boolean, // opzionale, divide un singolo file in un dizionario per chiave di primo livello (rilevamento automatico)
115
189
  });
116
190
  ```
117
191
 
@@ -136,17 +210,49 @@ syncJSON({
136
210
  }),
137
211
  ```
138
212
 
139
- ## Più sorgenti JSON e priorità
213
+ #### `splitKeys` (boolean)
214
+
215
+ Controlla se un singolo file JSON le cui **chiavi di primo livello sono namespace** debba diventare un dizionario per ogni chiave di primo livello, invece di un singolo dizionario che contiene l'intero file.
216
+
217
+ Questo corrisponde al modello di namespace di librerie come `next-intl` e `react-intl`, dove un file `messages/{locale}.json` raggruppa diversi namespace tramite le sue chiavi di primo livello, ciascuna indirizzata indipendentemente (ad esempio `useTranslations('Hero')` si risolve nel dizionario `Hero`).
218
+
219
+ - `undefined` (predefinito): **rilevamento automatico** — il file viene diviso quando il pattern `source` non ha un segmento `{key}` (un file contiene ogni namespace), e mantenuto come un singolo dizionario altrimenti (un file per chiave).
220
+ - `true`: divide sempre ogni chiave di primo livello nel proprio dizionario.
221
+ - `false`: non divide mai; l'intero file diventa un singolo dizionario.
222
+
223
+ Dato un singolo file `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, // implicito perché il pattern non ha un segmento `{key}`
238
+ }),
239
+ ```
240
+
241
+ Questo produce tre dizionari — `Hero`, `Nav` e `About` — quindi `useTranslations('Hero')` (next-intl) si risolve correttamente. Durante la riscrittura, tutti i namespace vengono riassemblati nello stesso file per locale.
242
+
243
+ > Quando mantieni il segmento `{key}` esplicito nel tuo `source` (ad esempio `./locales/${locale}/${key}.json`), ogni file è già un namespace, quindi la divisione è disabilitata per impostazione predefinita.
244
+
245
+ ### Multiple JSON sources and priority
140
246
 
141
247
  Puoi aggiungere più plugin `syncJSON` per sincronizzare diverse sorgenti JSON. Questo è utile quando hai più librerie i18n o diverse strutture JSON nel tuo progetto.
142
248
 
143
- ### Sistema di priorità
249
+ #### Sistema di priorità
144
250
 
145
251
  Quando più plugin puntano alla stessa chiave del dizionario, il parametro `priority` determina quale plugin ha la precedenza:
146
252
 
147
253
  - I numeri di priorità più alti prevalgono su quelli più bassi
148
254
  - La priorità predefinita dei file `.content` è `0`
149
- - La priorità predefinita dei file di contenuto dei plugin è `-1`
255
+ - La priorità predefinita dei plugin è `0`
150
256
  - I plugin con la stessa priorità vengono elaborati nell'ordine in cui appaiono nella configurazione
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
- ### Risoluzione dei conflitti
298
+ ## Load JSON plugin
193
299
 
194
- Quando la stessa chiave di traduzione esiste in più sorgenti JSON:
300
+ ### Quick start
195
301
 
196
- 1. Il plugin con la priorità più alta determina il valore finale
197
- 2. Le sorgenti con priorità inferiore vengono usate come fallback per le chiavi mancanti
198
- 3. Questo permette di mantenere le traduzioni legacy mentre si migra gradualmente verso nuove strutture
302
+ Aggiungi il plugin al tuo `intlayer.config.ts` per importare i file JSON esistenti come dizionari Intlayer. Questo plugin è di sola lettura (nessuna scrittura su disco):
199
303
 
200
- ## Integrazioni
304
+ ```ts fileName="intlayer.config.ts"
305
+ import { Locales, type IntlayerConfig } from "intlayer";
306
+ import { loadJSON } from "@intlayer/sync-json-plugin";
201
307
 
202
- Di seguito sono riportate le mappature comuni. Mantieni il tuo runtime intatto; aggiungi solo il plugin.
308
+ const config: IntlayerConfig = {
309
+ internationalization: {
310
+ locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
311
+ defaultLocale: Locales.ENGLISH,
312
+ },
313
+
314
+ plugins: [
315
+ // Ingerisci messaggi JSON situati ovunque nel tuo albero sorgente
316
+ loadJSON({
317
+ source: ({ key }) => `./src/**/${key}.i18n.json`,
318
+ // Carica una singola locale per istanza del plugin (predefinito alla defaultLocale della configurazione)
319
+ locale: Locales.ENGLISH,
320
+ priority: 0,
321
+ }),
322
+ ],
323
+ };
203
324
 
204
- ### i18next
325
+ export default config;
326
+ ```
205
327
 
206
- Layout tipico dei file: `./public/locales/{locale}/{namespace}.json` o `./locales/{locale}/{namespace}.json`.
328
+ Alternativa: layout per locale, ancora di sola lettura (viene caricata solo la locale selezionata):
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
+ // Solo i file per Locales.FRENCH verranno caricati da questo pattern
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
+ ### How it works
222
352
 
223
- Messaggi JSON per locale (spesso `./messages/{locale}.json`) o per namespace.
353
+ - Scopri: costruisce un glob dal tuo builder `source` e raccoglie i file JSON corrispondenti.
354
+ - Ingerisci: carica ogni file JSON come dizionario Intlayer con la `locale` fornita.
355
+ - Sola lettura: non scrive né formatta i file di output; usa `syncJSON` se hai bisogno di una sincronizzazione bidirezionale.
356
+ - Pronto per l'auto-fill: definisce un pattern `fill` in modo che `intlayer content fill` possa popolare le chiavi mancanti.
224
357
 
225
- ```ts fileName="intlayer.config.ts"
226
- plugins: [
227
- syncJSON({
228
- source: ({ locale, key }) => `./messages/${locale}/${key}.json`,
229
- }),
230
- ];
358
+ ### API
359
+
360
+ ```ts
361
+ loadJSON({
362
+ // Costruisci i percorsi ai tuoi JSON. `locale` è opzionale se la tua struttura non ha un segmento locale
363
+ source: ({ key, locale }) => string,
364
+
365
+ // Locale di destinazione per i dizionari caricati da questa istanza del plugin
366
+ // Predefinito a configuration.internationalization.defaultLocale
367
+ locale?: Locale,
368
+
369
+ // Etichetta opzionale per identificare la sorgente
370
+ location?: string, // predefinito: "plugin"
371
+
372
+ // Priorità utilizzata per la risoluzione dei conflitti contro altre sorgenti
373
+ priority?: number, // predefinito: 0
374
+
375
+ // Formattatore opzionale per il contenuto JSON
376
+ format?: 'intlayer' | 'icu' | 'i18next', // predefinito: 'intlayer'
377
+
378
+ // Divide un singolo file in un dizionario per chiave di primo livello (rilevamento automatico)
379
+ splitKeys?: boolean,
380
+ });
231
381
  ```
232
382
 
233
- Vedi anche: `docs/it/intlayer_with_next-intl.md`.
383
+ #### `format` ('intlayer' | 'icu' | 'i18next')
234
384
 
235
- ### react-intl
385
+ Specifica il formattatore da utilizzare per il contenuto del dizionario durante il caricamento dei file JSON. Ciò consente di utilizzare diverse sintassi di formattazione dei messaggi compatibili con varie librerie i18n.
236
386
 
237
- È comune un singolo JSON per locale:
387
+ - `'intlayer'`: Il formattatore Intlayer predefinito (predefinito).
388
+ - `'icu'`: Utilizza la formattazione dei messaggi ICU (compatibile con librerie come react-intl, vue-i18n).
389
+ - `'i18next'`: Utilizza la formattazione dei messaggi i18next (compatibile con 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
+ **Esempio:**
392
+
393
+ ```ts
394
+ loadJSON({
395
+ source: ({ key }) => `./src/**/${key}.i18n.json`,
396
+ locale: Locales.ENGLISH,
397
+ format: "icu", // Usa la formattazione ICU per la compatibilità
398
+ }),
245
399
  ```
246
400
 
247
- ### vue-i18n
401
+ #### `splitKeys` (boolean)
248
402
 
249
- Può essere un singolo file per locale o per namespace:
403
+ Stesso comportamento di [`syncJSON`](#splitkeys-boolean): quando un singolo file JSON raggruppa diversi namespace tramite le sue chiavi di primo livello, ogni chiave di primo livello diventa il proprio dizionario.
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` (predefinito): **rilevamento automatico** — divide quando il pattern `source` non ha un segmento `{key}`, singolo dizionario altrimenti.
406
+ - `true` / `false`: forza o disabilita la divisione.
407
+
408
+ ```ts
409
+ loadJSON({
410
+ source: ({ locale }) => `./messages/${locale}.json`,
411
+ format: "icu",
412
+ // splitKeys auto-enabled: `Hero`, `Nav`, `About`, … ciascuno diventa un dizionario
413
+ }),
257
414
  ```
258
415
 
416
+ ### Behavior and conventions
417
+
418
+ - Se la tua maschera `source` include un segnaposto per la locale, vengono ingeriti solo i file per la `locale` selezionata.
419
+ - Se non c'è un segmento `{key}` nella tua maschera, ogni chiave di primo livello del file diventa il proprio dizionario per impostazione predefinita (vedi [`splitKeys`](#splitkeys-boolean)). Imposta `splitKeys: false` per caricare invece l'intero file come un singolo dizionario `index`.
420
+ - Le chiavi sono derivate dai percorsi dei file sostituendo il segnaposto `{key}` nel tuo builder `source`.
421
+ - Il plugin utilizza solo i file scoperti e non fabbrica locali o chiavi mancanti.
422
+ - Il percorso `fill` è inferito dal tuo `source` e utilizzato per aggiornare i valori mancanti tramite CLI quando scegli di farlo.
423
+
424
+ ## Conflict resolution
425
+
426
+ Quando la stessa chiave di traduzione esiste in più sorgenti JSON:
427
+
428
+ 1. Il plugin con la priorità più alta determina il valore finale
429
+ 2. Le sorgenti con priorità inferiore vengono usate come fallback per le chiavi mancanti
430
+ 3. Questo permette di mantenere le traduzioni legacy mentre si migra gradualmente verso nuove strutture
431
+
259
432
  ## CLI
260
433
 
261
434
  I file JSON sincronizzati saranno considerati come altri file `.content`. Ciò significa che tutti i comandi di intlayer saranno disponibili per i file JSON sincronizzati. Inclusi:
@@ -268,13 +441,13 @@ I file JSON sincronizzati saranno considerati come altri file `.content`. Ciò s
268
441
 
269
442
  Vedi [Intlayer CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/it/cli/index.md) per maggiori dettagli.
270
443
 
271
- ## Limitazioni (attuali)
444
+ ## Limitations (current)
272
445
 
273
446
  - Nessun supporto per inserimenti o plurali/ICU quando si utilizzano librerie di terze parti.
274
447
  - L'editor visuale non è ancora disponibile per runtime non Intlayer.
275
448
  - Sincronizzazione solo di file JSON; i formati di catalogo non JSON non sono supportati.
276
449
 
277
- ## Perché è importante
450
+ ## Why this matters
278
451
 
279
452
  - Possiamo raccomandare soluzioni i18n consolidate e posizionare Intlayer come un componente aggiuntivo.
280
453
  - Sfruttiamo la loro SEO/parole chiave con tutorial che terminano suggerendo Intlayer per gestire JSON.