@intlayer/docs 7.0.4-canary.0 → 7.0.5

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 (107) hide show
  1. package/blog/ar/intlayer_with_i18next.md +68 -106
  2. package/blog/ar/intlayer_with_next-i18next.md +84 -288
  3. package/blog/ar/intlayer_with_next-intl.md +58 -337
  4. package/blog/ar/intlayer_with_react-i18next.md +68 -290
  5. package/blog/ar/intlayer_with_react-intl.md +63 -266
  6. package/blog/de/intlayer_with_i18next.md +77 -97
  7. package/blog/de/intlayer_with_next-i18next.md +69 -296
  8. package/blog/de/intlayer_with_next-intl.md +59 -340
  9. package/blog/de/intlayer_with_react-i18next.md +68 -290
  10. package/blog/de/intlayer_with_react-intl.md +62 -264
  11. package/blog/en/intlayer_with_i18next.md +36 -1638
  12. package/blog/en/intlayer_with_next-i18next.md +22 -847
  13. package/blog/en/intlayer_with_next-intl.md +32 -1053
  14. package/blog/en/intlayer_with_react-i18next.md +38 -764
  15. package/blog/en/intlayer_with_react-intl.md +42 -1018
  16. package/blog/en-GB/intlayer_with_i18next.md +67 -103
  17. package/blog/en-GB/intlayer_with_next-i18next.md +71 -292
  18. package/blog/en-GB/intlayer_with_next-intl.md +58 -337
  19. package/blog/en-GB/intlayer_with_react-i18next.md +67 -289
  20. package/blog/en-GB/intlayer_with_react-intl.md +61 -264
  21. package/blog/es/intlayer_with_i18next.md +67 -103
  22. package/blog/es/intlayer_with_next-i18next.md +71 -296
  23. package/blog/es/intlayer_with_next-intl.md +57 -338
  24. package/blog/es/intlayer_with_react-i18next.md +68 -290
  25. package/blog/es/intlayer_with_react-intl.md +62 -265
  26. package/blog/fr/intlayer_with_i18next.md +66 -104
  27. package/blog/fr/intlayer_with_next-i18next.md +82 -285
  28. package/blog/fr/intlayer_with_next-intl.md +57 -338
  29. package/blog/fr/intlayer_with_react-i18next.md +67 -289
  30. package/blog/fr/intlayer_with_react-intl.md +61 -264
  31. package/blog/hi/intlayer_with_i18next.md +68 -104
  32. package/blog/hi/intlayer_with_next-i18next.md +74 -299
  33. package/blog/hi/intlayer_with_next-intl.md +57 -239
  34. package/blog/hi/intlayer_with_react-i18next.md +69 -291
  35. package/blog/hi/intlayer_with_react-intl.md +65 -268
  36. package/blog/id/intlayer_with_i18next.md +126 -0
  37. package/blog/id/intlayer_with_next-i18next.md +142 -0
  38. package/blog/id/intlayer_with_next-intl.md +113 -0
  39. package/blog/id/intlayer_with_react-i18next.md +124 -0
  40. package/blog/id/intlayer_with_react-intl.md +122 -0
  41. package/blog/it/intlayer_with_i18next.md +67 -103
  42. package/blog/it/intlayer_with_next-i18next.md +71 -296
  43. package/blog/it/intlayer_with_next-intl.md +57 -338
  44. package/blog/it/intlayer_with_react-i18next.md +68 -290
  45. package/blog/it/intlayer_with_react-intl.md +62 -265
  46. package/blog/ja/intlayer_with_i18next.md +68 -103
  47. package/blog/ja/intlayer_with_next-i18next.md +85 -283
  48. package/blog/ja/intlayer_with_next-intl.md +58 -336
  49. package/blog/ja/intlayer_with_react-i18next.md +68 -290
  50. package/blog/ja/intlayer_with_react-intl.md +62 -264
  51. package/blog/ko/intlayer_with_i18next.md +80 -96
  52. package/blog/ko/intlayer_with_next-i18next.md +85 -287
  53. package/blog/ko/intlayer_with_next-intl.md +68 -327
  54. package/blog/ko/intlayer_with_react-i18next.md +68 -290
  55. package/blog/ko/intlayer_with_react-intl.md +64 -266
  56. package/blog/pl/intlayer_with_i18next.md +126 -0
  57. package/blog/pl/intlayer_with_next-i18next.md +142 -0
  58. package/blog/pl/intlayer_with_next-intl.md +111 -0
  59. package/blog/pl/intlayer_with_react-i18next.md +124 -0
  60. package/blog/pl/intlayer_with_react-intl.md +122 -0
  61. package/blog/pt/intlayer_with_i18next.md +67 -103
  62. package/blog/pt/intlayer_with_next-i18next.md +72 -293
  63. package/blog/pt/intlayer_with_next-intl.md +57 -256
  64. package/blog/pt/intlayer_with_react-i18next.md +104 -78
  65. package/blog/pt/intlayer_with_react-intl.md +62 -266
  66. package/blog/ru/intlayer_with_i18next.md +66 -104
  67. package/blog/ru/intlayer_with_next-i18next.md +71 -296
  68. package/blog/ru/intlayer_with_next-intl.md +58 -337
  69. package/blog/ru/intlayer_with_react-i18next.md +68 -290
  70. package/blog/ru/intlayer_with_react-intl.md +62 -265
  71. package/blog/tr/intlayer_with_i18next.md +71 -107
  72. package/blog/tr/intlayer_with_next-i18next.md +72 -297
  73. package/blog/tr/intlayer_with_next-intl.md +58 -339
  74. package/blog/tr/intlayer_with_react-i18next.md +69 -291
  75. package/blog/tr/intlayer_with_react-intl.md +63 -285
  76. package/blog/vi/intlayer_with_i18next.md +126 -0
  77. package/blog/vi/intlayer_with_next-i18next.md +142 -0
  78. package/blog/vi/intlayer_with_next-intl.md +111 -0
  79. package/blog/vi/intlayer_with_react-i18next.md +124 -0
  80. package/blog/vi/intlayer_with_react-intl.md +122 -0
  81. package/blog/zh/intlayer_with_i18next.md +67 -102
  82. package/blog/zh/intlayer_with_next-i18next.md +72 -296
  83. package/blog/zh/intlayer_with_next-intl.md +58 -336
  84. package/blog/zh/intlayer_with_react-i18next.md +68 -290
  85. package/blog/zh/intlayer_with_react-intl.md +63 -106
  86. package/docs/ar/plugins/sync-json.md +244 -0
  87. package/docs/de/plugins/sync-json.md +244 -0
  88. package/docs/en/intlayer_cli.md +25 -0
  89. package/docs/en/intlayer_with_nextjs_14.md +2 -0
  90. package/docs/en/intlayer_with_nextjs_15.md +2 -0
  91. package/docs/en/intlayer_with_nextjs_16.md +2 -0
  92. package/docs/en/plugins/sync-json.md +1 -1
  93. package/docs/en-GB/plugins/sync-json.md +244 -0
  94. package/docs/es/plugins/sync-json.md +244 -0
  95. package/docs/fr/plugins/sync-json.md +244 -0
  96. package/docs/hi/plugins/sync-json.md +244 -0
  97. package/docs/id/plugins/sync-json.md +244 -0
  98. package/docs/it/plugins/sync-json.md +244 -0
  99. package/docs/ja/plugins/sync-json.md +244 -0
  100. package/docs/ko/plugins/sync-json.md +244 -0
  101. package/docs/pl/plugins/sync-json.md +244 -0
  102. package/docs/pt/plugins/sync-json.md +244 -0
  103. package/docs/ru/plugins/sync-json.md +244 -0
  104. package/docs/tr/plugins/sync-json.md +245 -0
  105. package/docs/vi/plugins/sync-json.md +244 -0
  106. package/docs/zh/plugins/sync-json.md +244 -0
  107. package/package.json +14 -14
