@intlayer/docs 7.3.11 → 7.3.13

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 (90) hide show
  1. package/dist/cjs/generated/docs.entry.cjs +19 -0
  2. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  3. package/dist/esm/generated/docs.entry.mjs +19 -0
  4. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  5. package/dist/types/generated/docs.entry.d.ts +1 -0
  6. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  7. package/docs/ar/intlayer_with_nuxt.md +294 -438
  8. package/docs/ar/intlayer_with_react_router_v7.md +33 -4
  9. package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +516 -0
  10. package/docs/ar/intlayer_with_tanstack.md +2 -12
  11. package/docs/ar/intlayer_with_vite+vue.md +1 -0
  12. package/docs/de/intlayer_with_nuxt.md +284 -410
  13. package/docs/de/intlayer_with_react_router_v7.md +33 -4
  14. package/docs/de/intlayer_with_react_router_v7_fs_routes.md +573 -0
  15. package/docs/de/intlayer_with_tanstack.md +1 -0
  16. package/docs/de/intlayer_with_vite+vue.md +1 -0
  17. package/docs/en/intlayer_with_nuxt.md +237 -341
  18. package/docs/en/intlayer_with_react_router_v7.md +24 -0
  19. package/docs/en/intlayer_with_react_router_v7_fs_routes.md +570 -0
  20. package/docs/en/intlayer_with_tanstack.md +2 -12
  21. package/docs/en/intlayer_with_vite+vue.md +49 -48
  22. package/docs/en-GB/intlayer_with_nuxt.md +254 -378
  23. package/docs/en-GB/intlayer_with_react_router_v7.md +33 -4
  24. package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +513 -0
  25. package/docs/en-GB/intlayer_with_tanstack.md +2 -12
  26. package/docs/en-GB/intlayer_with_vite+vue.md +1 -0
  27. package/docs/es/intlayer_with_nuxt.md +271 -390
  28. package/docs/es/intlayer_with_react_router_v7.md +33 -4
  29. package/docs/es/intlayer_with_react_router_v7_fs_routes.md +575 -0
  30. package/docs/es/intlayer_with_tanstack.md +1 -0
  31. package/docs/es/intlayer_with_vite+vue.md +1 -2
  32. package/docs/fr/intlayer_with_nuxt.md +278 -405
  33. package/docs/fr/intlayer_with_react_router_v7.md +34 -5
  34. package/docs/fr/intlayer_with_react_router_v7_fs_routes.md +574 -0
  35. package/docs/fr/intlayer_with_tanstack.md +1 -0
  36. package/docs/fr/intlayer_with_vite+vue.md +1 -0
  37. package/docs/hi/intlayer_with_nuxt.md +303 -447
  38. package/docs/hi/intlayer_with_react_router_v7.md +33 -4
  39. package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +518 -0
  40. package/docs/hi/intlayer_with_tanstack.md +2 -12
  41. package/docs/hi/intlayer_with_vite+vue.md +1 -0
  42. package/docs/id/intlayer_with_nuxt.md +266 -395
  43. package/docs/id/intlayer_with_react_router_v7.md +29 -4
  44. package/docs/id/intlayer_with_react_router_v7_fs_routes.md +521 -0
  45. package/docs/id/intlayer_with_tanstack.md +2 -12
  46. package/docs/id/intlayer_with_vite+vue.md +1 -0
  47. package/docs/it/intlayer_with_nuxt.md +299 -423
  48. package/docs/it/intlayer_with_react_router_v7.md +33 -4
  49. package/docs/it/intlayer_with_react_router_v7_fs_routes.md +574 -0
  50. package/docs/it/intlayer_with_tanstack.md +1 -0
  51. package/docs/ja/intlayer_with_nuxt.md +309 -432
  52. package/docs/ja/intlayer_with_react_router_v7.md +33 -4
  53. package/docs/ja/intlayer_with_react_router_v7_fs_routes.md +574 -0
  54. package/docs/ja/intlayer_with_tanstack.md +2 -12
  55. package/docs/ja/intlayer_with_vite+vue.md +1 -0
  56. package/docs/ko/intlayer_with_nuxt.md +295 -422
  57. package/docs/ko/intlayer_with_react_router_v7.md +33 -4
  58. package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +515 -0
  59. package/docs/ko/intlayer_with_tanstack.md +2 -12
  60. package/docs/ko/intlayer_with_vite+vue.md +1 -0
  61. package/docs/pl/intlayer_with_nuxt.md +273 -476
  62. package/docs/pl/intlayer_with_react_router_v7.md +32 -5
  63. package/docs/pl/intlayer_with_react_router_v7_fs_routes.md +615 -0
  64. package/docs/pl/intlayer_with_tanstack.md +2 -12
  65. package/docs/pl/intlayer_with_vite+vue.md +1 -0
  66. package/docs/pt/intlayer_with_nuxt.md +277 -420
  67. package/docs/pt/intlayer_with_react_router_v7.md +28 -0
  68. package/docs/pt/intlayer_with_tanstack.md +1 -0
  69. package/docs/ru/intlayer_with_nuxt.md +287 -425
  70. package/docs/ru/intlayer_with_react_router_v7.md +33 -4
  71. package/docs/ru/intlayer_with_react_router_v7_fs_routes.md +574 -0
  72. package/docs/ru/intlayer_with_tanstack.md +1 -0
  73. package/docs/ru/intlayer_with_vite+vue.md +1 -0
  74. package/docs/tr/intlayer_with_nuxt.md +313 -406
  75. package/docs/tr/intlayer_with_react_router_v7.md +33 -4
  76. package/docs/tr/intlayer_with_react_router_v7_fs_routes.md +572 -0
  77. package/docs/tr/intlayer_with_tanstack.md +2 -12
  78. package/docs/tr/intlayer_with_vite+vue.md +1 -0
  79. package/docs/vi/intlayer_with_nuxt.md +273 -418
  80. package/docs/vi/intlayer_with_react_router_v7.md +29 -4
  81. package/docs/vi/intlayer_with_react_router_v7_fs_routes.md +523 -0
  82. package/docs/vi/intlayer_with_tanstack.md +2 -12
  83. package/docs/vi/intlayer_with_vite+vue.md +1 -0
  84. package/docs/zh/intlayer_with_nuxt.md +300 -461
  85. package/docs/zh/intlayer_with_react_router_v7.md +33 -4
  86. package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +516 -0
  87. package/docs/zh/intlayer_with_tanstack.md +2 -12
  88. package/docs/zh/intlayer_with_vite+vue.md +1 -0
  89. package/package.json +10 -11
  90. package/src/generated/docs.entry.ts +19 -0
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  createdAt: 2025-06-18
3
- updatedAt: 2025-06-29
4
- title: How to translate your Nuxt app – i18n guide 2025
3
+ updatedAt: 2025-12-07
4
+ title: How to translate your Nuxt and Vue app – i18n guide 2025
5
5
  description: Discover how to make your Nuxt and Vue website multilingual. Follow the documentation to internationalise (i18n) and translate it.
