@intlayer/docs 7.3.15 → 7.5.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/intlayer_with_i18next.md +2 -0
- package/blog/ar/intlayer_with_next-i18next.md +2 -0
- package/blog/ar/intlayer_with_next-intl.md +2 -0
- package/blog/ar/intlayer_with_react-i18next.md +2 -0
- package/blog/ar/intlayer_with_react-intl.md +2 -0
- package/blog/ar/intlayer_with_vue-i18n.md +2 -0
- package/blog/de/intlayer_with_i18next.md +2 -0
- package/blog/de/intlayer_with_next-i18next.md +1 -0
- package/blog/de/intlayer_with_next-intl.md +2 -0
- package/blog/de/intlayer_with_react-i18next.md +2 -0
- package/blog/de/intlayer_with_react-intl.md +2 -0
- package/blog/de/intlayer_with_vue-i18n.md +2 -0
- package/blog/en/intlayer_with_i18next.md +6 -0
- package/blog/en/intlayer_with_next-i18next.md +3 -0
- package/blog/en/intlayer_with_next-intl.md +3 -0
- package/blog/en/intlayer_with_react-i18next.md +3 -0
- package/blog/en/intlayer_with_react-intl.md +3 -0
- package/blog/en/intlayer_with_vue-i18n.md +3 -0
- package/blog/en-GB/intlayer_with_i18next.md +2 -0
- package/blog/en-GB/intlayer_with_next-i18next.md +2 -0
- package/blog/en-GB/intlayer_with_next-intl.md +2 -0
- package/blog/en-GB/intlayer_with_react-i18next.md +2 -0
- package/blog/en-GB/intlayer_with_react-intl.md +2 -0
- package/blog/en-GB/intlayer_with_vue-i18n.md +2 -0
- package/blog/es/intlayer_with_i18next.md +2 -0
- package/blog/es/intlayer_with_next-i18next.md +2 -0
- package/blog/es/intlayer_with_next-intl.md +2 -0
- package/blog/es/intlayer_with_react-i18next.md +2 -0
- package/blog/es/intlayer_with_react-intl.md +2 -0
- package/blog/es/intlayer_with_vue-i18n.md +2 -0
- package/blog/fr/intlayer_with_i18next.md +2 -0
- package/blog/fr/intlayer_with_next-i18next.md +2 -0
- package/blog/fr/intlayer_with_next-intl.md +2 -0
- package/blog/fr/intlayer_with_react-i18next.md +2 -0
- package/blog/fr/intlayer_with_react-intl.md +2 -0
- package/blog/fr/intlayer_with_vue-i18n.md +2 -0
- package/blog/hi/intlayer_with_i18next.md +2 -0
- package/blog/hi/intlayer_with_next-i18next.md +2 -0
- package/blog/hi/intlayer_with_next-intl.md +2 -0
- package/blog/hi/intlayer_with_react-i18next.md +2 -0
- package/blog/hi/intlayer_with_react-intl.md +2 -0
- package/blog/hi/intlayer_with_vue-i18n.md +2 -0
- package/blog/id/intlayer_with_i18next.md +2 -0
- package/blog/id/intlayer_with_next-i18next.md +2 -0
- package/blog/id/intlayer_with_next-intl.md +2 -0
- package/blog/id/intlayer_with_react-i18next.md +2 -0
- package/blog/id/intlayer_with_react-intl.md +2 -0
- package/blog/id/intlayer_with_vue-i18n.md +2 -0
- package/blog/it/intlayer_with_i18next.md +2 -0
- package/blog/it/intlayer_with_next-i18next.md +2 -0
- package/blog/it/intlayer_with_next-intl.md +2 -0
- package/blog/it/intlayer_with_react-i18next.md +2 -0
- package/blog/it/intlayer_with_react-intl.md +2 -0
- package/blog/it/intlayer_with_vue-i18n.md +2 -0
- package/blog/ja/intlayer_with_i18next.md +2 -0
- package/blog/ja/intlayer_with_next-i18next.md +1 -0
- package/blog/ja/intlayer_with_next-intl.md +2 -0
- package/blog/ja/intlayer_with_react-i18next.md +2 -0
- package/blog/ja/intlayer_with_react-intl.md +2 -0
- package/blog/ja/intlayer_with_vue-i18n.md +2 -0
- package/blog/ko/intlayer_with_i18next.md +2 -0
- package/blog/ko/intlayer_with_next-i18next.md +2 -0
- package/blog/ko/intlayer_with_next-intl.md +2 -0
- package/blog/ko/intlayer_with_react-i18next.md +2 -0
- package/blog/ko/intlayer_with_react-intl.md +2 -0
- package/blog/ko/intlayer_with_vue-i18n.md +2 -0
- package/blog/pl/intlayer_with_i18next.md +2 -0
- package/blog/pl/intlayer_with_next-i18next.md +2 -0
- package/blog/pl/intlayer_with_next-intl.md +2 -0
- package/blog/pl/intlayer_with_react-i18next.md +2 -0
- package/blog/pl/intlayer_with_react-intl.md +2 -0
- package/blog/pl/intlayer_with_vue-i18n.md +2 -0
- package/blog/pt/intlayer_with_i18next.md +2 -0
- package/blog/pt/intlayer_with_next-i18next.md +2 -0
- package/blog/pt/intlayer_with_next-intl.md +2 -0
- package/blog/pt/intlayer_with_react-i18next.md +2 -0
- package/blog/pt/intlayer_with_react-intl.md +2 -0
- package/blog/pt/intlayer_with_vue-i18n.md +2 -0
- package/blog/ru/intlayer_with_i18next.md +2 -0
- package/blog/ru/intlayer_with_next-i18next.md +2 -0
- package/blog/ru/intlayer_with_next-intl.md +2 -0
- package/blog/ru/intlayer_with_react-i18next.md +2 -0
- package/blog/ru/intlayer_with_react-intl.md +2 -0
- package/blog/ru/intlayer_with_vue-i18n.md +2 -0
- package/blog/tr/intlayer_with_i18next.md +2 -0
- package/blog/tr/intlayer_with_next-i18next.md +2 -0
- package/blog/tr/intlayer_with_next-intl.md +2 -0
- package/blog/tr/intlayer_with_react-i18next.md +2 -0
- package/blog/tr/intlayer_with_react-intl.md +2 -0
- package/blog/tr/intlayer_with_vue-i18n.md +2 -0
- package/blog/vi/intlayer_with_i18next.md +2 -0
- package/blog/vi/intlayer_with_next-i18next.md +2 -0
- package/blog/vi/intlayer_with_next-intl.md +2 -0
- package/blog/vi/intlayer_with_react-i18next.md +2 -0
- package/blog/vi/intlayer_with_react-intl.md +2 -0
- package/blog/vi/intlayer_with_vue-i18n.md +2 -0
- package/blog/zh/intlayer_with_i18next.md +2 -0
- package/blog/zh/intlayer_with_next-i18next.md +2 -0
- package/blog/zh/intlayer_with_next-intl.md +2 -0
- package/blog/zh/intlayer_with_react-i18next.md +2 -0
- package/blog/zh/intlayer_with_react-intl.md +2 -0
- package/blog/zh/intlayer_with_vue-i18n.md +2 -0
- package/docs/ar/dictionary/content_file.md +24 -1
- package/docs/ar/intlayer_with_astro.md +1 -1
- package/docs/ar/intlayer_with_express.md +1 -1
- package/docs/ar/intlayer_with_nestjs.md +1 -1
- package/docs/ar/intlayer_with_next-i18next.md +1 -0
- package/docs/ar/intlayer_with_next-intl.md +1 -0
- package/docs/ar/intlayer_with_tanstack.md +122 -3
- package/docs/ar/plugins/sync-json.md +27 -2
- package/docs/de/dictionary/content_file.md +24 -1
- package/docs/de/intlayer_with_astro.md +1 -1
- package/docs/de/intlayer_with_express.md +1 -1
- package/docs/de/intlayer_with_nestjs.md +1 -1
- package/docs/de/intlayer_with_next-i18next.md +1 -0
- package/docs/de/intlayer_with_next-intl.md +1 -0
- package/docs/de/intlayer_with_tanstack.md +122 -3
- package/docs/de/plugins/sync-json.md +27 -2
- package/docs/en/dictionary/content_file.md +24 -1
- package/docs/en/intlayer_with_astro.md +1 -1
- package/docs/en/intlayer_with_express.md +1 -1
- package/docs/en/intlayer_with_nestjs.md +1 -2
- package/docs/en/intlayer_with_next-i18next.md +1 -0
- package/docs/en/intlayer_with_next-intl.md +1 -0
- package/docs/en/intlayer_with_tanstack.md +120 -1
- package/docs/en/plugins/sync-json.md +53 -2
- package/docs/en-GB/dictionary/content_file.md +24 -1
- package/docs/en-GB/intlayer_with_astro.md +1 -1
- package/docs/en-GB/intlayer_with_express.md +1 -1
- package/docs/en-GB/intlayer_with_nestjs.md +1 -1
- package/docs/en-GB/intlayer_with_next-i18next.md +1 -0
- package/docs/en-GB/intlayer_with_next-intl.md +1 -0
- package/docs/en-GB/intlayer_with_tanstack.md +121 -2
- package/docs/en-GB/plugins/sync-json.md +26 -1
- package/docs/es/dictionary/content_file.md +24 -1
- package/docs/es/intlayer_with_astro.md +1 -1
- package/docs/es/intlayer_with_express.md +1 -1
- package/docs/es/intlayer_with_nestjs.md +1 -1
- package/docs/es/intlayer_with_next-i18next.md +1 -0
- package/docs/es/intlayer_with_next-intl.md +1 -0
- package/docs/es/intlayer_with_tanstack.md +122 -3
- package/docs/es/plugins/sync-json.md +27 -2
- package/docs/fr/dictionary/content_file.md +24 -1
- package/docs/fr/intlayer_with_astro.md +1 -1
- package/docs/fr/intlayer_with_express.md +1 -1
- package/docs/fr/intlayer_with_nestjs.md +1 -1
- package/docs/fr/intlayer_with_next-i18next.md +1 -0
- package/docs/fr/intlayer_with_next-intl.md +1 -0
- package/docs/fr/intlayer_with_tanstack.md +122 -3
- package/docs/fr/plugins/sync-json.md +27 -2
- package/docs/hi/dictionary/content_file.md +24 -1
- package/docs/hi/intlayer_with_astro.md +1 -1
- package/docs/hi/intlayer_with_express.md +1 -1
- package/docs/hi/intlayer_with_nestjs.md +1 -1
- package/docs/hi/intlayer_with_next-i18next.md +1 -0
- package/docs/hi/intlayer_with_next-intl.md +1 -0
- package/docs/hi/intlayer_with_tanstack.md +122 -3
- package/docs/hi/plugins/sync-json.md +27 -2
- package/docs/id/dictionary/content_file.md +24 -1
- package/docs/id/intlayer_with_astro.md +1 -1
- package/docs/id/intlayer_with_express.md +1 -1
- package/docs/id/intlayer_with_nestjs.md +1 -1
- package/docs/id/intlayer_with_next-i18next.md +1 -0
- package/docs/id/intlayer_with_next-intl.md +1 -0
- package/docs/id/intlayer_with_tanstack.md +122 -3
- package/docs/id/plugins/sync-json.md +27 -2
- package/docs/it/dictionary/content_file.md +24 -1
- package/docs/it/intlayer_with_astro.md +1 -1
- package/docs/it/intlayer_with_express.md +1 -1
- package/docs/it/intlayer_with_nestjs.md +1 -1
- package/docs/it/intlayer_with_next-i18next.md +1 -0
- package/docs/it/intlayer_with_next-intl.md +1 -0
- package/docs/it/intlayer_with_tanstack.md +122 -3
- package/docs/it/plugins/sync-json.md +27 -2
- package/docs/ja/dictionary/content_file.md +24 -1
- package/docs/ja/intlayer_with_astro.md +1 -1
- package/docs/ja/intlayer_with_express.md +1 -1
- package/docs/ja/intlayer_with_nestjs.md +1 -1
- package/docs/ja/intlayer_with_next-i18next.md +1 -0
- package/docs/ja/intlayer_with_next-intl.md +1 -0
- package/docs/ja/intlayer_with_tanstack.md +122 -3
- package/docs/ja/plugins/sync-json.md +27 -2
- package/docs/ko/dictionary/content_file.md +44 -1
- package/docs/ko/intlayer_with_astro.md +1 -1
- package/docs/ko/intlayer_with_express.md +1 -1
- package/docs/ko/intlayer_with_nestjs.md +1 -1
- package/docs/ko/intlayer_with_next-i18next.md +1 -0
- package/docs/ko/intlayer_with_next-intl.md +1 -0
- package/docs/ko/intlayer_with_tanstack.md +122 -3
- package/docs/ko/plugins/sync-json.md +27 -2
- package/docs/pl/dictionary/content_file.md +24 -1
- package/docs/pl/intlayer_with_astro.md +2 -2
- package/docs/pl/intlayer_with_express.md +1 -1
- package/docs/pl/intlayer_with_nestjs.md +1 -1
- package/docs/pl/intlayer_with_next-i18next.md +1 -0
- package/docs/pl/intlayer_with_next-intl.md +1 -0
- package/docs/pl/intlayer_with_tanstack.md +122 -3
- package/docs/pl/plugins/sync-json.md +24 -2
- package/docs/pt/dictionary/content_file.md +24 -1
- package/docs/pt/intlayer_with_astro.md +1 -1
- package/docs/pt/intlayer_with_express.md +1 -1
- package/docs/pt/intlayer_with_nestjs.md +1 -1
- package/docs/pt/intlayer_with_next-i18next.md +1 -0
- package/docs/pt/intlayer_with_next-intl.md +1 -0
- package/docs/pt/intlayer_with_tanstack.md +122 -3
- package/docs/pt/plugins/sync-json.md +27 -2
- package/docs/ru/dictionary/content_file.md +44 -1
- package/docs/ru/intlayer_with_astro.md +1 -1
- package/docs/ru/intlayer_with_express.md +1 -1
- package/docs/ru/intlayer_with_nestjs.md +1 -1
- package/docs/ru/intlayer_with_next-i18next.md +1 -0
- package/docs/ru/intlayer_with_next-intl.md +1 -0
- package/docs/ru/intlayer_with_tanstack.md +122 -3
- package/docs/ru/plugins/sync-json.md +27 -2
- package/docs/tr/dictionary/content_file.md +44 -1
- package/docs/tr/intlayer_with_astro.md +1 -1
- package/docs/tr/intlayer_with_express.md +1 -1
- package/docs/tr/intlayer_with_next-i18next.md +1 -0
- package/docs/tr/intlayer_with_next-intl.md +1 -0
- package/docs/tr/intlayer_with_tanstack.md +122 -3
- package/docs/tr/plugins/sync-json.md +27 -2
- package/docs/vi/dictionary/content_file.md +24 -1
- package/docs/vi/intlayer_with_astro.md +1 -1
- package/docs/vi/intlayer_with_express.md +1 -1
- package/docs/vi/intlayer_with_nestjs.md +1 -1
- package/docs/vi/intlayer_with_next-i18next.md +1 -0
- package/docs/vi/intlayer_with_next-intl.md +1 -0
- package/docs/vi/intlayer_with_tanstack.md +122 -3
- package/docs/vi/plugins/sync-json.md +27 -2
- package/docs/zh/dictionary/content_file.md +44 -1
- package/docs/zh/intlayer_with_astro.md +1 -1
- package/docs/zh/intlayer_with_express.md +1 -1
- package/docs/zh/intlayer_with_nestjs.md +1 -1
- package/docs/zh/intlayer_with_next-i18next.md +1 -0
- package/docs/zh/intlayer_with_next-intl.md +1 -0
- package/docs/zh/intlayer_with_tanstack.md +122 -3
- package/docs/zh/plugins/sync-json.md +27 -2
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Sync JSON plugin
|
|
5
5
|
description: Synchronize 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
6
|
keywords:
|
|
@@ -24,12 +24,15 @@ slugs:
|
|
|
24
24
|
- sync-json
|
|
25
25
|
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
26
26
|
history:
|
|
27
|
+
- version: 7.5.0
|
|
28
|
+
date: 2025-12-13
|
|
29
|
+
changes: Add ICU and i18next format support
|
|
27
30
|
- version: 6.1.6
|
|
28
31
|
date: 2025-10-05
|
|
29
32
|
changes: Initial Sync JSON plugin documentation
|
|
30
33
|
---
|
|
31
34
|
|
|
32
|
-
# Sync JSON (i18n bridges)
|
|
35
|
+
# Sync JSON (i18n bridges) - Sync JSON with ICU / i18next support
|
|
33
36
|
|
|
34
37
|
<iframe title="How to keep your JSON translations in sync with Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/MpGMxniDHNg?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
35
38
|
|
|
@@ -95,13 +98,16 @@ const config: IntlayerConfig = {
|
|
|
95
98
|
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
96
99
|
locale: Locales.ENGLISH,
|
|
97
100
|
priority: 1, // Ensures these JSON files take precedence over files at `./locales/en/${key}.json`
|
|
101
|
+
format: "intlayer", // Format of the JSON content
|
|
98
102
|
}),
|
|
99
103
|
/**
|
|
100
104
|
* Will load, and write the output and translations back to the JSON files in the locales directory
|
|
101
105
|
*/
|
|
102
106
|
syncJSON({
|
|
107
|
+
format: "i18next",
|
|
103
108
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
104
109
|
priority: 0,
|
|
110
|
+
format: "i18next",
|
|
105
111
|
}),
|
|
106
112
|
],
|
|
107
113
|
};
|
|
@@ -130,6 +136,7 @@ const config: IntlayerConfig = {
|
|
|
130
136
|
syncJSON({
|
|
131
137
|
// Per-locale, per-namespace layout (e.g., next-intl, i18next with namespaces)
|
|
132
138
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
139
|
+
format: "icu",
|
|
133
140
|
}),
|
|
134
141
|
],
|
|
135
142
|
};
|
|
@@ -150,7 +157,9 @@ const config: IntlayerConfig = {
|
|
|
150
157
|
},
|
|
151
158
|
plugins: [
|
|
152
159
|
syncJSON({
|
|
160
|
+
format: "i18next",
|
|
153
161
|
source: ({ locale }) => `./locales/${locale}.json`,
|
|
162
|
+
format: "i18next",
|
|
154
163
|
}),
|
|
155
164
|
],
|
|
156
165
|
};
|
|
@@ -171,9 +180,27 @@ syncJSON({
|
|
|
171
180
|
source: ({ key, locale }) => string, // required
|
|
172
181
|
location?: string, // optional label, default: "plugin"
|
|
173
182
|
priority?: number, // optional priority for conflict resolution, default: 0
|
|
183
|
+
format?: 'intlayer' | 'icu' | 'i18next', // optional formatter, default: 'intlayer'
|
|
174
184
|
});
|
|
175
185
|
```
|
|
176
186
|
|
|
187
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
188
|
+
|
|
189
|
+
Specifies the formatter to use for the dictionary content when synchronizing JSON files. This allows using different message formatting syntaxes compatible with various i18n libraries.
|
|
190
|
+
|
|
191
|
+
- `'intlayer'`: The default Intlayer formatter (default).
|
|
192
|
+
- `'icu'`: Uses ICU message formatting (compatible with libraries like react-intl, vue-i18n).
|
|
193
|
+
- `'i18next'`: Uses i18next message formatting (compatible with i18next, next-i18next, Solid-i18next).
|
|
194
|
+
|
|
195
|
+
**Example:**
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
syncJSON({
|
|
199
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
200
|
+
format: "i18next", // Use i18next formatting for compatibility
|
|
201
|
+
}),
|
|
202
|
+
```
|
|
203
|
+
|
|
177
204
|
### Multiple JSON sources and priority
|
|
178
205
|
|
|
179
206
|
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.
|
|
@@ -200,6 +227,7 @@ const config: IntlayerConfig = {
|
|
|
200
227
|
plugins: [
|
|
201
228
|
// Primary JSON source (highest priority)
|
|
202
229
|
syncJSON({
|
|
230
|
+
format: "i18next",
|
|
203
231
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
204
232
|
location: "main-translations",
|
|
205
233
|
priority: 10,
|
|
@@ -207,6 +235,7 @@ const config: IntlayerConfig = {
|
|
|
207
235
|
|
|
208
236
|
// Fallback JSON source (lower priority)
|
|
209
237
|
syncJSON({
|
|
238
|
+
format: "i18next",
|
|
210
239
|
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
211
240
|
location: "fallback-translations",
|
|
212
241
|
priority: 5,
|
|
@@ -214,6 +243,7 @@ const config: IntlayerConfig = {
|
|
|
214
243
|
|
|
215
244
|
// Legacy JSON source (lowest priority)
|
|
216
245
|
syncJSON({
|
|
246
|
+
format: "i18next",
|
|
217
247
|
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
218
248
|
location: "legacy-translations",
|
|
219
249
|
priority: 1,
|
|
@@ -300,9 +330,30 @@ loadJSON({
|
|
|
300
330
|
|
|
301
331
|
// Priority used for conflict resolution against other sources
|
|
302
332
|
priority?: number, // default: 0
|
|
333
|
+
|
|
334
|
+
// Optional formatter for the JSON content
|
|
335
|
+
format?: 'intlayer' | 'icu' | 'i18next', // default: 'intlayer'
|
|
303
336
|
});
|
|
304
337
|
```
|
|
305
338
|
|
|
339
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
340
|
+
|
|
341
|
+
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.
|
|
342
|
+
|
|
343
|
+
- `'intlayer'`: The default Intlayer formatter (default).
|
|
344
|
+
- `'icu'`: Uses ICU message formatting (compatible with libraries like react-intl, vue-i18n).
|
|
345
|
+
- `'i18next'`: Uses i18next message formatting (compatible with i18next, next-i18next, Solid-i18next).
|
|
346
|
+
|
|
347
|
+
**Example:**
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
loadJSON({
|
|
351
|
+
source: ({ key }) => `./src/**/${key}.i18n.json`,
|
|
352
|
+
locale: Locales.ENGLISH,
|
|
353
|
+
format: "icu", // Use ICU formatting for compatibility
|
|
354
|
+
}),
|
|
355
|
+
```
|
|
356
|
+
|
|
306
357
|
### Behavior and conventions
|
|
307
358
|
|
|
308
359
|
- If your `source` mask includes a locale placeholder, only files for the selected `locale` are ingested.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-02-07
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Content File
|
|
5
5
|
description: Learn how to customise the extensions for your content declaration files. Follow this documentation to implement conditions efficiently in your project.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,9 @@ slugs:
|
|
|
12
12
|
- concept
|
|
13
13
|
- content
|
|
14
14
|
history:
|
|
15
|
+
- version: 7.5.0
|
|
16
|
+
date: 2025-12-13
|
|
17
|
+
changes: Add ICU and i18next format support
|
|
15
18
|
- version: 6.0.0
|
|
16
19
|
date: 2025-09-20
|
|
17
20
|
changes: Add fields documentation
|
|
@@ -384,6 +387,26 @@ Array of strings for categorising and organising dictionaries. Tags provide addi
|
|
|
384
387
|
}
|
|
385
388
|
```
|
|
386
389
|
|
|
390
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
391
|
+
|
|
392
|
+
Specifies the formatter to use for the dictionary content. This allows using different message formatting syntaxes.
|
|
393
|
+
|
|
394
|
+
- `'intlayer'`: The default Intlayer formatter.
|
|
395
|
+
- `'icu'`: Uses ICU message formatting.
|
|
396
|
+
- `'i18next'`: Uses i18next message formatting.
|
|
397
|
+
|
|
398
|
+
**Example:**
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
{
|
|
402
|
+
key: "my-dictionary",
|
|
403
|
+
format: "icu",
|
|
404
|
+
content: {
|
|
405
|
+
message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}"
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
387
410
|
#### `locale` (LocalesValues)
|
|
388
411
|
|
|
389
412
|
Transforms the dictionary into a per-locale dictionary where each field declared in the content will be automatically transformed into a translation node. When this property is set:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-03-07
|
|
3
3
|
updatedAt: 2025-10-03
|
|
4
4
|
title: How to translate your Astro app – i18n guide 2025
|
|
5
|
-
description: Learn how to add internationalisation (i18n) to your
|
|
5
|
+
description: Learn how to add internationalisation (i18n) to your Astro website using Intlayer. Follow this guide to make your site multilingual.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internationalisation
|
|
8
8
|
- Documentation
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-08-11
|
|
3
3
|
updatedAt: 2025-06-29
|
|
4
4
|
title: How to translate your Express backend – i18n guide 2025
|
|
5
|
-
description: Discover how to make your
|
|
5
|
+
description: Discover how to make your Express backend multilingual. Follow the documentation to internationalize (i18n) and translate it.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internationalization
|
|
8
8
|
- Documentation
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
3
|
updatedAt: 2025-09-09
|
|
4
4
|
title: How to translate your Nest backend – i18n guide 2025
|
|
5
|
-
description: Discover how to make your
|
|
5
|
+
description: Discover how to make your NestJS backend multilingual. Follow the documentation to internationalise (i18n) and translate it.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internationalisation
|
|
8
8
|
- Documentation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-11
|
|
4
4
|
title: How to translate your Tanstack Start app – i18n guide 2025
|
|
5
5
|
description: Learn how to add internationalisation (i18n) to your Tanstack Start application using Intlayer. Follow this comprehensive guide to make your app multilingual with locale-aware routing.
|
|
6
6
|
keywords:
|
|
@@ -19,6 +19,9 @@ slugs:
|
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
|
|
21
21
|
history:
|
|
22
|
+
- version: 7.4.0
|
|
23
|
+
date: 2025-12-11
|
|
24
|
+
changes: Introduce validatePrefix and add step 14: Handling 404 pages with localized routes.
|
|
22
25
|
- version: 7.3.9
|
|
23
26
|
date: 2025-12-05
|
|
24
27
|
changes: Add step 13: Retrieve the locale in your server actions (Optional)
|
|
@@ -602,7 +605,123 @@ export const getLocaleServer = createServerFn().handler(async () => {
|
|
|
602
605
|
|
|
603
606
|
---
|
|
604
607
|
|
|
605
|
-
### Step 14:
|
|
608
|
+
### Step 14: Manage not found pages (Optional)
|
|
609
|
+
|
|
610
|
+
When a user visits a non-existing page, you can display a custom not found page and the locale prefix may impact the way the not found page is triggered.
|
|
611
|
+
|
|
612
|
+
#### Understanding TanStack Router's 404 Handling with Locale Prefixes
|
|
613
|
+
|
|
614
|
+
In TanStack Router, handling 404 pages with localized routes requires a multi-layered approach:
|
|
615
|
+
|
|
616
|
+
1. **Dedicated 404 route**: A specific route to display the 404 UI
|
|
617
|
+
2. **Route-level validation**: Validates locale prefixes and redirects invalid ones to 404
|
|
618
|
+
3. **Catch-all route**: Captures any unmatched paths within the locale segment
|
|
619
|
+
|
|
620
|
+
```tsx fileName="src/routes/{-$locale}/404.tsx"
|
|
621
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
622
|
+
|
|
623
|
+
// This creates a dedicated /[locale]/404 route
|
|
624
|
+
// It's used both as a direct route and imported as a component in other files
|
|
625
|
+
export const Route = createFileRoute("/{-$locale}/404")({
|
|
626
|
+
component: NotFoundComponent,
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
// Exported separately so it can be reused in notFoundComponent and catch-all routes
|
|
630
|
+
export function NotFoundComponent() {
|
|
631
|
+
return (
|
|
632
|
+
<div>
|
|
633
|
+
<h1>404</h1>
|
|
634
|
+
</div>
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
```tsx fileName="src/routes/{-$locale}/route.tsx"
|
|
640
|
+
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
|
|
641
|
+
import { validatePrefix } from "intlayer";
|
|
642
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
643
|
+
|
|
644
|
+
import { LocaleSwitcher } from "@/components/locale-switcher";
|
|
645
|
+
import { NotFoundComponent } from "./404";
|
|
646
|
+
|
|
647
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
648
|
+
// beforeLoad runs before the route renders (on both server and client)
|
|
649
|
+
// It's the ideal place to validate the locale prefix
|
|
650
|
+
beforeLoad: ({ params }) => {
|
|
651
|
+
// Get locale from route params (not from server headers, as beforeLoad runs on both client and server)
|
|
652
|
+
const localeParam = params.locale;
|
|
653
|
+
|
|
654
|
+
// validatePrefix checks if the locale is valid according to your intlayer config
|
|
655
|
+
// Returns: { isValid: boolean, localePrefix: string }
|
|
656
|
+
// - isValid: true if the prefix matches a configured locale (or is empty when prefix is optional)
|
|
657
|
+
// - localePrefix: the validated prefix or the default locale prefix for redirects
|
|
658
|
+
const { isValid, localePrefix } = validatePrefix(localeParam);
|
|
659
|
+
|
|
660
|
+
if (isValid) {
|
|
661
|
+
// Locale is valid, allow the route to render normally
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// Invalid locale prefix (e.g., /xyz/about where "xyz" isn't a valid locale)
|
|
666
|
+
// Redirect to the 404 page with a valid locale prefix
|
|
667
|
+
// This ensures the 404 page is still properly localized
|
|
668
|
+
throw redirect({
|
|
669
|
+
to: "/{-$locale}/404",
|
|
670
|
+
params: { locale: localePrefix },
|
|
671
|
+
});
|
|
672
|
+
},
|
|
673
|
+
component: RouteComponent,
|
|
674
|
+
// notFoundComponent is called when a child route doesn't exist
|
|
675
|
+
// e.g., /en/non-existent-page triggers this within the /en layout
|
|
676
|
+
notFoundComponent: NotFoundLayout,
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
function RouteComponent() {
|
|
680
|
+
const { defaultLocale } = useLocale();
|
|
681
|
+
const { locale } = Route.useParams();
|
|
682
|
+
|
|
683
|
+
return (
|
|
684
|
+
// Wrap the entire locale segment with IntlayerProvider
|
|
685
|
+
// Falls back to defaultLocale when locale param is undefined (optional prefix mode)
|
|
686
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
687
|
+
<Outlet />
|
|
688
|
+
</IntlayerProvider>
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// NotFoundLayout wraps the 404 component with IntlayerProvider
|
|
693
|
+
// This ensures translations still work on the 404 page
|
|
694
|
+
function NotFoundLayout() {
|
|
695
|
+
const { defaultLocale } = useLocale();
|
|
696
|
+
const { locale } = Route.useParams();
|
|
697
|
+
|
|
698
|
+
return (
|
|
699
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
700
|
+
<NotFoundComponent />
|
|
701
|
+
{/* Include LocaleSwitcher so users can change language even on 404 */}
|
|
702
|
+
<LocaleSwitcher />
|
|
703
|
+
</IntlayerProvider>
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
```tsx fileName="src/routes/{-$locale}/$.tsx"
|
|
709
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
710
|
+
|
|
711
|
+
import { NotFoundComponent } from "./404";
|
|
712
|
+
|
|
713
|
+
// The $ (splat/catch-all) route matches any path that doesn't match other routes
|
|
714
|
+
// e.g., /en/some/deeply/nested/invalid/path
|
|
715
|
+
// This ensures ALL unmatched paths within a locale show the 404 page
|
|
716
|
+
// Without this, unmatched deep paths might show a blank page or error
|
|
717
|
+
export const Route = createFileRoute("/{-$locale}/$")({
|
|
718
|
+
component: NotFoundComponent,
|
|
719
|
+
});
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
### Step 15: Configure TypeScript (Optional)
|
|
606
725
|
|
|
607
726
|
Intlayer uses module augmentation to benefit from TypeScript and strengthen your codebase.
|
|
608
727
|
|
|
@@ -24,12 +24,15 @@ slugs:
|
|
|
24
24
|
- sync-json
|
|
25
25
|
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
26
26
|
history:
|
|
27
|
+
- version: 7.5.0
|
|
28
|
+
date: 2025-12-13
|
|
29
|
+
changes: Add ICU and i18next format support
|
|
27
30
|
- version: 6.1.6
|
|
28
31
|
date: 2025-10-05
|
|
29
32
|
changes: Initial Sync JSON plugin documentation
|
|
30
33
|
---
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
# Sync JSON (i18n bridges) - Sync JSON with ICU / i18next support
|
|
33
36
|
|
|
34
37
|
<iframe title="How to keep your JSON translations in sync with Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/MpGMxniDHNg?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
35
38
|
|
|
@@ -105,9 +108,27 @@ syncJSON({
|
|
|
105
108
|
source: ({ key, locale }) => string, // required
|
|
106
109
|
location?: string, // optional label, default: "plugin"
|
|
107
110
|
priority?: number, // optional priority for conflict resolution, default: 0
|
|
111
|
+
format?: 'intlayer' | 'icu' | 'i18next', // optional formatter, default: 'intlayer'
|
|
108
112
|
});
|
|
109
113
|
```
|
|
110
114
|
|
|
115
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
116
|
+
|
|
117
|
+
Specifies the formatter to use for the dictionary content when synchronising JSON files. This allows using different message formatting syntaxes compatible with various i18n libraries.
|
|
118
|
+
|
|
119
|
+
- `'intlayer'`: The default Intlayer formatter (default).
|
|
120
|
+
- `'icu'`: Uses ICU message formatting (compatible with libraries like react-intl, vue-i18n).
|
|
121
|
+
- `'i18next'`: Uses i18next message formatting (compatible with i18next, next-i18next, Solid-i18next).
|
|
122
|
+
|
|
123
|
+
**Example:**
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
syncJSON({
|
|
127
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
128
|
+
format: "i18next", // Use i18next formatting for compatibility
|
|
129
|
+
}),
|
|
130
|
+
```
|
|
131
|
+
|
|
111
132
|
## Multiple JSON sources and priority
|
|
112
133
|
|
|
113
134
|
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.
|
|
@@ -134,6 +155,7 @@ export default defineConfig({
|
|
|
134
155
|
plugins: [
|
|
135
156
|
// Primary JSON source (highest priority)
|
|
136
157
|
syncJSON({
|
|
158
|
+
format: "i18next",
|
|
137
159
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
138
160
|
location: "main-translations",
|
|
139
161
|
priority: 10,
|
|
@@ -141,6 +163,7 @@ export default defineConfig({
|
|
|
141
163
|
|
|
142
164
|
// Fallback JSON source (lower priority)
|
|
143
165
|
syncJSON({
|
|
166
|
+
format: "i18next",
|
|
144
167
|
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
145
168
|
location: "fallback-translations",
|
|
146
169
|
priority: 5,
|
|
@@ -148,6 +171,7 @@ export default defineConfig({
|
|
|
148
171
|
|
|
149
172
|
// Legacy JSON source (lowest priority)
|
|
150
173
|
syncJSON({
|
|
174
|
+
format: "i18next",
|
|
151
175
|
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
152
176
|
location: "legacy-translations",
|
|
153
177
|
priority: 1,
|
|
@@ -178,6 +202,7 @@ import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
|
178
202
|
export default {
|
|
179
203
|
plugins: [
|
|
180
204
|
syncJSON({
|
|
205
|
+
format: "i18next",
|
|
181
206
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
182
207
|
}),
|
|
183
208
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-02-07
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Archivo de Contenido
|
|
5
5
|
description: Aprende a personalizar las extensiones para tus archivos de declaración de contenido. Sigue esta documentación para implementar condiciones de manera eficiente en tu proyecto.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,9 @@ slugs:
|
|
|
12
12
|
- concept
|
|
13
13
|
- content
|
|
14
14
|
history:
|
|
15
|
+
- version: 7.5.0
|
|
16
|
+
date: 2025-12-13
|
|
17
|
+
changes: Añadido soporte para formatos ICU e i18next
|
|
15
18
|
- version: 6.0.0
|
|
16
19
|
date: 2025-09-20
|
|
17
20
|
changes: Añadida documentación de campos
|
|
@@ -385,6 +388,26 @@ Array de cadenas para categorizar y organizar diccionarios. Las etiquetas propor
|
|
|
385
388
|
}
|
|
386
389
|
```
|
|
387
390
|
|
|
391
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
392
|
+
|
|
393
|
+
Especifica el formateador a utilizar para el contenido del diccionario. Esto permite usar diferentes sintaxis de formateo de mensajes.
|
|
394
|
+
|
|
395
|
+
- `'intlayer'`: El formateador Intlayer por defecto.
|
|
396
|
+
- `'icu'`: Usa el formateo de mensajes ICU.
|
|
397
|
+
- `'i18next'`: Usa el formateo de mensajes i18next.
|
|
398
|
+
|
|
399
|
+
**Ejemplo:**
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
{
|
|
403
|
+
key: "my-dictionary",
|
|
404
|
+
format: "icu",
|
|
405
|
+
content: {
|
|
406
|
+
message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}"
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
388
411
|
#### `locale` (LocalesValues)
|
|
389
412
|
|
|
390
413
|
Transforma el diccionario en un diccionario por localización donde cada campo declarado en el contenido se transformará automáticamente en un nodo de traducción. Cuando esta propiedad está establecida:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-03-07
|
|
3
3
|
updatedAt: 2025-10-03
|
|
4
4
|
title: Cómo traducir tu Astro – guía i18n 2025
|
|
5
|
-
description: Aprende cómo agregar internacionalización (i18n) a tu
|
|
5
|
+
description: Aprende cómo agregar internacionalización (i18n) a tu sitio web Astro usando Intlayer. Sigue esta guía para hacer tu sitio multilingüe.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacionalización
|
|
8
8
|
- Documentación
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-08-11
|
|
3
3
|
updatedAt: 2025-06-29
|
|
4
4
|
title: Cómo traducir tu Express backend – guía i18n 2025
|
|
5
|
-
description: Descubre cómo hacer que tu backend de
|
|
5
|
+
description: Descubre cómo hacer que tu backend de Express sea multilingüe. Sigue la documentación para internacionalizar (i18n) y traducirlo.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacionalización
|
|
8
8
|
- Documentación
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
3
|
updatedAt: 2025-09-09
|
|
4
4
|
title: Cómo traducir tu Nest backend – guía i18n 2025
|
|
5
|
-
description: Descubre cómo hacer que tu backend
|
|
5
|
+
description: Descubre cómo hacer que tu backend NestJS sea multilingüe. Sigue la documentación para internacionalizar (i18n) y traducirlo.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacionalización
|
|
8
8
|
- Documentación
|