@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.
Files changed (238) hide show
  1. package/blog/ar/intlayer_with_i18next.md +2 -0
  2. package/blog/ar/intlayer_with_next-i18next.md +2 -0
  3. package/blog/ar/intlayer_with_next-intl.md +2 -0
  4. package/blog/ar/intlayer_with_react-i18next.md +2 -0
  5. package/blog/ar/intlayer_with_react-intl.md +2 -0
  6. package/blog/ar/intlayer_with_vue-i18n.md +2 -0
  7. package/blog/de/intlayer_with_i18next.md +2 -0
  8. package/blog/de/intlayer_with_next-i18next.md +1 -0
  9. package/blog/de/intlayer_with_next-intl.md +2 -0
  10. package/blog/de/intlayer_with_react-i18next.md +2 -0
  11. package/blog/de/intlayer_with_react-intl.md +2 -0
  12. package/blog/de/intlayer_with_vue-i18n.md +2 -0
  13. package/blog/en/intlayer_with_i18next.md +6 -0
  14. package/blog/en/intlayer_with_next-i18next.md +3 -0
  15. package/blog/en/intlayer_with_next-intl.md +3 -0
  16. package/blog/en/intlayer_with_react-i18next.md +3 -0
  17. package/blog/en/intlayer_with_react-intl.md +3 -0
  18. package/blog/en/intlayer_with_vue-i18n.md +3 -0
  19. package/blog/en-GB/intlayer_with_i18next.md +2 -0
  20. package/blog/en-GB/intlayer_with_next-i18next.md +2 -0
  21. package/blog/en-GB/intlayer_with_next-intl.md +2 -0
  22. package/blog/en-GB/intlayer_with_react-i18next.md +2 -0
  23. package/blog/en-GB/intlayer_with_react-intl.md +2 -0
  24. package/blog/en-GB/intlayer_with_vue-i18n.md +2 -0
  25. package/blog/es/intlayer_with_i18next.md +2 -0
  26. package/blog/es/intlayer_with_next-i18next.md +2 -0
  27. package/blog/es/intlayer_with_next-intl.md +2 -0
  28. package/blog/es/intlayer_with_react-i18next.md +2 -0
  29. package/blog/es/intlayer_with_react-intl.md +2 -0
  30. package/blog/es/intlayer_with_vue-i18n.md +2 -0
  31. package/blog/fr/intlayer_with_i18next.md +2 -0
  32. package/blog/fr/intlayer_with_next-i18next.md +2 -0
  33. package/blog/fr/intlayer_with_next-intl.md +2 -0
  34. package/blog/fr/intlayer_with_react-i18next.md +2 -0
  35. package/blog/fr/intlayer_with_react-intl.md +2 -0
  36. package/blog/fr/intlayer_with_vue-i18n.md +2 -0
  37. package/blog/hi/intlayer_with_i18next.md +2 -0
  38. package/blog/hi/intlayer_with_next-i18next.md +2 -0
  39. package/blog/hi/intlayer_with_next-intl.md +2 -0
  40. package/blog/hi/intlayer_with_react-i18next.md +2 -0
  41. package/blog/hi/intlayer_with_react-intl.md +2 -0
  42. package/blog/hi/intlayer_with_vue-i18n.md +2 -0
  43. package/blog/id/intlayer_with_i18next.md +2 -0
  44. package/blog/id/intlayer_with_next-i18next.md +2 -0
  45. package/blog/id/intlayer_with_next-intl.md +2 -0
  46. package/blog/id/intlayer_with_react-i18next.md +2 -0
  47. package/blog/id/intlayer_with_react-intl.md +2 -0
  48. package/blog/id/intlayer_with_vue-i18n.md +2 -0
  49. package/blog/it/intlayer_with_i18next.md +2 -0
  50. package/blog/it/intlayer_with_next-i18next.md +2 -0
  51. package/blog/it/intlayer_with_next-intl.md +2 -0
  52. package/blog/it/intlayer_with_react-i18next.md +2 -0
  53. package/blog/it/intlayer_with_react-intl.md +2 -0
  54. package/blog/it/intlayer_with_vue-i18n.md +2 -0
  55. package/blog/ja/intlayer_with_i18next.md +2 -0
  56. package/blog/ja/intlayer_with_next-i18next.md +1 -0
  57. package/blog/ja/intlayer_with_next-intl.md +2 -0
  58. package/blog/ja/intlayer_with_react-i18next.md +2 -0
  59. package/blog/ja/intlayer_with_react-intl.md +2 -0
  60. package/blog/ja/intlayer_with_vue-i18n.md +2 -0
  61. package/blog/ko/intlayer_with_i18next.md +2 -0
  62. package/blog/ko/intlayer_with_next-i18next.md +2 -0
  63. package/blog/ko/intlayer_with_next-intl.md +2 -0
  64. package/blog/ko/intlayer_with_react-i18next.md +2 -0
  65. package/blog/ko/intlayer_with_react-intl.md +2 -0
  66. package/blog/ko/intlayer_with_vue-i18n.md +2 -0
  67. package/blog/pl/intlayer_with_i18next.md +2 -0
  68. package/blog/pl/intlayer_with_next-i18next.md +2 -0
  69. package/blog/pl/intlayer_with_next-intl.md +2 -0
  70. package/blog/pl/intlayer_with_react-i18next.md +2 -0
  71. package/blog/pl/intlayer_with_react-intl.md +2 -0
  72. package/blog/pl/intlayer_with_vue-i18n.md +2 -0
  73. package/blog/pt/intlayer_with_i18next.md +2 -0
  74. package/blog/pt/intlayer_with_next-i18next.md +2 -0
  75. package/blog/pt/intlayer_with_next-intl.md +2 -0
  76. package/blog/pt/intlayer_with_react-i18next.md +2 -0
  77. package/blog/pt/intlayer_with_react-intl.md +2 -0
  78. package/blog/pt/intlayer_with_vue-i18n.md +2 -0
  79. package/blog/ru/intlayer_with_i18next.md +2 -0
  80. package/blog/ru/intlayer_with_next-i18next.md +2 -0
  81. package/blog/ru/intlayer_with_next-intl.md +2 -0
  82. package/blog/ru/intlayer_with_react-i18next.md +2 -0
  83. package/blog/ru/intlayer_with_react-intl.md +2 -0
  84. package/blog/ru/intlayer_with_vue-i18n.md +2 -0
  85. package/blog/tr/intlayer_with_i18next.md +2 -0
  86. package/blog/tr/intlayer_with_next-i18next.md +2 -0
  87. package/blog/tr/intlayer_with_next-intl.md +2 -0
  88. package/blog/tr/intlayer_with_react-i18next.md +2 -0
  89. package/blog/tr/intlayer_with_react-intl.md +2 -0
  90. package/blog/tr/intlayer_with_vue-i18n.md +2 -0
  91. package/blog/vi/intlayer_with_i18next.md +2 -0
  92. package/blog/vi/intlayer_with_next-i18next.md +2 -0
  93. package/blog/vi/intlayer_with_next-intl.md +2 -0
  94. package/blog/vi/intlayer_with_react-i18next.md +2 -0
  95. package/blog/vi/intlayer_with_react-intl.md +2 -0
  96. package/blog/vi/intlayer_with_vue-i18n.md +2 -0
  97. package/blog/zh/intlayer_with_i18next.md +2 -0
  98. package/blog/zh/intlayer_with_next-i18next.md +2 -0
  99. package/blog/zh/intlayer_with_next-intl.md +2 -0
  100. package/blog/zh/intlayer_with_react-i18next.md +2 -0
  101. package/blog/zh/intlayer_with_react-intl.md +2 -0
  102. package/blog/zh/intlayer_with_vue-i18n.md +2 -0
  103. package/docs/ar/dictionary/content_file.md +24 -1
  104. package/docs/ar/intlayer_with_astro.md +1 -1
  105. package/docs/ar/intlayer_with_express.md +1 -1
  106. package/docs/ar/intlayer_with_nestjs.md +1 -1
  107. package/docs/ar/intlayer_with_next-i18next.md +1 -0
  108. package/docs/ar/intlayer_with_next-intl.md +1 -0
  109. package/docs/ar/intlayer_with_tanstack.md +122 -3
  110. package/docs/ar/plugins/sync-json.md +27 -2
  111. package/docs/de/dictionary/content_file.md +24 -1
  112. package/docs/de/intlayer_with_astro.md +1 -1
  113. package/docs/de/intlayer_with_express.md +1 -1
  114. package/docs/de/intlayer_with_nestjs.md +1 -1
  115. package/docs/de/intlayer_with_next-i18next.md +1 -0
  116. package/docs/de/intlayer_with_next-intl.md +1 -0
  117. package/docs/de/intlayer_with_tanstack.md +122 -3
  118. package/docs/de/plugins/sync-json.md +27 -2
  119. package/docs/en/dictionary/content_file.md +24 -1
  120. package/docs/en/intlayer_with_astro.md +1 -1
  121. package/docs/en/intlayer_with_express.md +1 -1
  122. package/docs/en/intlayer_with_nestjs.md +1 -2
  123. package/docs/en/intlayer_with_next-i18next.md +1 -0
  124. package/docs/en/intlayer_with_next-intl.md +1 -0
  125. package/docs/en/intlayer_with_tanstack.md +120 -1
  126. package/docs/en/plugins/sync-json.md +53 -2
  127. package/docs/en-GB/dictionary/content_file.md +24 -1
  128. package/docs/en-GB/intlayer_with_astro.md +1 -1
  129. package/docs/en-GB/intlayer_with_express.md +1 -1
  130. package/docs/en-GB/intlayer_with_nestjs.md +1 -1
  131. package/docs/en-GB/intlayer_with_next-i18next.md +1 -0
  132. package/docs/en-GB/intlayer_with_next-intl.md +1 -0
  133. package/docs/en-GB/intlayer_with_tanstack.md +121 -2
  134. package/docs/en-GB/plugins/sync-json.md +26 -1
  135. package/docs/es/dictionary/content_file.md +24 -1
  136. package/docs/es/intlayer_with_astro.md +1 -1
  137. package/docs/es/intlayer_with_express.md +1 -1
  138. package/docs/es/intlayer_with_nestjs.md +1 -1
  139. package/docs/es/intlayer_with_next-i18next.md +1 -0
  140. package/docs/es/intlayer_with_next-intl.md +1 -0
  141. package/docs/es/intlayer_with_tanstack.md +122 -3
  142. package/docs/es/plugins/sync-json.md +27 -2
  143. package/docs/fr/dictionary/content_file.md +24 -1
  144. package/docs/fr/intlayer_with_astro.md +1 -1
  145. package/docs/fr/intlayer_with_express.md +1 -1
  146. package/docs/fr/intlayer_with_nestjs.md +1 -1
  147. package/docs/fr/intlayer_with_next-i18next.md +1 -0
  148. package/docs/fr/intlayer_with_next-intl.md +1 -0
  149. package/docs/fr/intlayer_with_tanstack.md +122 -3
  150. package/docs/fr/plugins/sync-json.md +27 -2
  151. package/docs/hi/dictionary/content_file.md +24 -1
  152. package/docs/hi/intlayer_with_astro.md +1 -1
  153. package/docs/hi/intlayer_with_express.md +1 -1
  154. package/docs/hi/intlayer_with_nestjs.md +1 -1
  155. package/docs/hi/intlayer_with_next-i18next.md +1 -0
  156. package/docs/hi/intlayer_with_next-intl.md +1 -0
  157. package/docs/hi/intlayer_with_tanstack.md +122 -3
  158. package/docs/hi/plugins/sync-json.md +27 -2
  159. package/docs/id/dictionary/content_file.md +24 -1
  160. package/docs/id/intlayer_with_astro.md +1 -1
  161. package/docs/id/intlayer_with_express.md +1 -1
  162. package/docs/id/intlayer_with_nestjs.md +1 -1
  163. package/docs/id/intlayer_with_next-i18next.md +1 -0
  164. package/docs/id/intlayer_with_next-intl.md +1 -0
  165. package/docs/id/intlayer_with_tanstack.md +122 -3
  166. package/docs/id/plugins/sync-json.md +27 -2
  167. package/docs/it/dictionary/content_file.md +24 -1
  168. package/docs/it/intlayer_with_astro.md +1 -1
  169. package/docs/it/intlayer_with_express.md +1 -1
  170. package/docs/it/intlayer_with_nestjs.md +1 -1
  171. package/docs/it/intlayer_with_next-i18next.md +1 -0
  172. package/docs/it/intlayer_with_next-intl.md +1 -0
  173. package/docs/it/intlayer_with_tanstack.md +122 -3
  174. package/docs/it/plugins/sync-json.md +27 -2
  175. package/docs/ja/dictionary/content_file.md +24 -1
  176. package/docs/ja/intlayer_with_astro.md +1 -1
  177. package/docs/ja/intlayer_with_express.md +1 -1
  178. package/docs/ja/intlayer_with_nestjs.md +1 -1
  179. package/docs/ja/intlayer_with_next-i18next.md +1 -0
  180. package/docs/ja/intlayer_with_next-intl.md +1 -0
  181. package/docs/ja/intlayer_with_tanstack.md +122 -3
  182. package/docs/ja/plugins/sync-json.md +27 -2
  183. package/docs/ko/dictionary/content_file.md +44 -1
  184. package/docs/ko/intlayer_with_astro.md +1 -1
  185. package/docs/ko/intlayer_with_express.md +1 -1
  186. package/docs/ko/intlayer_with_nestjs.md +1 -1
  187. package/docs/ko/intlayer_with_next-i18next.md +1 -0
  188. package/docs/ko/intlayer_with_next-intl.md +1 -0
  189. package/docs/ko/intlayer_with_tanstack.md +122 -3
  190. package/docs/ko/plugins/sync-json.md +27 -2
  191. package/docs/pl/dictionary/content_file.md +24 -1
  192. package/docs/pl/intlayer_with_astro.md +2 -2
  193. package/docs/pl/intlayer_with_express.md +1 -1
  194. package/docs/pl/intlayer_with_nestjs.md +1 -1
  195. package/docs/pl/intlayer_with_next-i18next.md +1 -0
  196. package/docs/pl/intlayer_with_next-intl.md +1 -0
  197. package/docs/pl/intlayer_with_tanstack.md +122 -3
  198. package/docs/pl/plugins/sync-json.md +24 -2
  199. package/docs/pt/dictionary/content_file.md +24 -1
  200. package/docs/pt/intlayer_with_astro.md +1 -1
  201. package/docs/pt/intlayer_with_express.md +1 -1
  202. package/docs/pt/intlayer_with_nestjs.md +1 -1
  203. package/docs/pt/intlayer_with_next-i18next.md +1 -0
  204. package/docs/pt/intlayer_with_next-intl.md +1 -0
  205. package/docs/pt/intlayer_with_tanstack.md +122 -3
  206. package/docs/pt/plugins/sync-json.md +27 -2
  207. package/docs/ru/dictionary/content_file.md +44 -1
  208. package/docs/ru/intlayer_with_astro.md +1 -1
  209. package/docs/ru/intlayer_with_express.md +1 -1
  210. package/docs/ru/intlayer_with_nestjs.md +1 -1
  211. package/docs/ru/intlayer_with_next-i18next.md +1 -0
  212. package/docs/ru/intlayer_with_next-intl.md +1 -0
  213. package/docs/ru/intlayer_with_tanstack.md +122 -3
  214. package/docs/ru/plugins/sync-json.md +27 -2
  215. package/docs/tr/dictionary/content_file.md +44 -1
  216. package/docs/tr/intlayer_with_astro.md +1 -1
  217. package/docs/tr/intlayer_with_express.md +1 -1
  218. package/docs/tr/intlayer_with_next-i18next.md +1 -0
  219. package/docs/tr/intlayer_with_next-intl.md +1 -0
  220. package/docs/tr/intlayer_with_tanstack.md +122 -3
  221. package/docs/tr/plugins/sync-json.md +27 -2
  222. package/docs/vi/dictionary/content_file.md +24 -1
  223. package/docs/vi/intlayer_with_astro.md +1 -1
  224. package/docs/vi/intlayer_with_express.md +1 -1
  225. package/docs/vi/intlayer_with_nestjs.md +1 -1
  226. package/docs/vi/intlayer_with_next-i18next.md +1 -0
  227. package/docs/vi/intlayer_with_next-intl.md +1 -0
  228. package/docs/vi/intlayer_with_tanstack.md +122 -3
  229. package/docs/vi/plugins/sync-json.md +27 -2
  230. package/docs/zh/dictionary/content_file.md +44 -1
  231. package/docs/zh/intlayer_with_astro.md +1 -1
  232. package/docs/zh/intlayer_with_express.md +1 -1
  233. package/docs/zh/intlayer_with_nestjs.md +1 -1
  234. package/docs/zh/intlayer_with_next-i18next.md +1 -0
  235. package/docs/zh/intlayer_with_next-intl.md +1 -0
  236. package/docs/zh/intlayer_with_tanstack.md +122 -3
  237. package/docs/zh/plugins/sync-json.md +27 -2
  238. package/package.json +6 -6
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-03-13
3
- updatedAt: 2025-10-05
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&amp;origin=http://intlayer.org&amp;controls=0&amp;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-09-20
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 Vite and React application using Intlayer. Follow this guide to make your app multilingual.
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 vite backend multilingual. Follow the documentation to internationalize (i18n) and translate it.
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 vite backend multilingual. Follow the documentation to internationalise (i18n) and translate it.
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
@@ -580,6 +580,7 @@ const config: IntlayerConfig = {
580
580
  },