6
6
  keywords:
7
7
  - Internationalisation
@@ -14,16 +14,22 @@ slugs:
14
14
  - doc
15
15
  - environment
16
16
  - nuxt-and-vue
17
- applicationTemplate: https://github.com/aymericzip/intlayer-nuxt-template
17
+ applicationTemplate: https://github.com/aymericzip/intlayer-nuxt-4-template
18
+ youtubeVideo: https://www.youtube.com/watch?v=nhUcUAVQ6eQ
18
19
  history:
20
+ - version: 7.3.11
21
+ date: 2025-12-07
22
+ changes: Update LocaleSwitcher, SEO, metadata
19
23
  - version: 5.5.10
20
24
  date: 2025-06-29
21
25
  changes: Init history
22
26
  ---
23
27
 
24
- # Getting Started Internationalising (i18n) with Intlayer and Nuxt
28
+ # Translate your Nuxt and Vue website using Intlayer | Internationalisation (i18n)
25
29
 
26
- See [Application Template](https://github.com/aymericzip/intlayer-nuxt-template) on GitHub.
30
+ ## Table of Contents
31
+
32
+ <TOC/>
27
33
 
28
34
  ## What is Intlayer?
29
35
 
@@ -40,6 +46,27 @@ With Intlayer, you can:
40
46
 
41
47
  ## Step-by-Step Guide to Set Up Intlayer in a Nuxt Application
42
48
 
49
+ <Tab defaultTab="video">
50
+ <TabItem label="Video" value="video">
51
+
52
+ <iframe title="How to translate your Nuxt and Vue app using Intlayer? Discover 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/nhUcUAVQ6eQ?autoplay=0&amp;origin=http://intlayer.org&amp;controls=0&amp;rel=1"/>
53
+
54
+ </TabItem>
55
+ <TabItem label="Code" value="code">
56
+
57
+ <iframe
58
+ src="https://stackblitz.com/github/aymericzip/intlayer-nuxt-4-template?embed=1&ctl=1&file=intlayer.config.ts"
59
+ className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
60
+ title="Demo CodeSandbox - How to Internationalise your application using Intlayer"
61
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
62
+ loading="lazy"
63
+ />
64
+
65
+ </TabItem>
66
+ </Tab>
67
+
68
+ See [Application Template](https://github.com/aymericzip/intlayer-nuxt-4-template) on GitHub.
69
+
43
70
  ### Step 1: Install Dependencies
44
71
 
45
72
  Install the necessary packages using npm:
@@ -61,7 +88,7 @@ yarn add --save-dev nuxt-intlayer
61
88
 
62
89
  - **intlayer**
63
90
 
64
- The core package that provides internationalisation tools for configuration management, translation, [content declaration](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/dictionary/get_started.md), transpilation, and [CLI commands](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_cli.md).
91
+ The core package that provides internationalisation tools for configuration management, translation, [content declaration](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/dictionary/content_file.md), transpilation, and [CLI commands](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/cli/index.md).
65
92
 
66
93
  - **vue-intlayer**
67
94
  The package that integrates Intlayer with Vue applications. It provides the composables for the Vue components.
@@ -86,9 +113,6 @@ const config: IntlayerConfig = {
86
113
  ],
87
114
  defaultLocale: Locales.ENGLISH,
88
115
  },
89
- content: {
90
- contentDir: ["."], // Because by default Intlayer will watch content declaration files from the `./src` directory
91
- },
92
116
  };
93
117
 
94
118
  export default config;
@@ -98,7 +122,6 @@ export default config;
98
122
  import { Locales } from "intlayer";
99
123
 
100
124
  /** @type {import('intlayer').IntlayerConfig} */