@@ -42,13 +42,7 @@ However, next-i18next comes with some challenges:
42
42
 
43
43
  **Intlayer** is an innovative, open-source internationalization library designed to address the shortcomings of traditional i18n solutions. It offers a modern approach to content management in Next.js applications.
44
44
 
45
- Key advantages of Intlayer:
46
-
47
- - **Declarative content management**: Translations are defined alongside components, improving maintainability.
48
- - **Type-safe by design**: Auto-generated TypeScript types ensure type safety and autocompletion.
49
- - **Flexible content structure**: Supports complex content structures beyond simple key-value pairs.
50
- - **Built-in Visual Editor**: Optional visual editing capabilities for non-technical team members.
51
- - **Framework optimization**: Deep integration with Next.js for optimal performance.
45
+ See a concrete comparison with next-intl in our [next-i18next vs. next-intl vs. Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/blog/en/next-i18next_vs_next-intl_vs_intlayer.md) blog post.
52
46
 
53
47
  ## Why Combine Intlayer with next-i18next?
54
48
 
@@ -58,21 +52,9 @@ While Intlayer provides an excellent standalone i18n solution (see our [Next.js
58
52
  2. **Legacy requirements**: Your project requires compatibility with existing i18next plugins or workflows.
59
53
  3. **Team familiarity**: Your team is comfortable with next-i18next but wants better content management.
60
54
 
61
- This guide shows you how to leverage Intlayer's superior content declaration system while maintaining compatibility with next-i18next.
62
-
63
- ## Intlayer vs. next-i18next: Key Differences
64
-
65
- For a detailed comparison of different i18n solutions including next-i18next and Intlayer, check out our [next-i18next vs. next-intl vs. Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/blog/en/next-i18next_vs_next-intl_vs_intlayer.md) blog post.
55
+ **For that, Intlayer can be implemented as an adapter for next-i18next to help automating your JSON translations in CLI or CI/CD pipelines, testing your translations, and more.**
66
56
 
67
- Key differences:
68
-
69
- | Feature | next-i18next | Intlayer with next-i18next |
70
- | ----------------- | ---------------------------- | -------------------------- |
71
- | Content Location | Separate translation folders | Co-located with components |
72
- | Type Safety | Manual setup required | Auto-generated types |
73
- | Content Structure | Flat key-value pairs | Nested, structured objects |
74
- | Visual Editor | Not included | Built-in optional editor |
75
- | Setup Complexity | Multiple config files | Minimal configuration |
57
+ This guide shows you how to leverage Intlayer's superior content declaration system while maintaining compatibility with next-i18next.
76
58
 
77
59
  ---
78
60
 
@@ -83,15 +65,15 @@ Key differences:
83
65
  Install the necessary packages using your preferred package manager:
84
66
 
85
67
  ```bash packageManager="npm"
86
- npm install intlayer next-intlayer i18next next-i18next i18next-resources-to-backend @intlayer/sync-json-plugin
68
+ npm install intlayer @intlayer/sync-json-plugin
87
69
  ```
88
70
 
89
71
  ```bash packageManager="pnpm"
90
- pnpm add intlayer next-intlayer i18next next-i18next i18next-resources-to-backend @intlayer/sync-json-plugin
72
+ pnpm add intlayer @intlayer/sync-json-plugin
91
73
  ```
92
74
 
93
75
  ```bash packageManager="yarn"
94
- yarn add intlayer next-intlayer i18next next-i18next i18next-resources-to-backend @intlayer/sync-json-plugin
76
+ yarn add intlayer @intlayer/sync-json-plugin
95
77
  ```
96
78
 
97
79
  **Package explanations:**
@@ -103,28 +85,24 @@ yarn add intlayer next-intlayer i18next next-i18next i18next-resources-to-backen
103
85
  - **i18next-resources-to-backend**: Dynamic resource loading for i18next
104
86
  - **@intlayer/sync-json-plugin**: Plugin to sync Intlayer content declarations to i18next JSON format
105
87
 
106
- ### Step 2: Configure Your Project
88
+ ### Step 2: Implement the Intlayer plugin to wrap the JSON
89
+
90
+ Create an Intlayer configuration file to define your supported locales:
107
91
 
108
- Create an Intlayer configuration file to define your locales and set up the sync plugin:
92
+ **If you want to also export JSON dictionaries for i18next**, add the `syncJSON` plugin:
109
93
 
110
- ```typescript fileName="intlayer.config.ts" codeFormat="typescript"
94
+ ```typescript fileName="intlayer.config.ts"
111
95
  import { Locales, type IntlayerConfig } from "intlayer";
112
96
  import { syncJSON } from "@intlayer/sync-json-plugin";
113
97
 
114
98
  const config: IntlayerConfig = {
115
99
  internationalization: {
116
- locales: [
117
- Locales.ENGLISH,
118
- Locales.FRENCH,
119
- Locales.SPANISH,
120
- // Add your other locales
121
- ],
100
+ locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
122
101
  defaultLocale: Locales.ENGLISH,
123
102
  },
124
103
  plugins: [
125
104
  syncJSON({
126
- // Specify where i18next JSON files should be generated
127
- source: ({ key, locale }) => `./intl/messages/${locale}/${key}.json`,
105
+ source: ({ key, locale }) => `./messages/${locale}/${key}.json`,
128
106
  }),
129
107
  ],
130
108
  };
@@ -132,775 +110,16 @@ const config: IntlayerConfig = {
132
110
  export default config;
133
111
  ```
134
112
 
135
- ```javascript fileName="intlayer.config.mjs" codeFormat="esm"
136
- import { Locales } from "intlayer";
137
- import { syncJSON } from "@intlayer/sync-json-plugin";
113
+ The `syncJSON` plugin will automatically wrap the JSON. It will read and write the JSON files without changing the content architecture.
138
114
 
139
- /** @type {import('intlayer').IntlayerConfig} */
140
- const config = {
141
- internationalization: {
142
- locales: [
143
- Locales.ENGLISH,
144
- Locales.FRENCH,
145
- Locales.SPANISH,
146
- // Add your other locales
147
- ],
148
- defaultLocale: Locales.ENGLISH,
149
- },
150
- plugins: [
151
- syncJSON({
152
- source: ({ key, locale }) => `./intl/messages/${locale}/${key}.json`,
153
- }),
154
- ],
155
- };
115
+ If you want to make coexist that JSON with intlayer content declaration files (`.content` files), Intlayer will proceed this way:
156
116
 
157
- export default config;
158
- ```
159
-
160
- ```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
161
- const { Locales } = require("intlayer");
162
- const { syncJSON } = require("@intlayer/sync-json-plugin");
163
-
164
- /** @type {import('intlayer').IntlayerConfig} */
165
- const config = {
166
- internationalization: {
167
- locales: [
168
- Locales.ENGLISH,
169
- Locales.FRENCH,
170
- Locales.SPANISH,
171
- // Add your other locales
172
- ],
173
- defaultLocale: Locales.ENGLISH,
174
- },
175
- plugins: [
176
- syncJSON({
177
- source: ({ key, locale }) => `./intl/messages/${locale}/${key}.json`,
178
- }),
179
- ],
180
- };
181
-
182
- module.exports = config;
183
- ```
184
-
185
- > The `syncJSON` plugin automatically converts Intlayer content declarations to i18next-compatible JSON files. For more configuration options, refer to the [configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md).
186
-
187
- ### Step 3: Integrate Intlayer in Your Next.js Configuration
188
-
189
- Configure your Next.js setup to use Intlayer's build plugin:
190
-
191
- ```typescript fileName="next.config.ts" codeFormat="typescript"
192
- import type { NextConfig } from "next";
193
- import { withIntlayer } from "next-intlayer/server";
194
-
195
- const nextConfig: NextConfig = {
196
- /* your Next.js config options */
197
- };
198
-
199
- export default withIntlayer(nextConfig);
200
- ```
201
-
202
- ```javascript fileName="next.config.mjs" codeFormat="esm"
203
- import { withIntlayer } from "next-intlayer/server";
204
-
205
- /** @type {import('next').NextConfig} */
206
- const nextConfig = {
207
- /* your Next.js config options */
208
- };
209
-
210
- export default withIntlayer(nextConfig);
211
- ```
212
-
213
- ```javascript fileName="next.config.cjs" codeFormat="commonjs"
214
- const { withIntlayer } = require("next-intlayer/server");
215
-
216
- /** @type {import('next').NextConfig} */
217
- const nextConfig = {
218
- /* your Next.js config options */
219
- };
220
-
221
- module.exports = withIntlayer(nextConfig);
222
- ```
223
-
224
- > The `withIntlayer()` plugin ensures that Intlayer content declarations are built and monitored during development. It automatically regenerates i18next JSON files when you modify content declarations.
225
-
226
- ### Step 4: Set Up next-i18next Configuration
227
-
228
- Create the standard next-i18next configuration file:
229
-
230
- ```javascript fileName="next-i18next.config.js"
231
- module.exports = {
232
- i18n: {
233
- defaultLocale: "en",
234
- locales: ["en", "fr", "es"],
235
- },
236
- };
237
- ```
238
-
239
- Update your Next.js config to use next-i18next:
240
-
241
- ```typescript fileName="next.config.ts" codeFormat="typescript"
242
- import type { NextConfig } from "next";
243
- import { withIntlayer } from "next-intlayer/server";
244
-
245
- const nextConfig: NextConfig = {
246
- /* your Next.js config options */
247
- i18n: {
248
- defaultLocale: "en",
249
- locales: ["en", "fr", "es"],
250
- },
251
- };
252
-
253
- export default withIntlayer(nextConfig);
254
- ```
255
-
256
- ```javascript fileName="next.config.mjs" codeFormat="esm"
257
- import { withIntlayer } from "next-intlayer/server";
258
-
259
- /** @type {import('next').NextConfig} */
260
- const nextConfig = {
261
- /* your Next.js config options */
262
- i18n: {
263
- defaultLocale: "en",
264
- locales: ["en", "fr", "es"],
265
- },
266
- };
267
-
268
- export default withIntlayer(nextConfig);
269
- ```
270
-
271
- ```javascript fileName="next.config.cjs" codeFormat="commonjs"
272
- const { withIntlayer } = require("next-intlayer/server");
273
-
274
- /** @type {import('next').NextConfig} */
275
- const nextConfig = {
276
- /* your Next.js config options */
277
- i18n: {
278
- defaultLocale: "en",
279
- locales: ["en", "fr", "es"],
280
- },
281
- };
282
-
283
- module.exports = withIntlayer(nextConfig);
284
- ```
285
-
286
- ### Step 5: Set Up i18next Client Configuration
287
-
288
- Create an i18next configuration file to load the generated resources:
289
-
290
- ```typescript fileName="i18n/client.ts" codeFormat="typescript"
291
- import i18next from "i18next";
292
- import { initReactI18next } from "react-i18next";
293
- import resourcesToBackend from "i18next-resources-to-backend";
294
-
295
- i18next
296
- .use(initReactI18next)
297
- .use(
298
- resourcesToBackend(
299
- (language: string, namespace: string) =>
300
- import(`../intl/messages/${language}/${namespace}.json`)
301
- )
302
- )
303
- .init({
304
- fallbackLng: "en",
305
- // Add other i18next configuration options as needed
306
- });
307
-
308
- export default i18next;
309
- ```
310
-
311
- ```javascript fileName="i18n/client.mjs" codeFormat="esm"
312
- import i18next from "i18next";
313
- import { initReactI18next } from "react-i18next";
314
- import resourcesToBackend from "i18next-resources-to-backend";
315
-
316
- i18next
317
- .use(initReactI18next)
318
- .use(
319
- resourcesToBackend(
320
- (language, namespace) =>
321
- import(`../intl/messages/${language}/${namespace}.json`)
322
- )
323
- )
324
- .init({
325
- fallbackLng: "en",
326
- });
327
-
328
- export default i18next;
329
- ```
330
-
331
- ```javascript fileName="i18n/client.cjs" codeFormat="commonjs"
332
- const i18next = require("i18next");
333
- const { initReactI18next } = require("react-i18next");
334
- const resourcesToBackend = require("i18next-resources-to-backend");
335
-
336
- i18next
337
- .use(initReactI18next)
338
- .use(
339
- resourcesToBackend(
340
- (language, namespace) =>
341
- import(`../intl/messages/${language}/${namespace}.json`)
342
- )
343
- )
344
- .init({
345
- fallbackLng: "en",
346
- });
347
-
348
- module.exports = i18next;
349
- ```
350
-
351
- ### Step 6: Declare Your Content
352
-
353
- Create content declaration files alongside your components:
354
-
355
- ```typescript fileName="src/components/Hero/Hero.content.ts" contentDeclarationFormat="typescript"
356
- import { t, type Dictionary } from "intlayer";
357
-
358
- const heroContent = {
359
- key: "hero",
360
- content: {
361
- title: t({
362
- en: "Welcome to Our Platform",
363
- fr: "Bienvenue sur notre plateforme",
364
- es: "Bienvenido a nuestra plataforma",
365
- }),
366
- description: t({
367
- en: "Discover amazing features and possibilities",
368
- fr: "Découvrez des fonctionnalités et possibilités incroyables",
369
- es: "Descubre características y posibilidades increíbles",
370
- }),
371
- cta: {
372
- primary: t({
373
- en: "Get Started",
374
- fr: "Commencer",
375
- es: "Empezar",
376
- }),
377
- secondary: t({
378
- en: "Learn More",
379
- fr: "En savoir plus",
380
- es: "Saber más",
381
- }),
382
- },
383
- },
384
- } satisfies Dictionary;
385
-
386
- export default heroContent;
387
- ```
388
-
389
- ```javascript fileName="src/components/Hero/Hero.content.mjs" contentDeclarationFormat="esm"
390
- import { t } from "intlayer";
391
-
392
- /** @type {import('intlayer').Dictionary} */
393
- const heroContent = {
394
- key: "hero",
395
- content: {
396
- title: t({
397
- en: "Welcome to Our Platform",
398
- fr: "Bienvenue sur notre plateforme",
399
- es: "Bienvenido a nuestra plataforma",
400
- }),
401
- description: t({
402
- en: "Discover amazing features and possibilities",
403
- fr: "Découvrez des fonctionnalités et possibilités incroyables",
404
- es: "Descubre características y posibilidades increíbles",
405
- }),
406
- cta: {
407
- primary: t({
408
- en: "Get Started",
409
- fr: "Commencer",
410
- es: "Empezar",
411
- }),
412
- secondary: t({
413
- en: "Learn More",
414
- fr: "En savoir plus",
415
- es: "Saber más",
416
- }),
417
- },
418
- },
419
- };
420
-
421
- export default heroContent;
422
- ```
423
-
424
- ```javascript fileName="src/components/Hero/Hero.content.cjs" contentDeclarationFormat="commonjs"
425
- const { t } = require("intlayer");
426
-
427
- /** @type {import('intlayer').Dictionary} */
428
- const heroContent = {
429
- key: "hero",
430
- content: {
431
- title: t({
432
- en: "Welcome to Our Platform",
433
- fr: "Bienvenue sur notre plateforme",
434
- es: "Bienvenido a nuestra plataforma",
435
- }),
436
- description: t({
437
- en: "Discover amazing features and possibilities",
438
- fr: "Découvrez des fonctionnalités et possibilités incroyables",
439
- es: "Descubre características y posibilidades increíbles",
440
- }),
441
- cta: {
442
- primary: t({
443
- en: "Get Started",
444
- fr: "Commencer",
445
- es: "Empezar",
446
- }),
447
- secondary: t({
448
- en: "Learn More",
449
- fr: "En savoir plus",
450
- es: "Saber más",
451
- }),
452
- },
453
- },
454
- };
455
-
456
- module.exports = heroContent;
457
- ```
458
-
459
- ```json fileName="src/components/Hero/Hero.content.json" contentDeclarationFormat="json"
460
- {
461
- "$schema": "https://intlayer.org/schema.json",
462
- "key": "hero",
463
- "content": {
464
- "title": {
465
- "nodeType": "translation",
466
- "translation": {
467
- "en": "Welcome to Our Platform",
468
- "fr": "Bienvenue sur notre plateforme",
469
- "es": "Bienvenido a nuestra plataforma"
470
- }
471
- },
472
- "description": {
473
- "nodeType": "translation",
474
- "translation": {
475
- "en": "Discover amazing features and possibilities",
476
- "fr": "Découvrez des fonctionnalités et possibilités incroyables",
477
- "es": "Descubre características y posibilidades increíbles"
478
- }
479
- },
480
- "cta": {
481
- "primary": {
482
- "nodeType": "translation",
483
- "translation": {
484
- "en": "Get Started",
485
- "fr": "Commencer",
486
- "es": "Empezar"
487
- }
488
- },
489
- "secondary": {
490
- "nodeType": "translation",
491
- "translation": {
492
- "en": "Learn More",
493
- "fr": "En savoir plus",
494
- "es": "Saber más"
495
- }
496
- }
497
- }
498
- }
499
- }
500
- ```
117
+ 1. load both JSON and content declaration files and transform them into a intlayer dictionary.
118
+ 2. if there is conflicts between the JSON and the content declaration files, Intlayer will process to the merge of that all dictionaries. Depending of the priority of the plugins, and the one of the content declaration file (all are configurable).
501
119
 
502
- > Content declarations can be placed anywhere in your `src` directory (or configured `contentDir`). The file must match the pattern `*.content.{ts,tsx,js,jsx,mjs,cjs,json}`. For more details, see the [content declaration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dictionary/content_file.md).
120
+ If changes are made using the CLI to translate the JSON, or using the CMS, Intlayer will update the JSON file with the new translations.
503
121
 
504
- ### Step 7: Build i18next Resources
505
-
506
- Generate the i18next JSON files from your Intlayer content declarations:
507
-
508
- ```bash packageManager="npm"
509
- npx intlayer build
510
- ```
511
-
512
- ```bash packageManager="yarn"
513
- yarn intlayer build
514
- ```
515
-
516
- ```bash packageManager="pnpm"
517
- pnpm intlayer build
518
- ```
519
-
520
- This will generate files in the `./intl/messages` directory:
521
-
522
- ```bash
523
- intl
524
- └── messages
525
- ├── en
526
- │ └── hero.json
527
- ├── fr
528
- │ └── hero.json
529
- └── es
530
- └── hero.json
531
- ```
532
-
533
- Each JSON file contains translations extracted from the corresponding Intlayer content declarations.
534
-
535
- ### Step 8: Utilize Content in Your Code
536
-
537
- Access your translations using next-i18next's hooks:
538
-
539
- ```typescript fileName="src/components/Hero/Hero.tsx" codeFormat="typescript"
540
- import type { FC } from "react";
541
- import { useTranslation } from "next-i18next";
542
-
543
- const Hero: FC = () => {
544
- const { t } = useTranslation("hero");
545
-
546
- return (
547
- <section>
548
- <h1>{t("title")}</h1>
549
- <p>{t("description")}</p>
550
- <div>
551
- <button>{t("cta.primary")}</button>
552
- <button>{t("cta.secondary")}</button>
553
- </div>
554
- </section>
555
- );
556
- };
557
-
558
- export default Hero;
559
- ```
560
-
561
- ```jsx fileName="src/components/Hero/Hero.mjx" codeFormat="esm"
562
- import { useTranslation } from "next-i18next";
563
-
564
- const Hero = () => {
565
- const { t } = useTranslation("hero");
566
-
567
- return (
568
- <section>
569
- <h1>{t("title")}</h1>
570
- <p>{t("description")}</p>
571
- <div>
572
- <button>{t("cta.primary")}</button>
573
- <button>{t("cta.secondary")}</button>
574
- </div>
575
- </section>
576
- );
577
- };
578
-
579
- export default Hero;
580
- ```
581
-
582
- ```jsx fileName="src/components/Hero/Hero.csx" codeFormat="commonjs"
583
- const { useTranslation } = require("next-i18next");
584
-
585
- const Hero = () => {
586
- const { t } = useTranslation("hero");
587
-
588
- return (
589
- <section>
590
- <h1>{t("title")}</h1>
591
- <p>{t("description")}</p>
592
- <div>
593
- <button>{t("cta.primary")}</button>
594
- <button>{t("cta.secondary")}</button>
595
- </div>
596
- </section>
597
- );
598
- };
599
-
600
- module.exports = Hero;
601
- ```
602
-
603
- > The namespace in `useTranslation("hero")` corresponds to the `key` field in your Intlayer content declaration.
604
-
605
- ### (Optional) Step 9: Internationalization of Metadata
606
-
607
- For page metadata, use next-i18next's `serverSideTranslations`:
608
-
609
- ```typescript fileName="src/pages/index.tsx" codeFormat="typescript"
610
- import { GetStaticProps } from "next";
611
- import { serverSideTranslations } from "next-i18next/serverSideTranslations";
612
- import { useTranslation } from "next-i18next";
613
- import Head from "next/head";
614
-
615
- export default function Home() {
616
- const { t } = useTranslation("common");
617
-
618
- return (
619
- <>
620
- <Head>
621
- <title>{t("meta.title")}</title>
622
- <meta name="description" content={t("meta.description")} />
623
- </Head>
624
- {/* Page content */}
625
- </>
626
- );
627
- }
628
-
629
- export const getStaticProps: GetStaticProps = async ({ locale }) => {
630
- return {
631
- props: {
632
- ...(await serverSideTranslations(locale ?? "en", ["common"])),
633
- },
634
- };
635
- };
636
- ```
637
-
638
- Create a corresponding metadata content declaration:
639
-
640
- ```typescript fileName="src/content/metadata.content.ts" contentDeclarationFormat="typescript"
641
- import { t, type Dictionary } from "intlayer";
642
-
643
- const metadataContent = {
644
- key: "common",
645
- content: {
646
- meta: {
647
- title: t({
648
- en: "My Amazing App",
649
- fr: "Mon Application Incroyable",
650
- es: "Mi Aplicación Increíble",
651
- }),
652
- description: t({
653
- en: "Discover the best features of our platform",
654
- fr: "Découvrez les meilleures fonctionnalités de notre plateforme",
655
- es: "Descubre las mejores características de nuestra plataforma",
656
- }),
657
- },
658
- },
659
- } satisfies Dictionary;
660
-
661
- export default metadataContent;
662
- ```
663
-
664
- ### (Optional) Step 10: Internationalization of sitemap.xml and robots.txt
665
-
666
- For sitemap and robots.txt internationalization, you can use next-i18next's locale information:
667
-
668
- ```typescript fileName="src/pages/sitemap.xml.ts" codeFormat="typescript"
669
- import { GetServerSideProps } from "next";
670
-
671
- const SITE_URL = "https://example.com";
672
-
673
- function generateSiteMap(locales: string[]) {
674
- return `<?xml version="1.0" encoding="UTF-8"?>
675
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
676
- xmlns:xhtml="http://www.w3.org/1999/xhtml">
677
- ${locales
678
- .map((locale) => {
679
- return `
680
- <url>
681
- <loc>${SITE_URL}/${locale}</loc>
682
- ${locales
683
- .map((altLocale) => {
684
- return `
685
- <xhtml:link
686
- rel="alternate"
687
- hreflang="${altLocale}"
688
- href="${SITE_URL}/${altLocale}"/>
689
- `;
690
- })
691
- .join("")}
692
- </url>
693
- `;
694
- })
695
- .join("")}
696
- </urlset>
697
- `;
698
- }
699
-
700
- export const getServerSideProps: GetServerSideProps = async ({ res }) => {
701
- const locales = ["en", "fr", "es"];
702
- const sitemap = generateSiteMap(locales);
703
-
704
- res.setHeader("Content-Type", "text/xml");
705
- res.write(sitemap);
706
- res.end();
707
-
708
- return {
709
- props: {},
710
- };
711
- };
712
-
713
- export default function SiteMap() {
714
- return null;
715
- }
716
- ```
717
-
718
- ### (Optional) Step 11: Change the Language of Your Content
719
-
720
- Implement a language switcher using next-i18next:
721
-
722
- ```typescript fileName="src/components/LanguageSwitcher.tsx" codeFormat="typescript"
723
- import { useRouter } from "next/router";
724
- import Link from "next/link";
725
- import type { FC } from "react";
726
-
727
- const LanguageSwitcher: FC = () => {
728
- const router = useRouter();
729
- const { locales, locale: currentLocale, asPath } = router;
730
-
731
- return (
732
- <div>
733
- <p>Current Language: {currentLocale}</p>
734
- <ul>
735
- {locales?.map((locale) => (
736
- <li key={locale}>
737
- <Link href={asPath} locale={locale}>
738
- <a style={{ fontWeight: locale === currentLocale ? "bold" : "normal" }}>
739
- {locale.toUpperCase()}
740
- </a>
741
- </Link>
742
- </li>
743
- ))}
744
- </ul>
745
- </div>
746
- );
747
- };
748
-
749
- export default LanguageSwitcher;
750
- ```
751
-
752
- ```jsx fileName="src/components/LanguageSwitcher.mjx" codeFormat="esm"
753
- import { useRouter } from "next/router";
754
- import Link from "next/link";
755
-
756
- const LanguageSwitcher = () => {
757
- const router = useRouter();
758
- const { locales, locale: currentLocale, asPath } = router;
759
-
760
- return (
761
- <div>
762
- <p>Current Language: {currentLocale}</p>
763
- <ul>
764
- {locales?.map((locale) => (
765
- <li key={locale}>
766
- <Link href={asPath} locale={locale}>
767
- <a
768
- style={{
769
- fontWeight: locale === currentLocale ? "bold" : "normal",
770
- }}
771
- >
772
- {locale.toUpperCase()}
773
- </a>
774
- </Link>
775
- </li>
776
- ))}
777
- </ul>
778
- </div>
779
- );
780
- };
781
-
782
- export default LanguageSwitcher;
783
- ```
784
-
785
- ```jsx fileName="src/components/LanguageSwitcher.csx" codeFormat="commonjs"
786
- const { useRouter } = require("next/router");
787
- const Link = require("next/link");
788
-
789
- const LanguageSwitcher = () => {
790
- const router = useRouter();
791
- const { locales, locale: currentLocale, asPath } = router;
792
-
793
- return (
794
- <div>
795
- <p>Current Language: {currentLocale}</p>
796
- <ul>
797
- {locales?.map((locale) => (
798
- <li key={locale}>
799
- <Link href={asPath} locale={locale}>
800
- <a
801
- style={{
802
- fontWeight: locale === currentLocale ? "bold" : "normal",
803
- }}
804
- >
805
- {locale.toUpperCase()}
806
- </a>
807
- </Link>
808
- </li>
809
- ))}
810
- </ul>
811
- </div>
812
- );
813
- };
814
-
815
- module.exports = LanguageSwitcher;
816
- ```
817
-
818
- ### (Optional) Step 12: Creating a Localized Link Component
819
-
820
- Create a custom Link component that preserves locale context:
821
-
822
- ```typescript fileName="src/components/LocalizedLink.tsx" codeFormat="typescript"
823
- import Link, { LinkProps } from "next/link";
824
- import { useRouter } from "next/router";
825
- import type { FC, PropsWithChildren } from "react";
826
-
827
- const LocalizedLink: FC<PropsWithChildren<LinkProps>> = ({
828
- children,
829
- href,
830
- ...props
831
- }) => {
832
- const router = useRouter();
833
- const { locale } = router;
834
-
835
- return (
836
- <Link href={href} locale={locale} {...props}>
837
- {children}
838
- </Link>
839
- );
840
- };
841
-
842
- export default LocalizedLink;
843
- ```
844
-
845
- ```jsx fileName="src/components/LocalizedLink.mjx" codeFormat="esm"
846
- import Link from "next/link";
847
- import { useRouter } from "next/router";
848
-
849
- const LocalizedLink = ({ children, href, ...props }) => {
850
- const router = useRouter();
851
- const { locale } = router;
852
-
853
- return (
854
- <Link href={href} locale={locale} {...props}>
855
- {children}
856
- </Link>
857
- );
858
- };
859
-
860
- export default LocalizedLink;
861
- ```
862
-
863
- ```jsx fileName="src/components/LocalizedLink.csx" codeFormat="commonjs"
864
- const Link = require("next/link");
865
- const { useRouter } = require("next/router");
866
-
867
- const LocalizedLink = ({ children, href, ...props }) => {
868
- const router = useRouter();
869
- const { locale } = router;
870
-
871
- return (
872
- <Link href={href} locale={locale} {...props}>
873
- {children}
874
- </Link>
875
- );
876
- };
877
-
878
- module.exports = LocalizedLink;
879
- ```
880
-
881
- ---
882
-
883
- ## TypeScript Configuration
884
-
885
- Intlayer generates TypeScript type definitions for your content. To enable these types:
886
-
887
- ```json5 fileName="tsconfig.json"
888
- {
889
- "compilerOptions": {
890
- // Your existing TypeScript config
891
- },
892
- "include": [
893
- "src",
894
- ".intlayer/**/*.ts", // Include Intlayer auto-generated types
895
- ],
896
- }
897
- ```
898
-
899
- This provides:
900
-
901
- - **Autocompletion** for translation keys
902
- - **Type checking** to catch missing translations
903
- - **IntelliSense** support in your IDE
122
+ To see more details about the `syncJSON` plugin, please refer to the [syncJSON plugin documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/plugins/sync-json.md).
904
123
 
905
124
  ---
906
125
 
@@ -916,52 +135,8 @@ intl
916
135
 
917
136
  These files are automatically regenerated during the build process and don't need to be committed to your repository.
918
137
 
919
- ---
920
-
921
- ## VS Code Extension
922
-
923
- Intlayer provides a VS Code extension to enhance your development experience:
924
-
925
- [Install from VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
926
-
927
- Features:
928
-
929
- - **Autocompletion** for content keys
930
- - **Inline previews** of translations
931
- - **Error detection** for missing translations
932
- - **Quick actions** for managing content
933
-
934
- For more details, see the [VS Code Extension documentation](https://intlayer.org/doc/vs-code-extension).
935
-
936
- ---
937
-
938
- ## Development Workflow
939
-
940
- When working with this setup:
941
-
942
- 1. **Declare content** in `*.content.*` files alongside your components
943
- 2. **Build translations** with `intlayer build` (or let Next.js plugin auto-rebuild in dev mode)
944
- 3. **Use translations** in components via `useTranslation` from next-i18next
945
- 4. **Benefit from TypeScript** autocompletion and type checking
946
-
947
- ---
948
-
949
- ## Going Further
950
-
951
- - **Visual Editor**: Consider implementing the [Intlayer Visual Editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_visual_editor.md) for non-technical team members
952
- - **CMS Integration**: Externalize your content using the [Intlayer CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md)
953
- - **Full Intlayer Migration**: For new projects or major refactors, consider using [pure Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_nextjs_16.md) for the best developer experience
954
-
955
- ---
956
-
957
- ## Conclusion
958
-
959
- By combining Intlayer's superior content declaration system with next-i18next's mature i18n infrastructure, you get:
138
+ ### VS Code Extension
960
139
 
961
- **Better content organization** - Co-located with components
962
- ✅ **Type safety** - Auto-generated TypeScript types
963
- ✅ **Easier maintenance** - Single source of truth for translations
964
- ✅ **Compatibility** - Works with existing i18next ecosystem
965
- ✅ **Flexibility** - Gradual migration path from pure next-i18next
140
+ For improved developer experience, install the official **Intlayer VS Code Extension**:
966
141
 
967
- This approach is ideal for teams that want to improve their i18n workflow while maintaining compatibility with the i18next ecosystem.
142
+ [Install from the VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)