581
581
  plugins: [
582
582
  syncJSON({
583
+ format: "i18next",
583
584
  source: ({ locale }) => `./locales/${locale}.json`,
584
585
  }),
585
586
  ],
@@ -419,6 +419,7 @@ const config: IntlayerConfig = {
419
419
  plugins: [
420
420
  // Keep your per-namespace folder structure in sync with Intlayer
421
421
  syncJSON({
422
+ format: "icu",
422
423
  source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
423
424
  }),
424
425
  ],
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-09-09
3
- updatedAt: 2025-09-09
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: Configure TypeScript (Optional)
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
- ## 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&amp;origin=http://intlayer.org&amp;controls=0&amp;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-09-20
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 aplicación Vite y React usando Intlayer. Sigue esta guía para hacer tu aplicación multilingüe.
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 vite sea multilingüe. Sigue la documentación para internacionalizar (i18n) y traducirlo.
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 vite sea multilingüe. Sigue la documentación para internacionalizar (i18n) y traducirlo.
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
@@ -581,6 +581,7 @@ const config: IntlayerConfig = {
581
581
  },
582
582
  plugins: [
583
583
  syncJSON({
584
+ format: "i18next",
584
585
  source: ({ locale }) => `./locales/${locale}.json`,
585
586
  }),
586
587
  ],
@@ -419,6 +419,7 @@ const config: IntlayerConfig = {
419
419
  plugins: [
420
420
  // Mantén la estructura de carpetas por namespace sincronizada con Intlayer
421
421
  syncJSON({
422
+ format: "icu",
422
423
  source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
423
424
  }),
424
425
  ],