@intlayer/docs 7.0.3 → 7.0.4
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/blog/ar/intlayer_with_i18next.md +68 -106
- package/blog/ar/intlayer_with_next-i18next.md +84 -288
- package/blog/ar/intlayer_with_next-intl.md +58 -337
- package/blog/ar/intlayer_with_react-i18next.md +68 -290
- package/blog/ar/intlayer_with_react-intl.md +63 -266
- package/blog/de/intlayer_with_i18next.md +77 -97
- package/blog/de/intlayer_with_next-i18next.md +69 -296
- package/blog/de/intlayer_with_next-intl.md +59 -340
- package/blog/de/intlayer_with_react-i18next.md +68 -290
- package/blog/de/intlayer_with_react-intl.md +62 -264
- package/blog/en/intlayer_with_i18next.md +67 -103
- package/blog/en/intlayer_with_next-i18next.md +69 -294
- package/blog/en/intlayer_with_next-intl.md +48 -300
- package/blog/en/intlayer_with_react-i18next.md +61 -289
- package/blog/en/intlayer_with_react-intl.md +61 -284
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/en-GB/intlayer_with_i18next.md +67 -103
- package/blog/en-GB/intlayer_with_next-i18next.md +71 -292
- package/blog/en-GB/intlayer_with_next-intl.md +58 -337
- package/blog/en-GB/intlayer_with_react-i18next.md +67 -289
- package/blog/en-GB/intlayer_with_react-intl.md +61 -264
- package/blog/es/intlayer_with_i18next.md +67 -103
- package/blog/es/intlayer_with_next-i18next.md +71 -296
- package/blog/es/intlayer_with_next-intl.md +57 -338
- package/blog/es/intlayer_with_react-i18next.md +68 -290
- package/blog/es/intlayer_with_react-intl.md +62 -265
- package/blog/fr/intlayer_with_i18next.md +66 -104
- package/blog/fr/intlayer_with_next-i18next.md +82 -285
- package/blog/fr/intlayer_with_next-intl.md +57 -338
- package/blog/fr/intlayer_with_react-i18next.md +67 -289
- package/blog/fr/intlayer_with_react-intl.md +61 -264
- package/blog/hi/intlayer_with_i18next.md +68 -104
- package/blog/hi/intlayer_with_next-i18next.md +74 -299
- package/blog/hi/intlayer_with_next-intl.md +57 -239
- package/blog/hi/intlayer_with_react-i18next.md +69 -291
- package/blog/hi/intlayer_with_react-intl.md +65 -268
- package/blog/id/intlayer_with_i18next.md +126 -0
- package/blog/id/intlayer_with_next-i18next.md +142 -0
- package/blog/id/intlayer_with_next-intl.md +113 -0
- package/blog/id/intlayer_with_react-i18next.md +124 -0
- package/blog/id/intlayer_with_react-intl.md +122 -0
- package/blog/it/intlayer_with_i18next.md +67 -103
- package/blog/it/intlayer_with_next-i18next.md +71 -296
- package/blog/it/intlayer_with_next-intl.md +57 -338
- package/blog/it/intlayer_with_react-i18next.md +68 -290
- package/blog/it/intlayer_with_react-intl.md +62 -265
- package/blog/ja/intlayer_with_i18next.md +68 -103
- package/blog/ja/intlayer_with_next-i18next.md +85 -283
- package/blog/ja/intlayer_with_next-intl.md +58 -336
- package/blog/ja/intlayer_with_react-i18next.md +68 -290
- package/blog/ja/intlayer_with_react-intl.md +62 -264
- package/blog/ko/intlayer_with_i18next.md +80 -96
- package/blog/ko/intlayer_with_next-i18next.md +85 -287
- package/blog/ko/intlayer_with_next-intl.md +68 -327
- package/blog/ko/intlayer_with_react-i18next.md +68 -290
- package/blog/ko/intlayer_with_react-intl.md +64 -266
- package/blog/pl/intlayer_with_i18next.md +126 -0
- package/blog/pl/intlayer_with_next-i18next.md +142 -0
- package/blog/pl/intlayer_with_next-intl.md +111 -0
- package/blog/pl/intlayer_with_react-i18next.md +124 -0
- package/blog/pl/intlayer_with_react-intl.md +122 -0
- package/blog/pt/intlayer_with_i18next.md +67 -103
- package/blog/pt/intlayer_with_next-i18next.md +72 -293
- package/blog/pt/intlayer_with_next-intl.md +57 -256
- package/blog/pt/intlayer_with_react-i18next.md +104 -78
- package/blog/pt/intlayer_with_react-intl.md +62 -266
- package/blog/ru/intlayer_with_i18next.md +66 -104
- package/blog/ru/intlayer_with_next-i18next.md +71 -296
- package/blog/ru/intlayer_with_next-intl.md +58 -337
- package/blog/ru/intlayer_with_react-i18next.md +68 -290
- package/blog/ru/intlayer_with_react-intl.md +62 -265
- package/blog/tr/intlayer_with_i18next.md +71 -107
- package/blog/tr/intlayer_with_next-i18next.md +72 -297
- package/blog/tr/intlayer_with_next-intl.md +58 -339
- package/blog/tr/intlayer_with_react-i18next.md +69 -291
- package/blog/tr/intlayer_with_react-intl.md +63 -285
- package/blog/vi/intlayer_with_i18next.md +126 -0
- package/blog/vi/intlayer_with_next-i18next.md +142 -0
- package/blog/vi/intlayer_with_next-intl.md +111 -0
- package/blog/vi/intlayer_with_react-i18next.md +124 -0
- package/blog/vi/intlayer_with_react-intl.md +122 -0
- package/blog/zh/intlayer_with_i18next.md +67 -102
- package/blog/zh/intlayer_with_next-i18next.md +72 -296
- package/blog/zh/intlayer_with_next-intl.md +58 -336
- package/blog/zh/intlayer_with_react-i18next.md +68 -290
- package/blog/zh/intlayer_with_react-intl.md +63 -106
- package/dist/cjs/generated/blog.entry.cjs +13 -1
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +13 -1
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +13 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +13 -1
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +13 -2
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +13 -2
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +13 -2
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs +13 -2
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
- package/dist/types/generated/legal.entry.d.ts.map +1 -1
- package/docs/ar/plugins/sync-json.md +244 -0
- package/docs/de/plugins/sync-json.md +244 -0
- package/docs/de/releases/v7.md +1 -18
- package/docs/en/CI_CD.md +1 -1
- package/docs/en/configuration.md +1 -1
- package/docs/en/formatters.md +1 -1
- package/docs/en/how_works_intlayer.md +1 -1
- package/docs/en/intlayer_CMS.md +1 -1
- package/docs/en/intlayer_cli.md +26 -1
- package/docs/en/intlayer_with_nextjs_14.md +3 -1
- package/docs/en/intlayer_with_nextjs_15.md +3 -1
- package/docs/en/intlayer_with_nextjs_16.md +3 -1
- package/docs/en/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en/intlayer_with_nuxt.md +1 -1
- package/docs/en/intlayer_with_react_native+expo.md +1 -1
- package/docs/en/intlayer_with_react_router_v7.md +1 -1
- package/docs/en/intlayer_with_tanstack.md +1 -1
- package/docs/en/intlayer_with_vite+preact.md +1 -1
- package/docs/en/intlayer_with_vite+react.md +1 -1
- package/docs/en/intlayer_with_vite+solid.md +1 -1
- package/docs/en/intlayer_with_vite+svelte.md +1 -1
- package/docs/en/intlayer_with_vite+vue.md +1 -1
- package/docs/en/plugins/sync-json.md +1 -1
- package/docs/en/roadmap.md +1 -1
- package/docs/en-GB/plugins/sync-json.md +244 -0
- package/docs/es/plugins/sync-json.md +244 -0
- package/docs/es/releases/v7.md +1 -18
- package/docs/fr/intlayer_with_nextjs_16.md +2 -51
- package/docs/fr/plugins/sync-json.md +244 -0
- package/docs/fr/releases/v7.md +1 -18
- package/docs/hi/intlayer_with_nextjs_16.md +3 -2
- package/docs/hi/plugins/sync-json.md +244 -0
- package/docs/id/plugins/sync-json.md +244 -0
- package/docs/id/releases/v7.md +1 -18
- package/docs/it/plugins/sync-json.md +244 -0
- package/docs/it/releases/v7.md +1 -18
- package/docs/ja/intlayer_with_nextjs_16.md +44 -205
- package/docs/ja/plugins/sync-json.md +244 -0
- package/docs/ja/releases/v7.md +1 -18
- package/docs/ko/plugins/sync-json.md +244 -0
- package/docs/ko/releases/v7.md +1 -18
- package/docs/pl/plugins/sync-json.md +244 -0
- package/docs/pt/intlayer_with_nextjs_16.md +1 -52
- package/docs/pt/plugins/sync-json.md +244 -0
- package/docs/ru/plugins/sync-json.md +244 -0
- package/docs/tr/plugins/sync-json.md +245 -0
- package/docs/vi/plugins/sync-json.md +244 -0
- package/docs/zh/plugins/sync-json.md +244 -0
- package/package.json +14 -14
- package/src/generated/blog.entry.ts +26 -3
- package/src/generated/docs.entry.ts +26 -3
- package/src/generated/frequentQuestions.entry.ts +26 -3
- package/src/generated/legal.entry.ts +26 -3
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-03-13
|
|
3
|
+
updatedAt: 2025-10-05
|
|
4
|
+
title: Sync JSON plugin
|
|
5
|
+
description: Synchronise Intlayer dictionaries with third‑party i18n JSON files (i18next, next-intl, react-intl, vue-i18n, and more). Keep your existing i18n while using Intlayer to manage, translate, and test your messages.
|
|
6
|
+
keywords:
|
|
7
|
+
- Intlayer
|
|
8
|
+
- Sync JSON
|
|
9
|
+
- i18next
|
|
10
|
+
- next-intl
|
|
11
|
+
- react-intl
|
|
12
|
+
- vue-i18n
|
|
13
|
+
- next-translate
|
|
14
|
+
- nuxt-i18n
|
|
15
|
+
- LinguiJS
|
|
16
|
+
- Polyglot.js
|
|
17
|
+
- Solid-i18next
|
|
18
|
+
- svelte-i18n
|
|
19
|
+
- i18n
|
|
20
|
+
- translations
|
|
21
|
+
slugs:
|
|
22
|
+
- doc
|
|
23
|
+
- plugin
|
|
24
|
+
- sync-json
|
|
25
|
+
history:
|
|
26
|
+
- version: 6.1.6
|
|
27
|
+
date: 2025-10-05
|
|
28
|
+
changes: Initial Sync JSON plugin documentation
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Sync JSON (i18n bridges)
|
|
32
|
+
|
|
33
|
+
Use Intlayer as an add‑on to your existing i18n stack. This plugin keeps your JSON messages in sync with Intlayer dictionaries so you can:
|
|
34
|
+
|
|
35
|
+
- Keep i18next, next‑intl, react‑intl, vue‑i18n, next‑translate, nuxt‑i18n, Solid‑i18next, svelte‑i18n, etc.
|
|
36
|
+
- Manage and translate your messages with Intlayer (CLI, CI, providers, CMS), without refactoring your app.
|
|
37
|
+
- Deliver tutorials and SEO content targeting each ecosystem, while recommending Intlayer as the JSON management layer.
|
|
38
|
+
|
|
39
|
+
Notes and current scope:
|
|
40
|
+
|
|
41
|
+
- Externalisation to the CMS works for translations and classic text.
|
|
42
|
+
- No support yet for insertions, plurals/ICU, or advanced runtime features of other libraries.
|
|
43
|
+
- The visual editor is not supported yet for third‑party i18n outputs.
|
|
44
|
+
|
|
45
|
+
### When to use this plugin
|
|
46
|
+
|
|
47
|
+
- You already use an i18n library and store messages in JSON files.
|
|
48
|
+
- You want AI-assisted fill, test in CI, and content operations without changing your rendering runtime.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pnpm add -D @intlayer/sync-json-plugin
|
|
54
|
+
# or
|
|
55
|
+
npm i -D @intlayer/sync-json-plugin
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick start
|
|
59
|
+
|
|
60
|
+
Add the plugin to your `intlayer.config.ts` and point it at your existing JSON structure.
|
|
61
|
+
|
|
62
|
+
```ts fileName="intlayer.config.ts"
|
|
63
|
+
import { defineConfig, Locales } from "intlayer";
|
|
64
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
65
|
+
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
internationalization: {
|
|
68
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
69
|
+
defaultLocale: Locales.ENGLISH,
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
// Keep your current JSON files in sync with Intlayer dictionaries
|
|
73
|
+
plugins: [
|
|
74
|
+
syncJSON({
|
|
75
|
+
// Per-locale, per-namespace layout (e.g., next-intl, i18next with namespaces)
|
|
76
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
77
|
+
}),
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Alternative: single file per locale (common with i18next/react-intl setups):
|
|
83
|
+
|
|
84
|
+
```ts fileName="intlayer.config.ts"
|
|
85
|
+
plugins: [
|
|
86
|
+
syncJSON({
|
|
87
|
+
source: ({ locale }) => `./locales/${locale}.json`,
|
|
88
|
+
}),
|
|
89
|
+
];
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### How it works
|
|
93
|
+
|
|
94
|
+
- Read: the plugin discovers JSON files from your `source` builder and loads them as Intlayer dictionaries.
|
|
95
|
+
- Write: after builds and fills, it writes localised JSON back to the same paths (with a final newline to avoid formatting issues).
|
|
96
|
+
- Auto‑fill: the plugin declares an `autoFill` path for each dictionary. Running `intlayer fill` updates only missing translations in your JSON files by default.
|
|
97
|
+
|
|
98
|
+
API:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
syncJSON({
|
|
102
|
+
source: ({ key, locale }) => string, // required
|
|
103
|
+
location?: string, // optional label, default: "plugin"
|
|
104
|
+
priority?: number, // optional priority for conflict resolution, default: 0
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Multiple JSON sources and priority
|
|
109
|
+
|
|
110
|
+
You can add multiple `syncJSON` plugins to synchronise different JSON sources. This is useful when you have multiple i18n libraries or different JSON structures in your project.
|
|
111
|
+
|
|
112
|
+
### Priority system
|
|
113
|
+
|
|
114
|
+
When multiple plugins target the same dictionary key, the `priority` parameter determines which plugin takes precedence:
|
|
115
|
+
|
|
116
|
+
- Higher priority numbers win over lower ones
|
|
117
|
+
- Default priority of `.content` files is `0`
|
|
118
|
+
- Default priority of plugins content files is `-1`
|
|
119
|
+
- Plugins with the same priority are processed in the order they appear in the configuration
|
|
120
|
+
|
|
121
|
+
```ts fileName="intlayer.config.ts"
|
|
122
|
+
import { defineConfig, Locales } from "intlayer";
|
|
123
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
124
|
+
|
|
125
|
+
export default defineConfig({
|
|
126
|
+
internationalization: {
|
|
127
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
128
|
+
defaultLocale: Locales.ENGLISH,
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
plugins: [
|
|
132
|
+
// Primary JSON source (highest priority)
|
|
133
|
+
syncJSON({
|
|
134
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
135
|
+
location: "main-translations",
|
|
136
|
+
priority: 10,
|
|
137
|
+
}),
|
|
138
|
+
|
|
139
|
+
// Fallback JSON source (lower priority)
|
|
140
|
+
syncJSON({
|
|
141
|
+
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
142
|
+
location: "fallback-translations",
|
|
143
|
+
priority: 5,
|
|
144
|
+
}),
|
|
145
|
+
|
|
146
|
+
// Legacy JSON source (lowest priority)
|
|
147
|
+
syncJSON({
|
|
148
|
+
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
149
|
+
location: "legacy-translations",
|
|
150
|
+
priority: 1,
|
|
151
|
+
}),
|
|
152
|
+
],
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Conflict resolution
|
|
157
|
+
|
|
158
|
+
When the same translation key exists in multiple JSON sources:
|
|
159
|
+
|
|
160
|
+
1. The plugin with the highest priority determines the final value
|
|
161
|
+
2. Lower priority sources are used as fallbacks for missing keys
|
|
162
|
+
3. This allows you to maintain legacy translations whilst gradually migrating to new structures
|
|
163
|
+
|
|
164
|
+
## Integrations
|
|
165
|
+
|
|
166
|
+
Below are common mappings. Keep your runtime untouched; only add the plugin.
|
|
167
|
+
|
|
168
|
+
### i18next
|
|
169
|
+
|
|
170
|
+
Typical file layout: `./public/locales/{locale}/{namespace}.json` or `./locales/{locale}/{namespace}.json`.
|
|
171
|
+
|
|
172
|
+
```ts fileName="intlayer.config.ts"
|
|
173
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
174
|
+
|
|
175
|
+
export default {
|
|
176
|
+
plugins: [
|
|
177
|
+
syncJSON({
|
|
178
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
179
|
+
}),
|
|
180
|
+
],
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### next-intl
|
|
185
|
+
|
|
186
|
+
Per-locale JSON messages (often `./messages/{locale}.json`) or per-namespace.
|
|
187
|
+
|
|
188
|
+
```ts fileName="intlayer.config.ts"
|
|
189
|
+
plugins: [
|
|
190
|
+
syncJSON({
|
|
191
|
+
source: ({ locale, key }) => `./messages/${locale}/${key}.json`,
|
|
192
|
+
}),
|
|
193
|
+
];
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
See also: `docs/en/intlayer_with_next-intl.md`.
|
|
197
|
+
|
|
198
|
+
### react-intl
|
|
199
|
+
|
|
200
|
+
A single JSON file per locale is common:
|
|
201
|
+
|
|
202
|
+
```ts fileName="intlayer.config.ts"
|
|
203
|
+
plugins: [
|
|
204
|
+
syncJSON({
|
|
205
|
+
source: ({ locale }) => `./locales/${locale}.json`,
|
|
206
|
+
}),
|
|
207
|
+
];
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### vue-i18n
|
|
211
|
+
|
|
212
|
+
Either a single file per locale or per-namespace:
|
|
213
|
+
|
|
214
|
+
```ts fileName="intlayer.config.ts"
|
|
215
|
+
plugins: [
|
|
216
|
+
syncJSON({
|
|
217
|
+
source: ({ key, locale }) => `./src/locales/${locale}/${key}.json`,
|
|
218
|
+
}),
|
|
219
|
+
];
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## CLI
|
|
223
|
+
|
|
224
|
+
The synchronised JSON files will be considered as other `.content` files. That means, all intlayer commands will be available for the synchronised JSON files. Including:
|
|
225
|
+
|
|
226
|
+
- `intlayer content test` to test if there are missing translations
|
|
227
|
+
- `intlayer content list` to list the synchronised JSON files
|
|
228
|
+
- `intlayer content fill` to fill the missing translations
|
|
229
|
+
- `intlayer content push` to push the synchronised JSON files
|
|
230
|
+
- `intlayer content pull` to pull the synchronised JSON files
|
|
231
|
+
|
|
232
|
+
See [Intlayer CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_cli.md) for more details.
|
|
233
|
+
|
|
234
|
+
## Limitations (current)
|
|
235
|
+
|
|
236
|
+
- No insertions or plurals/ICU support when targeting third‑party libraries.
|
|
237
|
+
- Visual editor is not available for non‑Intlayer runtimes yet.
|
|
238
|
+
- JSON synchronisation only; non‑JSON catalogue formats are not supported.
|
|
239
|
+
|
|
240
|
+
## Why this matters
|
|
241
|
+
|
|
242
|
+
- We can recommend established i18n solutions and position Intlayer as an add‑on.
|
|
243
|
+
- We leverage their SEO/keywords with tutorials that end by suggesting Intlayer to manage JSON.
|
|
244
|
+
- Expands the addressable audience from “new projects” to “any team already using i18n”.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-03-13
|
|
3
|
+
updatedAt: 2025-10-05
|
|
4
|
+
title: Plugin de sincronización JSON
|
|
5
|
+
description: Sincroniza los diccionarios de Intlayer con archivos JSON i18n de terceros (i18next, next-intl, react-intl, vue-i18n y más). Mantén tu i18n existente mientras usas Intlayer para gestionar, traducir y probar tus mensajes.
|
|
6
|
+
keywords:
|
|
7
|
+
- Intlayer
|
|
8
|
+
- Sincronización JSON
|
|
9
|
+
- i18next
|
|
10
|
+
- next-intl
|
|
11
|
+
- react-intl
|
|
12
|
+
- vue-i18n
|
|
13
|
+
- next-translate
|
|
14
|
+
- nuxt-i18n
|
|
15
|
+
- LinguiJS
|
|
16
|
+
- Polyglot.js
|
|
17
|
+
- Solid-i18next
|
|
18
|
+
- svelte-i18n
|
|
19
|
+
- i18n
|
|
20
|
+
- traducciones
|
|
21
|
+
slugs:
|
|
22
|
+
- doc
|
|
23
|
+
- plugin
|
|
24
|
+
- sync-json
|
|
25
|
+
history:
|
|
26
|
+
- version: 6.1.6
|
|
27
|
+
date: 2025-10-05
|
|
28
|
+
changes: Documentación inicial del plugin de sincronización JSON
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Sincronización JSON (puentes i18n)
|
|
32
|
+
|
|
33
|
+
Usa Intlayer como un complemento para tu stack i18n existente. Este plugin mantiene tus mensajes JSON sincronizados con los diccionarios de Intlayer para que puedas:
|
|
34
|
+
|
|
35
|
+
- Mantener i18next, next-intl, react-intl, vue-i18n, next-translate, nuxt-i18n, Solid-i18next, svelte-i18n, etc.
|
|
36
|
+
- Gestionar y traducir tus mensajes con Intlayer (CLI, CI, proveedores, CMS), sin necesidad de refactorizar tu aplicación.
|
|
37
|
+
- Publicar tutoriales y contenido SEO dirigido a cada ecosistema, mientras sugieres Intlayer como la capa de gestión de JSON.
|
|
38
|
+
|
|
39
|
+
Notas y alcance actual:
|
|
40
|
+
|
|
41
|
+
- La externalización al CMS funciona para traducciones y texto clásico.
|
|
42
|
+
- Aún no hay soporte para inserciones, plurales/ICU, o funciones avanzadas en tiempo de ejecución de otras bibliotecas.
|
|
43
|
+
- El editor visual aún no es compatible con salidas i18n de terceros.
|
|
44
|
+
|
|
45
|
+
### Cuándo usar este plugin
|
|
46
|
+
|
|
47
|
+
- Ya usas una biblioteca i18n y almacenas mensajes en archivos JSON.
|
|
48
|
+
- Quieres un llenado asistido por IA, pruebas en CI y operaciones de contenido sin cambiar tu tiempo de ejecución de renderizado.
|
|
49
|
+
|
|
50
|
+
## Instalación
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pnpm add -D @intlayer/sync-json-plugin
|
|
54
|
+
# o
|
|
55
|
+
npm i -D @intlayer/sync-json-plugin
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Inicio rápido
|
|
59
|
+
|
|
60
|
+
Agrega el plugin a tu `intlayer.config.ts` y apúntalo a tu estructura JSON existente.
|
|
61
|
+
|
|
62
|
+
```ts fileName="intlayer.config.ts"
|
|
63
|
+
import { defineConfig, Locales } from "intlayer";
|
|
64
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
65
|
+
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
internationalization: {
|
|
68
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
69
|
+
defaultLocale: Locales.ENGLISH,
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
// Mantén tus archivos JSON actuales sincronizados con los diccionarios de Intlayer
|
|
73
|
+
plugins: [
|
|
74
|
+
syncJSON({
|
|
75
|
+
// Diseño por idioma, por espacio de nombres (por ejemplo, next-intl, i18next con espacios de nombres)
|
|
76
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
77
|
+
}),
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Alternativa: archivo único por idioma (común en configuraciones i18next/react-intl):
|
|
83
|
+
|
|
84
|
+
```ts fileName="intlayer.config.ts"
|
|
85
|
+
plugins: [
|
|
86
|
+
syncJSON({
|
|
87
|
+
source: ({ locale }) => `./locales/${locale}.json`,
|
|
88
|
+
}),
|
|
89
|
+
];
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Cómo funciona
|
|
93
|
+
|
|
94
|
+
- Lectura: el plugin descubre archivos JSON desde tu generador `source` y los carga como diccionarios de Intlayer.
|
|
95
|
+
- Escritura: después de las compilaciones y llenados, escribe los JSON localizados de vuelta en las mismas rutas (con una nueva línea final para evitar problemas de formato).
|
|
96
|
+
- Auto‑relleno: el plugin declara una ruta `autoFill` para cada diccionario. Ejecutar `intlayer fill` actualiza solo las traducciones faltantes en tus archivos JSON por defecto.
|
|
97
|
+
|
|
98
|
+
API:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
syncJSON({
|
|
102
|
+
source: ({ key, locale }) => string, // requerido
|
|
103
|
+
location?: string, // etiqueta opcional, por defecto: "plugin"
|
|
104
|
+
priority?: number, // prioridad opcional para resolución de conflictos, por defecto: 0
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Múltiples fuentes JSON y prioridad
|
|
109
|
+
|
|
110
|
+
Puedes agregar múltiples plugins `syncJSON` para sincronizar diferentes fuentes JSON. Esto es útil cuando tienes múltiples bibliotecas i18n o diferentes estructuras JSON en tu proyecto.
|
|
111
|
+
|
|
112
|
+
### Sistema de prioridad
|
|
113
|
+
|
|
114
|
+
Cuando múltiples plugins apuntan a la misma clave del diccionario, el parámetro `priority` determina qué plugin tiene precedencia:
|
|
115
|
+
|
|
116
|
+
- Los números de prioridad más altos ganan sobre los más bajos
|
|
117
|
+
- La prioridad por defecto de los archivos `.content` es `0`
|
|
118
|
+
- La prioridad por defecto de los archivos de contenido de plugins es `-1`
|
|
119
|
+
- Los plugins con la misma prioridad se procesan en el orden en que aparecen en la configuración
|
|
120
|
+
|
|
121
|
+
```ts fileName="intlayer.config.ts"
|
|
122
|
+
import { defineConfig, Locales } from "intlayer";
|
|
123
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
124
|
+
|
|
125
|
+
export default defineConfig({
|
|
126
|
+
internationalization: {
|
|
127
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
128
|
+
defaultLocale: Locales.ENGLISH,
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
plugins: [
|
|
132
|
+
// Fuente JSON principal (mayor prioridad)
|
|
133
|
+
syncJSON({
|
|
134
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
135
|
+
location: "main-translations",
|
|
136
|
+
priority: 10,
|
|
137
|
+
}),
|
|
138
|
+
|
|
139
|
+
// Fuente JSON de respaldo (menor prioridad)
|
|
140
|
+
syncJSON({
|
|
141
|
+
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
142
|
+
location: "fallback-translations",
|
|
143
|
+
priority: 5,
|
|
144
|
+
}),
|
|
145
|
+
|
|
146
|
+
// Fuente JSON heredada (prioridad más baja)
|
|
147
|
+
syncJSON({
|
|
148
|
+
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
149
|
+
location: "legacy-translations",
|
|
150
|
+
priority: 1,
|
|
151
|
+
}),
|
|
152
|
+
],
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Resolución de conflictos
|
|
157
|
+
|
|
158
|
+
Cuando la misma clave de traducción existe en múltiples fuentes JSON:
|
|
159
|
+
|
|
160
|
+
1. El plugin con la prioridad más alta determina el valor final
|
|
161
|
+
2. Las fuentes con menor prioridad se usan como respaldo para claves faltantes
|
|
162
|
+
3. Esto permite mantener traducciones heredadas mientras se migra gradualmente a nuevas estructuras
|
|
163
|
+
|
|
164
|
+
## Integraciones
|
|
165
|
+
|
|
166
|
+
A continuación se muestran mapeos comunes. Mantén tu entorno de ejecución sin cambios; solo agrega el plugin.
|
|
167
|
+
|
|
168
|
+
### i18next
|
|
169
|
+
|
|
170
|
+
Disposición típica de archivos: `./public/locales/{locale}/{namespace}.json` o `./locales/{locale}/{namespace}.json`.
|
|
171
|
+
|
|
172
|
+
```ts fileName="intlayer.config.ts"
|
|
173
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
174
|
+
|
|
175
|
+
export default {
|
|
176
|
+
plugins: [
|
|
177
|
+
syncJSON({
|
|
178
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
179
|
+
}),
|
|
180
|
+
],
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### next-intl
|
|
185
|
+
|
|
186
|
+
Mensajes JSON por localidad (a menudo `./messages/{locale}.json`) o por espacio de nombres.
|
|
187
|
+
|
|
188
|
+
```ts fileName="intlayer.config.ts"
|
|
189
|
+
plugins: [
|
|
190
|
+
syncJSON({
|
|
191
|
+
source: ({ locale, key }) => `./messages/${locale}/${key}.json`,
|
|
192
|
+
}),
|
|
193
|
+
];
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Véase también: `docs/es/intlayer_with_next-intl.md`.
|
|
197
|
+
|
|
198
|
+
### react-intl
|
|
199
|
+
|
|
200
|
+
Es común un único JSON por localidad:
|
|
201
|
+
|
|
202
|
+
```ts fileName="intlayer.config.ts"
|
|
203
|
+
plugins: [
|
|
204
|
+
syncJSON({
|
|
205
|
+
source: ({ locale }) => `./locales/${locale}.json`,
|
|
206
|
+
}),
|
|
207
|
+
];
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### vue-i18n
|
|
211
|
+
|
|
212
|
+
Puede ser un solo archivo por locale o por namespace:
|
|
213
|
+
|
|
214
|
+
```ts fileName="intlayer.config.ts"
|
|
215
|
+
plugins: [
|
|
216
|
+
syncJSON({
|
|
217
|
+
source: ({ key, locale }) => `./src/locales/${locale}/${key}.json`,
|
|
218
|
+
}),
|
|
219
|
+
];
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## CLI
|
|
223
|
+
|
|
224
|
+
Los archivos JSON sincronizados serán considerados como otros archivos `.content`. Eso significa que todos los comandos de intlayer estarán disponibles para los archivos JSON sincronizados. Incluyendo:
|
|
225
|
+
|
|
226
|
+
- `intlayer content test` para probar si faltan traducciones
|
|
227
|
+
- `intlayer content list` para listar los archivos JSON sincronizados
|
|
228
|
+
- `intlayer content fill` para completar las traducciones faltantes
|
|
229
|
+
- `intlayer content push` para enviar los archivos JSON sincronizados
|
|
230
|
+
- `intlayer content pull` para descargar los archivos JSON sincronizados
|
|
231
|
+
|
|
232
|
+
Vea [Intlayer CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_cli.md) para más detalles.
|
|
233
|
+
|
|
234
|
+
## Limitaciones (actuales)
|
|
235
|
+
|
|
236
|
+
- No hay soporte para inserciones o plurales/ICU al dirigirse a bibliotecas de terceros.
|
|
237
|
+
- El editor visual aún no está disponible para entornos de ejecución que no sean Intlayer.
|
|
238
|
+
- Solo sincronización JSON; no se admiten formatos de catálogo que no sean JSON.
|
|
239
|
+
|
|
240
|
+
## Por qué esto es importante
|
|
241
|
+
|
|
242
|
+
- Podemos recomendar soluciones i18n establecidas y posicionar Intlayer como un complemento.
|
|
243
|
+
- Aprovechamos su SEO/palabras clave con tutoriales que terminan sugiriendo Intlayer para gestionar JSON.
|
|
244
|
+
- Amplía la audiencia objetivo desde “nuevos proyectos” hasta “cualquier equipo que ya use i18n”.
|
package/docs/es/releases/v7.md
CHANGED
|
@@ -411,23 +411,6 @@ El sistema automáticamente:
|
|
|
411
411
|
|
|
412
412
|
**Antes (v6):**
|
|
413
413
|
|
|
414
|
-
````typescript
|
|
415
|
-
export default {
|
|
416
|
-
#### Mapeo de configuración
|
|
417
|
-
|
|
418
|
-
| Configuración v6 | Configuración v7 |
|
|
419
|
-
| -------------------------- | ---------------------------------------------------- |
|
|
420
|
-
| `autoFill: xxx` | `fill: xxx` |
|
|
421
|
-
| `prefixDefault: false` | `mode: 'prefix-no-default'` |
|
|
422
|
-
| `prefixDefault: true` | `mode: 'prefix-all'` |
|
|
423
|
-
| `noPrefix: true` | `mode: 'no-prefix'` |
|
|
424
|
-
| `cookieName: 'my-locale'` | `storage: { type: 'cookie', name: 'my-locale' }` |
|
|
425
|
-
| `serverSetCookie: 'never'` | `storage: false` o eliminar la cookie del array de almacenamiento |
|
|
426
|
-
|
|
427
|
-
#### Ejemplo de migración
|
|
428
|
-
|
|
429
|
-
**Antes (v6):**
|
|
430
|
-
|
|
431
414
|
```typescript
|
|
432
415
|
export default {
|
|
433
416
|
middleware: {
|
|
@@ -439,7 +422,7 @@ export default {
|
|
|
439
422
|
noPrefix: false,
|
|
440
423
|
},
|
|
441
424
|
};
|
|
442
|
-
|
|
425
|
+
```
|
|
443
426
|
|
|
444
427
|
**Después (v7):**
|
|
445
428
|
|
|
@@ -931,26 +931,6 @@ module.exports = { generateMetadata };
|
|
|
931
931
|
|
|
932
932
|
Alternativement, vous pouvez utiliser la fonction `getTranslation` pour déclarer vos métadonnées. Cependant, il est recommandé d'utiliser des fichiers de déclaration de contenu afin d'automatiser la traduction de vos métadonnées et d'externaliser le contenu à un moment donné.
|
|
933
933
|
|
|
934
|
-
````typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat="typescript"
|
|
935
|
-
import {
|
|
936
|
-
type IConfigLocales,
|
|
937
|
-
getTranslation,
|
|
938
|
-
getMultilingualUrls,
|
|
939
|
-
} from "intlayer";
|
|
940
|
-
import type { Metadata } from "next";
|
|
941
|
-
import type { LocalPromiseParams } from "next-intlayer";
|
|
942
|
-
|
|
943
|
-
export const generateMetadata = async ({
|
|
944
|
-
params,
|
|
945
|
-
}: LocalPromiseParams): Promise<Metadata> => {
|
|
946
|
-
const { locale } = await params;
|
|
947
|
-
const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale);
|
|
948
|
-
|
|
949
|
-
return {
|
|
950
|
-
title: t<string>({
|
|
951
|
-
en: "My title",
|
|
952
|
-
Alternativement, vous pouvez utiliser la fonction `getTranslation` pour déclarer vos métadonnées. Cependant, il est recommandé d'utiliser des fichiers de déclaration de contenu afin d'automatiser la traduction de vos métadonnées et d'externaliser le contenu à un moment donné.
|
|
953
|
-
|
|
954
934
|
```typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat="typescript"
|
|
955
935
|
import {
|
|
956
936
|
type IConfigLocales,
|
|
@@ -981,7 +961,7 @@ export const generateMetadata = async ({
|
|
|
981
961
|
};
|
|
982
962
|
|
|
983
963
|
// ... Reste du code
|
|
984
|
-
|
|
964
|
+
```
|
|
985
965
|
|
|
986
966
|
```javascript fileName="src/app/[locale]/layout.mjs or src/app/[locale]/page.mjs" codeFormat="esm"
|
|
987
967
|
import { getTranslation, getMultilingualUrls } from "intlayer";
|
|
@@ -1007,37 +987,8 @@ export const generateMetadata = async ({ params }) => {
|
|
|
1007
987
|
// ... Reste du code
|
|
1008
988
|
```
|
|
1009
989
|
|
|
1010
|
-
```javascript fileName="src/app/[locale]/layout.cjs or src/app/[locale]/page.cjs" codeFormat="commonjs"
|
|
1011
|
-
const { getTranslation, getMultilingualUrls } = require("intlayer");
|
|
1012
|
-
|
|
1013
|
-
const generateMetadata = async ({ params }) => {
|
|
1014
|
-
const { locale } = await params;
|
|
1015
|
-
|
|
1016
|
-
const t = (content) => getTranslation(content, locale);
|
|
1017
|
-
|
|
1018
|
-
return {
|
|
1019
|
-
title: t({
|
|
1020
|
-
en: "My title",
|
|
1021
|
-
fr: "Mon titre",
|
|
1022
|
-
es: "Mi título",
|
|
1023
|
-
}),
|
|
1024
|
-
description: t({
|
|
1025
|
-
en: "My description",
|
|
1026
|
-
fr: "Ma description",
|
|
1027
|
-
es: "Mi descripción",
|
|
1028
|
-
}),
|
|
1029
|
-
};
|
|
1030
|
-
};
|
|
1031
|
-
|
|
1032
|
-
module.exports = { generateMetadata };
|
|
1033
|
-
|
|
1034
|
-
// ... Reste du code
|
|
1035
|
-
```
|
|
1036
|
-
|
|
1037
990
|
> En savoir plus sur l'optimisation des métadonnées [dans la documentation officielle de Next.js](https://nextjs.org/docs/app/building-your-application/optimizing/metadata).
|
|
1038
991
|
|
|
1039
|
-
````
|
|
1040
|
-
|
|
1041
992
|
```javascript fileName="src/app/[locale]/layout.cjs or src/app/[locale]/page.cjs" codeFormat="commonjs"
|
|
1042
993
|
const { getTranslation, getMultilingualUrls } = require("intlayer");
|
|
1043
994
|
|
|
@@ -1063,7 +1014,7 @@ const generateMetadata = async ({ params }) => {
|
|
|
1063
1014
|
module.exports = { generateMetadata };
|
|
1064
1015
|
|
|
1065
1016
|
// ... Reste du code
|
|
1066
|
-
|
|
1017
|
+
```
|
|
1067
1018
|
|
|
1068
1019
|
> En savoir plus sur l'optimisation des métadonnées [dans la documentation officielle de Next.js](https://nextjs.org/docs/app/building-your-application/optimizing/metadata).
|
|
1069
1020
|
|