101
- // Configuration object for Intlayer
102
125
  const config = {
103
126
  internationalization: {
104
127
  locales: [
@@ -109,9 +132,6 @@ const config = {
109
132
  ],
110
133
  defaultLocale: Locales.ENGLISH,
111
134
  },
112
- content: {
113
- contentDir: ["."], // Default directory for content declarations
114
- },
115
135
  };
116
136
 
117
137
  export default config;
@@ -121,7 +141,6 @@ export default config;
121
141
  const { Locales } = require("intlayer");
122
142
 
123
143
  /** @type {import('intlayer').IntlayerConfig} */
124
- // Configuration object for Intlayer
125
144
  const config = {
126
145
  internationalization: {
127
146
  locales: [
@@ -132,15 +151,12 @@ const config = {
132
151
  ],
133
152
  defaultLocale: Locales.ENGLISH,
134
153
  },
135
- content: {
136
- contentDir: ["."],
137
- },
138
154
  };
139
155
 
140
156
  module.exports = config;
141
157
  ```
142
158
 
143
- > Through this configuration file, you can configure localised URLs, middleware redirection, cookie names, the location and extension of your content declarations, disable Intlayer logs in the console, and more. For a complete list of available parameters, refer to the [configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/configuration.md).
159
+ > Through this configuration file, you can set up localised URLs, middleware redirection, cookie names, the location and extension of your content declarations, disable Intlayer logs in the console, and more. For a complete list of available parameters, refer to the [configuration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/configuration.md).
144
160
 
145
161
  ### Step 3: Integrate Intlayer in Your Nuxt Configuration
146
162
 
@@ -161,220 +177,36 @@ export default defineNuxtConfig({
161
177
 
162
178
  Create and manage your content declarations to store translations:
163
179
 
164
- ```tsx fileName="components/helloWorld.content.ts" contentDeclarationFormat="typescript"
165
- import { t, type Dictionary } from "intlayer";
180
+ ```tsx fileName="content/home-page.content.ts" contentDeclarationFormat="typescript"
181
+ import { type Dictionary, t } from "intlayer";
166
182
 
167
- const helloWorldContent = {
168
- key: "helloworld",
183
+ const content = {
184
+ key: "home-page",
169
185
  content: {
170
- count: t({ en: "count is ", fr: "le compte est ", es: "el recuento es " }),
171
- edit: t({
172
- en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
173
- fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
174
- es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
175
- }),
176
- checkOut: t({
177
- "en-GB": "Check out ",
178
- en: "Check out ",
179
- fr: "Vérifiez ",
180
- es: "Compruebe ",
181
- }),
182
- nuxtIntlayer: t({
183
- "en-GB": "Nuxt Intlayer documentation",
184
- en: "Nuxt Intlayer documentation",
185
- fr: "Documentation de Nuxt Intlayer",
186
- es: "Documentación de Nuxt Intlayer",
187
- }),
188
- learnMore: t({
189
- "en-GB": "Learn more about Nuxt in the ",
190
- en: "Learn more about Nuxt in the ",
191
- fr: "En savoir plus sur Nuxt dans la ",
192
- es: "Aprenda más sobre Nuxt en la ",
186
+ title: t({
187
+ en: "Hello world",
188
+ fr: "Bonjour le monde",
189
+ es: "Hola mundo",
193
190
  }),
194
- nuxtDocs: t({
195
- "en-GB": "Nuxt Documentation",
196
- en: "Nuxt Documentation",
197
- fr: "Documentation Nuxt",
198
- es: "Documentación de Nuxt",
191
+ metaTitle: t({
192
+ en: "Welcome | My Application",
193
+ fr: "Bienvenue | Mon Application",
194
+ es: "Bienvenido | Mi Aplicación",
199
195
  }),
200
- readTheDocs: t({
201
- "en-GB": "Click on the Nuxt logo to learn more",
202
- fr: "Cliquez sur le logo Nuxt pour en savoir plus",
203
- es: "Haga clic en el logotipo de Nuxt para obtener más información",
196
+ metaDescription: t({
197
+ en: "Discover your multilingual Nuxt app homepage powered by Intlayer.",
198
+ fr: "Découvrez la page d'accueil multilingue de votre application Nuxt propulsée par Intlayer.",
199
+ es: "Descubre la página de inicio multilingüe de tu aplicación Nuxt impulsada por Intlayer.",
204
200
  }),
205
201
  },
206
202
  } satisfies Dictionary;
207
203
 
208
- export default helloWorldContent;
209
- ```
210
-
211
- ```javascript fileName="components/helloWorld.content.mjs" contentDeclarationFormat="esm"
212
- import { t } from "intlayer";
213
-
214
- /** @type {import('intlayer').Dictionary} */
215
- const helloWorldContent = {
216
- key: "helloworld",
217
- content: {
218
- count: t({
219
- "en-GB": "count is ",
220
- en: "count is ",
221
- fr: "le compte est ",
222
- es: "el recuento es ",
223
- }),
224
- edit: t({
225
- "en-GB":
226
- "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
227
- en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
228
- fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
229
- es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
230
- }),
231
- checkOut: t({ "en-GB": "Check out ", fr: "Vérifiez ", es: "Compruebe " }),
232
- nuxtIntlayer: t({
233
- "en-GB": "Nuxt Intlayer documentation",
234
- fr: "Documentation de Nuxt Intlayer",
235
- es: "Documentación de Nuxt Intlayer",
236
- }),
237
- learnMore: t({
238
- "en-GB": "Learn more about Nuxt in the ",
239
- fr: "En savoir plus sur Nuxt dans la ",
240
- es: "Aprenda más sobre Nuxt en la ",
241
- }),
242
- nuxtDocs: t({
243
- "en-GB": "Nuxt Documentation",
244
- fr: "Documentation Nuxt",
245
- es: "Documentación de Nuxt",
246
- }),
247
- readTheDocs: t({
248
- "en-GB": "Click on the Nuxt logo to learn more",
249
- fr: "Cliquez sur le logo Nuxt pour en savoir plus",
250
- es: "Haga clic en el logotipo de Nuxt para obtener más información",
251
- }),
252
- },
253
- };
254
-
255
- export default helloWorldContent;
256
- ```
257
-
258
- ```const { t } = require("intlayer");
259
-
260
- /** @type {import('intlayer').Dictionary} */
261
- const helloWorldContent = {
262
- key: "helloworld",
263
- content: {
264
- count: t({ 'en-GB': "count is ", en: "count is ", fr: "le compte est ", es: "el recuento es " }),
265
- edit: t({
266
- 'en-GB': "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
267
- en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
268
- fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
269
- es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
270
- }),
271
- checkOut: t({ 'en-GB': "Check out ", en: "Check out ", fr: "Vérifiez ", es: "Compruebe " }),
272
- nuxtIntlayer: t({
273
- 'en-GB': "Nuxt Intlayer documentation",
274
- en: "Nuxt Intlayer documentation",
275
- fr: "Documentation de Nuxt Intlayer",
276
- es: "Documentación de Nuxt Intlayer",
277
- }),
278
- es: "Documentación de Nuxt Intlayer",
279
- }),
280
- learnMore: t({
281
- 'en-GB': "Learn more about Nuxt in the ",
282
- en: "Learn more about Nuxt in the ",
283
- fr: "En savoir plus sur Nuxt dans la ",
284
- es: "Aprenda más sobre Nuxt en la ",
285
- }),
286
- nuxtDocs: t({
287
- 'en-GB': "Nuxt Documentation",
288
- en: "Nuxt Documentation",
289
- fr: "Documentation Nuxt",
290
- es: "Documentación de Nuxt",
291
- }),
292
- readTheDocs: t({
293
- 'en-GB': "Click on the Nuxt logo to learn more",
294
- en: "Click on the Nuxt logo to learn more",
295
- fr: "Cliquez sur le logo Nuxt pour en savoir plus",
296
- es: "Haga clic en el logotipo de Nuxt para obtener más información",
297
- }),
298
- },
299
- };
300
-
301
- module.exports = helloWorldContent;
302
- ```
303
-
304
- ```json fileName="components/helloWorld.content.json" contentDeclarationFormat="json"
305
- {
306
- "$schema": "https://intlayer.org/schema.json",
307
- "key": "helloworld",
308
- "content": {
309
- "count": {
310
- "nodeType": "translation",
311
- "translation": {
312
- "en-GB": "count is ",
313
- "en": "count is ",
314
- "fr": "le compte est ",
315
- "es": "el recuento es "
316
- }
317
- },
318
- "edit": {
319
- "nodeType": "translation",
320
- "translation": {
321
- "en-GB": "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
322
- "en": "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
323
- "fr": "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
324
- "es": "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR"
325
- }
326
- },
327
- "checkOut": {
328
- "nodeType": "translation",
329
- "translation": {
330
- "en-GB": "Check out ",
331
- "en": "Check out ",
332
- "fr": "Vérifiez ",
333
- "es": "Compruebe "
334
- }
335
- },
336
- "nuxtIntlayer": {
337
- "nodeType": "translation",
338
- "translation": {
339
- "en-GB": "Nuxt Intlayer documentation",
340
- "fr": "Documentation de Nuxt Intlayer",
341
- "es": "Documentación de Nuxt Intlayer"
342
- }
343
- },
344
- "learnMore": {
345
- "nodeType": "translation",
346
- "translation": {
347
- "en-GB": "Learn more about Nuxt in the ",
348
- "fr": "En savoir plus sur Nuxt dans la ",
349
- "es": "Aprenda más sobre Nuxt en la "
350
- }
351
- },
352
- "nuxtDocs": {
353
- "nodeType": "translation",
354
- "translation": {
355
- "en-GB": "Nuxt Documentation",
356
- "fr": "Documentation Nuxt",
357
- "es": "Documentación de Nuxt"
358
- }
359
- },
360
- "readTheDocs": {
361
- "nodeType": "translation",
362
- "translation": {
363
- "en-GB": "Click on the Nuxt logo to learn more",
364
- "fr": "Cliquez sur le logo Nuxt pour en savoir plus",
365
- "en-GB": "Click on the Nuxt logo to learn more",
366
- "en": "Click on the Nuxt logo to learn more",
367
- "fr": "Cliquez sur le logo Nuxt pour en savoir plus",
368
- "es": "Haga clic en el logotipo de Nuxt para obtener más información"
369
- }
370
- }
371
- }
372
- }
204
+ export default content;
373
205
  ```
374
206
 
375
207
  > Your content declarations can be defined anywhere in your application as long as they are included in the `contentDir` directory (by default, `./src`). And match the content declaration file extension (by default, `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
376
208
 
377
- > For more details, refer to the [content declaration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/dictionary/get_started.md).
209
+ > For more details, refer to the [content declaration documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dictionary/content_file.md).
378
210
 
379
211
  ### Step 5: Utilise Intlayer in Your Code
380
212
 
@@ -441,7 +273,7 @@ Intlayer offers different APIs to access your content:
441
273
  Use `<div v-html="myContent" />` to render the content as raw HTML, without Visual Editor support.
442
274
 
443
275
  - **Destructuration syntax**:
444
- The `useIntlayer` composable returns a Proxy with the content. This proxy can be destructured to access the content while maintaining reactivity.
276
+ The `useIntlayer` composable returns a Proxy with the content. This proxy can be destructured to access the content while keeping the reactivity.
445
277
  - Use `const content = useIntlayer("myContent");` and `{{ content.myContent }}` / `<content.myContent />`.
446
278
  - Or use `const { myContent } = useIntlayer("myContent");` and `{{ myContent }}` / `<myContent />` to destructure the content.
447
279
 
@@ -449,64 +281,54 @@ Intlayer offers different APIs to access your content:
449
281
 
450
282
  To change the language of your content, you can use the `setLocale` function provided by the `useLocale` composable. This function allows you to set the locale of the application and update the content accordingly.
451
283
 
452
- Create a component to switch between languages:
284
+ Create a component to switch between languages using `NuxtLink`. **Using links instead of buttons for locale switching is a best practice for SEO and page discoverability**, as it allows search engines to crawl and index all localised versions of your pages:
453
285
 
454
286
  ```vue fileName="components/LocaleSwitcher.vue"
455
- <template>
456
- <div class="locale-switcher">
457
- <select v-model="selectedLocale" @change="changeLocale">
458
- <option v-for="loc in availableLocales" :key="loc" :value="loc">
459
- {{ getLocaleName(loc) }}
460
- </option>
461
- </select>
462
- </div>
463
- </template>
464
-
465
287
  <script setup lang="ts">
466
- import { ref, watch } from "vue";
467
- import { getLocaleName } from "intlayer";
288
+ import { getLocaleName, getLocalizedUrl } from "intlayer";
468
289
  import { useLocale } from "vue-intlayer";
469
290
 
470
- // Get locale information and setLocale function
291
+ // Nuxt auto-imports useRoute
292
+ const route = useRoute();
471
293
  const { locale, availableLocales, setLocale } = useLocale();
472
-
473
- // Track the selected locale with a ref
474
- const selectedLocale = ref(locale.value);
475
-
476
- // Update the locale when the selection changes
477
- const changeLocale = () => setLocale(selectedLocale.value);
478
-
479
- // Keep the selectedLocale in sync with the global locale
480
- watch(
481
- () => locale.value,
482
- (newLocale) => {
483
- selectedLocale.value = newLocale;
484
- }
485
- );
486
294
  </script>
295
+
296
+ <template>
297
+ <nav class="locale-switcher">
298
+ <NuxtLink
299
+ v-for="localeEl in availableLocales"
300
+ :key="localeEl"
301
+ :to="getLocalizedUrl(route.fullPath, localeEl)"
302
+ class="locale-link"
303
+ :class="{ 'active-locale': localeEl === locale }"
304
+ @click="setLocale(localeEl)"
305
+ >
306
+ {{ getLocaleName(localeEl) }}
307
+ </NuxtLink>
308
+ </nav>
487
309
  </template>
310
+ ```
488
311
 
489
- <style scoped>
490
- .locale-switcher {
491
- margin: 1rem 0;
492
- }
312
+ > Using `NuxtLink` with proper `href` attributes (via `getLocalizedUrl`) ensures that search engines can discover all language variants of your pages. This is preferable to JavaScript-only locale switching, which search engine crawlers may not follow.
493
313
 
494
- select {
495
- padding: 0.5rem;
496
- border-radius: 0.25rem;
497
- border: 1px solid #ccc;
498
- }
499
- </style>
314
+ Then, set up your `app.vue` to use layouts:
315
+
316
+ ```vue fileName="app.vue"
317
+ <template>
318
+ <NuxtLayout>
319
+ <NuxtPage />
320
+ </NuxtLayout>
321
+ </template>
500
322
  ```
501
323
 
502
- Then, use this component in your pages or layout:
324
+ ### (Optional) Step 6b: Create a Layout with Navigation
503
325
 
504
- ```vue fileName="app.vue"
326
+ Nuxt layouts allow you to define a common structure for your pages. Create a default layout that includes the locale switcher and navigation:
327
+
328
+ ```vue fileName="layouts/default.vue"
505
329
  <script setup lang="ts">
506
- import { useIntlayer } from "vue-intlayer";
330
+ import Links from "~/components/Links.vue";
507
331
  import LocaleSwitcher from "~/components/LocaleSwitcher.vue";
508
-
509
- const content = useIntlayer("app"); // Create related intlayer declaration file
510
332
  </script>
511
333
 
512
334
  <template>
@@ -515,12 +337,17 @@ const content = useIntlayer("app"); // Create related intlayer declaration file
515
337
  <LocaleSwitcher />
516
338
  </header>
517
339
  <main>
518
- <NuxtPage />
340
+ <slot />
519
341
  </main>
342
+
343
+ <Links href="/">Home</Links>
344
+ <Links href="/about">About</Links>
520
345
  </div>
521
346
  </template>
522
347
  ```
523
348
 
349
+ The `Links` component (shown below) ensures that internal navigation links are automatically localised.
350
+
524
351
  ### (Optional) Step 7: Add localised Routing to your application
525
352
 
526
353
  Nuxt automatically handles localised routing when using the `nuxt-intlayer` module. This creates routes for each language automatically based on your pages directory structure.
@@ -535,23 +362,58 @@ pages/
535
362
  └── index.vue → /contact, /fr/contact, /es/contact
536
363
  ```
537
364
 
538
- To create a localised page, simply create your Vue files in the `pages/` directory:
365
+ To create localised pages, simply create your Vue files in the `pages/` directory. Here are two example pages:
366
+
367
+ **Home page (`pages/index.vue`):**
368
+
369
+ ```vue fileName="pages/index.vue"
370
+ <script setup lang="ts">
371
+ import { useIntlayer } from "vue-intlayer";
372
+
373
+ const content = useIntlayer("home-page");
374
+
375
+ useHead({
376
+ title: content.metaTitle.value,
377
+ meta: [
378
+ {
379
+ name: "description",
380
+ content: content.metaDescription.value,
381
+ },
382
+ ],
383
+ });
384
+ </script>
385
+
386
+ <template>
387
+ <h1><content.title /></h1>
388
+ </template>
389
+ ```
390
+
391
+ **About page (`pages/about.vue`):**
539
392
 
540
393
  ```vue fileName="pages/about.vue"
541
394
  <script setup lang="ts">
542
395
  import { useIntlayer } from "vue-intlayer";
543
396
 
544
- const content = useIntlayer("about");
397
+ const content = useIntlayer("about-page");
398
+
399
+ useHead({
400
+ title: content.metaTitle.raw, // Use .raw for primitive string access
401
+ meta: [
402
+ {
403
+ name: "description",
404
+ content: content.metaDescription.raw, // Use .raw for primitive string access
405
+ },
406
+ ],
407
+ });
545
408
  </script>
546
409
 
547
410
  <template>
548
- <div>
549
- <h1>{{ content.title }}</h1>
550
- <p>{{ content.description }}</p>
551
- </div>
411
+ <h1><content.title /></h1>
552
412
  </template>
553
413
  ```
554
414
 
415
+ > Note: `useHead` is auto-imported in Nuxt. You can access content values using either `.value` (reactive) or `.raw` (primitive string) depending on your needs.
416
+
555
417
  The `nuxt-intlayer` module will automatically:
556
418
 
557
419
  - Detect the user's preferred locale
@@ -562,217 +424,233 @@ The `nuxt-intlayer` module will automatically:
562
424
 
563
425
  ### (Optional) Step 8: Creating a Localised Link Component
564
426
 
565
- To ensure that your application's navigation respects the current locale, you can create a custom `LocalisedLink` component. This component automatically prefixes internal URLs with the current language.
566
-
567
- ```vue fileName="components/LocalisedLink.vue"
568
- <template>
569
- <NuxtLink :to="localisedHref" v-bind="$attrs">
570
- <slot />
571
- </NuxtLink>
572
- </template>
427
+ To ensure that your application's navigation respects the current locale, you can create a custom `Links` component. This component automatically prefixes internal URLs with the current language, which is essential for **SEO and page discoverability**.
573
428
 
429
+ ```vue fileName="components/Links.vue"
574
430
  <script setup lang="ts">
575
- import { computed } from "vue";
576
431
  import { getLocalizedUrl } from "intlayer";
577
432
  import { useLocale } from "vue-intlayer";
578
433
 
579
- const props = defineProps({
580
- to: {
581
- type: String,
582
- required: true,
583
- },
584
- });
434
+ interface Props {
435
+ href: string;
436
+ locale?: string;
437
+ }
438
+
439
+ const props = defineProps<Props>();
440
+
441
+ const { locale: currentLocale } = useLocale();
585
442
 
586
- const { locale } = useLocale();
443
+ // Compute the final path
444
+ const finalPath = computed(() => {
445
+ // 1. Check if the link is external
446
+ const isExternal = /^https?:\/\//.test(props.href || "");
587
447
 
588
- // Check if the link is external
589
- const isExternalLink = computed(() => /^https?:\/\//.test(props.to || ""));
448
+ // 2. If external, return as is (NuxtLink handles the <a> tag generation)
449
+ if (isExternal) return props.href;
590
450
 
591
- // Create a localised href for internal links
592
- const localizedHref = computed(() =>
593
- isExternalLink.value ? props.to : getLocalizedUrl(props.to, locale.value)
594
- );
451
+ // 3. If internal, localise the URL
452
+ const targetLocale = props.locale || currentLocale.value;
453
+ return getLocalizedUrl(props.href, targetLocale);
454
+ });
595
455
  </script>
456
+
457
+ <template>
458
+ <NuxtLink :to="finalPath" v-bind="$attrs">
459
+ <slot />
460
+ </NuxtLink>
461
+ </template>
596
462
  ```
597
463
 
598
464
  Then use this component throughout your application:
599
465
 
600
- ```vue fileName="pages/index.vue"
466
+ ```vue fileName="layouts/default.vue"
467
+ <script setup lang="ts">
468
+ import Links from "~/components/Links.vue";
469
+ import LocaleSwitcher from "~/components/LocaleSwitcher.vue";
470
+ </script>
471
+
601
472
  <template>
602
473
  <div>
603
- <LocalizedLink to="/about">
604
- {{ content.aboutLink }}
605
- </LocalizedLink>
606
- <LocalizedLink to="/contact">
607
- {{ content.contactLink }}
608
- </LocalizedLink>
474
+ <header>
475
+ <LocaleSwitcher />
476
+ </header>
477
+ <main>
478
+ <slot />
479
+ </main>
480
+
481
+ <Links href="/">Home</Links>
482
+ <Links href="/about">About</Links>
609
483
  </div>
610
484
  </template>
611
-
612
- <script setup lang="ts">
613
- import { useIntlayer } from "vue-intlayer";
614
- import LocalizedLink from "~/components/LocalizedLink.vue";
615
-
616
- const content = useIntlayer("home");
617
- </script>
618
485
  ```
619
486
 
487
+ > By using `NuxtLink` with localised paths, you ensure that:
488
+ >
489
+ > - Search engines can crawl and index all language versions of your pages
490
+ > - Users can share localised URLs directly
491
+ > - Browser history works correctly with locale-prefixed URLs
492
+
620
493
  ### (Optional) Step 9: Handle Metadata and SEO
621
494
 
622
- Nuxt provides excellent SEO capabilities. You can use Intlayer to manage localised metadata:
495
+ Nuxt provides excellent SEO capabilities via the `useHead` composable (auto-imported). You can use Intlayer to handle localised metadata using the `.raw` or `.value` accessor to get the primitive string value:
623
496
 
624
497
  ```vue fileName="pages/about.vue"
625
498
  <script setup lang="ts">
626
- import { useSeoMeta } from "nuxt/app";
627
- import { getIntlayer } from "intlayer";
628
- import { useLocale } from "vue-intlayer";
499
+ import { useIntlayer } from "vue-intlayer";
629
500
 
630
- const { locale } = useLocale();
631
- const content = getIntlayer("about-meta", locale.value);
501
+ // useHead is auto-imported in Nuxt
502
+ const content = useIntlayer("about-page");
632
503
 
633
- useSeoMeta({
634
- title: content.title,
635
- description: content.description,
504
+ useHead({
505
+ title: content.metaTitle.raw, // Use .raw for primitive string access
506
+ meta: [
507
+ {
508
+ name: "description",
509
+ content: content.metaDescription.raw, // Use .raw for primitive string access
510
+ },
511
+ ],
636
512
  });
637
513
  </script>
638
514
 
639
515
  <template>
640
- <div>
641
- <h1>{{ content.pageTitle }}</h1>
642
- <p>{{ content.pageContent }}</p>
643
- </div>
516
+ <h1><content.title /></h1>
644
517
  </template>
645
518
  ```
646
519
 
520
+ > Alternatively, you can use the `import { getIntlayer } from "intlayer"` function to get the content without Vue reactivity.
521
+
522
+ > **Accessing content values:**
523
+ >
524
+ > - Use `.raw` to get the primitive string value (non-reactive)
525
+ > - Use `.value` to get the reactive value
526
+ > - Use `<content.key />` component syntax for Visual Editor support
527
+
647
528
  Create the corresponding content declaration:
648
529
 
649
- ```ts fileName="pages/about-meta.content.ts"
530
+ ```ts fileName="pages/about-page.content.ts" contentDeclarationFormat="typescript"
650
531
  import { t, type Dictionary } from "intlayer";
651
- import type { useSeoMeta } from "nuxt/app";
652
532
 
653
- const aboutMetaContent = {
654
- key: "about-meta",
533
+ const aboutPageContent = {
534
+ key: "about-page",
655
535
  content: {
656
- title: t({
657
- "en-GB": "About Us - My Company",
536
+ metaTitle: t({
658
537
  en: "About Us - My Company",
659
538
  fr: "À Propos - Ma Société",
660
539
  es: "Acerca de Nosotros - Mi Empresa",
661
540
  }),
662
- description: t({
663
- "en-GB": "Learn more about our company and our mission",
541
+ metaDescription: t({
664
542
  en: "Learn more about our company and our mission",
665
543
  fr: "En savoir plus sur notre société et notre mission",
666
544
  es: "Conozca más sobre nuestra empresa y nuestra misión",
667
545
  }),
546
+ title: t({
547
+ en: "About Us",
548
+ fr: "À Propos",
549
+ es: "Acerca de Nosotros",
550
+ }),
668
551
  },
669
- } satisfies Dictionary<Parameters<typeof useSeoMeta>[0]>;
552
+ } satisfies Dictionary;
670
553
 
671
- export default aboutMetaContent;
554
+ export default aboutPageContent;
672
555
  ```
673
556
 
674
- ```typescript fileName="pages/about-meta.content.mjs" contentDeclarationFormat="esm"
557
+ ```javascript fileName="pages/about-page.content.mjs" contentDeclarationFormat="esm"
675
558
  import { t } from "intlayer";
676
559
 
677
560
  /** @type {import('intlayer').Dictionary} */
678
- const aboutMetaContent = {
679
- key: "about-meta",
561
+ const aboutPageContent = {
562
+ key: "about-page",
680
563
  content: {
681
- title: t({
682
- zh: "关于我们 - 我的公司",
683
- "en-GB": "About Us - My Company",
564
+ metaTitle: t({
684
565
  en: "About Us - My Company",
685
566
  fr: "À Propos - Ma Société",
686
567
  es: "Acerca de Nosotros - Mi Empresa",
687
568
  }),
688
- description: t({
689
- zh: "了解更多关于我们公司和我们的使命",
569
+ metaDescription: t({
690
570
  "en-GB": "Learn more about our company and our mission",
691
571
  en: "Learn more about our company and our mission",
692
572
  fr: "En savoir plus sur notre société et notre mission",
693
573
  es: "Conozca más sobre nuestra empresa y nuestra misión",
694
574
  }),
575
+ title: t({
576
+ "en-GB": "About Us",
577
+ en: "About Us",
578
+ fr: "À Propos",
579
+ es: "Acerca de Nosotros",
580
+ }),
695
581
  },
696
582
  };
697
583
 
698
- export default aboutMetaContent;
584
+ export default aboutPageContent;
699
585
  ```
700
586
 
701
- ```typescript fileName="pages/about-meta.content.js" contentDeclarationFormat="cjs"
587
+ ```javascript fileName="pages/about-page.content.cjs" contentDeclarationFormat="commonjs"
702
588
  const { t } = require("intlayer");
703
589
 
704
590
  /** @type {import('intlayer').Dictionary} */
705
- const aboutMetaContent = {
706
- key: "about-meta",
591
+ const aboutPageContent = {
592
+ key: "about-page",
707
593
  content: {
708
- title: t({
709
- zh: "关于我们 - 我的公司",
594
+ metaTitle: t({
710
595
  "en-GB": "About Us - My Company",
711
596
  en: "About Us - My Company",
712
597
  fr: "À Propos - Ma Société",
713
598
  es: "Acerca de Nosotros - Mi Empresa",
714
599
  }),
715
- description: t({
716
- zh: "了解更多关于我们公司和我们的使命",
600
+ metaDescription: t({
717
601
  "en-GB": "Learn more about our company and our mission",
718
602
  en: "Learn more about our company and our mission",
719
603
  fr: "En savoir plus sur notre société et notre mission",
720
604
  es: "Conozca más sobre nuestra empresa y nuestra misión",
721
605
  }),
606
+ title: t({
607
+ "en-GB": "About Us",
608
+ en: "About Us",
609
+ fr: "À Propos",
610
+ es: "Acerca de Nosotros",
611
+ }),
722
612
  },
723
613
  };
724
614
 
725
- module.exports = aboutMetaContent;
615
+ module.exports = aboutPageContent;
726
616
  ```
727
617
 
728
- ```json fileName="pages/about-meta.content.json" contentDeclarationFormat="json"
618
+ ```json fileName="pages/about-page.content.json" contentDeclarationFormat="json"
729
619
  {
730
- "key": "about-meta",
620
+ "$schema": "https://intlayer.org/schema.json",
621
+ "key": "about-page",
731
622
  "content": {
732
- "title": {
623
+ "metaTitle": {
733
624
  "nodeType": "translation",
734
- "translations": {
735
- "zh": "关于我们 - 我的公司",
625
+ "translation": {
736
626
  "en-GB": "About Us - My Company",
737
627
  "en": "About Us - My Company",
738
628
  "fr": "À Propos - Ma Société",
739
629
  "es": "Acerca de Nosotros - Mi Empresa"
740
630
  }
741
631
  },
742
- "description": {
632
+ "metaDescription": {
743
633
  "nodeType": "translation",
744
- "translations": {
745
- "zh": "了解更多关于我们公司和我们的使命",
634
+ "translation": {
746
635
  "en-GB": "Learn more about our company and our mission",
747
636
  "en": "Learn more about our company and our mission",
748
637
  "fr": "En savoir plus sur notre société et notre mission",
749
638
  "es": "Conozca más sobre nuestra empresa y nuestra misión"
750
639
  }
640
+ },
641
+ "title": {
642
+ "nodeType": "translation",
643
+ "translation": {
644
+ "en-GB": "About Us",
645
+ "en": "About Us",
646
+ "fr": "À Propos",
647
+ "es": "Acerca de Nosotros"
648
+ }
751
649
  }
752
650
  }
753
651
  }
754
652
  ```
755
653
 
756
- ### Configure TypeScript
757
-
758
- Intlayer uses module augmentation to gain the benefits of TypeScript and strengthen your codebase.
759
-
760
- ![Autocompletion](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)
761
-
762
- ![Translation error](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)
763
-
764
- Ensure your TypeScript configuration includes the autogenerated types.
765
-
766
- ```json5 fileName="tsconfig.json"
767
- {
768
- // ... Your existing TypeScript configurations
769
- "include": [
770
- // ... Your existing TypeScript configurations
771
- ".intlayer/**/*.ts", // Include the auto-generated types
772
- ],
773
- }
774
- ```
775
-
776
654
  ### Git Configuration
777
655
 
778
656
  It is recommended to ignore the files generated by Intlayer. This prevents you from committing them to your Git repository.
@@ -786,7 +664,7 @@ To do this, you can add the following instructions to your `.gitignore` file:
786
664
 
787
665
  ### VS Code Extension
788
666
 
789
- To enhance your development experience with Intlayer, you can install the official **Intlayer VS Code Extension**.
667
+ To improve your development experience with Intlayer, you can install the official **Intlayer VS Code Extension**.
790
668
 
791
669
  [Install from the VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
792
670
 
@@ -804,5 +682,3 @@ For more details on how to use the extension, refer to the [Intlayer VS Code Ext
804
682
  ### Go Further
805
683
 
806
684
  To go further, you can implement the [visual editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_visual_editor.md) or externalise your content using the [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_CMS.md).
807
-
808
- ---