@intlayer/docs 7.0.0-canary.2 → 7.0.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 (59) hide show
  1. package/dist/cjs/common.cjs.map +1 -1
  2. package/dist/esm/common.mjs.map +1 -1
  3. package/dist/types/common.d.ts +5 -0
  4. package/dist/types/common.d.ts.map +1 -1
  5. package/docs/ar/configuration.md +0 -24
  6. package/docs/ar/intlayer_with_nextjs_16.md +1652 -0
  7. package/docs/ar/releases/v7.md +485 -0
  8. package/docs/de/configuration.md +0 -24
  9. package/docs/de/intlayer_with_nextjs_16.md +1662 -0
  10. package/docs/de/releases/v7.md +502 -0
  11. package/docs/en/autoFill.md +3 -1
  12. package/docs/en/configuration.md +53 -58
  13. package/docs/en/intlayer_with_nextjs_15.md +5 -2
  14. package/docs/en/intlayer_with_nextjs_16.md +4 -4
  15. package/docs/en/releases/v7.md +142 -2
  16. package/docs/en-GB/configuration.md +9 -30
  17. package/docs/en-GB/intlayer_with_nextjs_16.md +1642 -0
  18. package/docs/en-GB/releases/v7.md +485 -0
  19. package/docs/es/configuration.md +0 -24
  20. package/docs/es/intlayer_with_nextjs_16.md +1670 -0
  21. package/docs/es/releases/v7.md +502 -0
  22. package/docs/fr/configuration.md +0 -24
  23. package/docs/fr/intlayer_with_nextjs_16.md +1692 -0
  24. package/docs/fr/releases/v7.md +503 -0
  25. package/docs/hi/configuration.md +0 -24
  26. package/docs/hi/intlayer_with_nextjs_16.md +1618 -0
  27. package/docs/hi/releases/v7.md +485 -0
  28. package/docs/id/intlayer_with_nextjs_16.md +1604 -0
  29. package/docs/id/releases/v7.md +502 -0
  30. package/docs/it/configuration.md +0 -24
  31. package/docs/it/intlayer_with_nextjs_16.md +1600 -0
  32. package/docs/it/releases/v7.md +504 -0
  33. package/docs/ja/configuration.md +0 -24
  34. package/docs/ja/intlayer_CMS.md +0 -9
  35. package/docs/ja/intlayer_with_nextjs_16.md +1788 -0
  36. package/docs/ja/releases/v7.md +503 -0
  37. package/docs/ko/configuration.md +0 -24
  38. package/docs/ko/intlayer_with_nextjs_16.md +1641 -0
  39. package/docs/ko/releases/v7.md +503 -0
  40. package/docs/pl/intlayer_with_nextjs_16.md +1645 -0
  41. package/docs/pl/releases/v7.md +485 -0
  42. package/docs/pt/configuration.md +0 -24
  43. package/docs/pt/intlayer_with_nextjs_16.md +1646 -0
  44. package/docs/pt/introduction.md +0 -15
  45. package/docs/pt/releases/v7.md +485 -0
  46. package/docs/ru/configuration.md +0 -24
  47. package/docs/ru/intlayer_with_nextjs_16.md +1610 -0
  48. package/docs/ru/releases/v7.md +485 -0
  49. package/docs/tr/configuration.md +0 -24
  50. package/docs/tr/intlayer_with_nextjs_16.md +1599 -0
  51. package/docs/tr/releases/v7.md +485 -0
  52. package/docs/vi/intlayer_with_nextjs_16.md +1597 -0
  53. package/docs/vi/releases/v7.md +485 -0
  54. package/docs/zh/configuration.md +0 -24
  55. package/docs/zh/intlayer_CMS.md +0 -23
  56. package/docs/zh/intlayer_with_nextjs_16.md +1628 -0
  57. package/docs/zh/releases/v7.md +486 -0
  58. package/package.json +14 -14
  59. package/src/common.ts +5 -0
@@ -0,0 +1,1670 @@
1
+ ---
2
+ createdAt: 2024-12-06
3
+ updatedAt: 2025-10-09
4
+ title: Cómo traducir tu aplicación Next.js 16 – Guía i18n 2025
5
+ description: Descubre cómo hacer que tu sitio web Next.js 16 sea multilingüe. Sigue la documentación para internacionalizar (i18n) y traducirlo.
6
+ keywords:
7
+ - Internacionalización
8
+ - Documentación
9
+ - Intlayer
10
+ - Next.js 16
11
+ - JavaScript
12
+ - React
13
+ slugs:
14
+ - doc
15
+ - environment
16
+ - nextjs
17
+ applicationTemplate: https://github.com/aymericzip/intlayer-next-16-template
18
+ youtubeVideo: https://www.youtube.com/watch?v=e_PPG7PTqGU
19
+ history:
20
+ - version: 7.0.0
21
+ date: 2025-06-29
22
+ changes: Historial inicial
23
+ ---
24
+
25
+ # Traduce tu sitio web Next.js 16 usando Intlayer | Internacionalización (i18n)
26
+
27
+ <iframe title="¿La mejor solución i18n para Next.js? Descubre 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/e_PPG7PTqGU?autoplay=0&amp;origin=http://intlayer.org&amp;controls=0&amp;rel=1"/>
28
+
29
+ Consulta la [Plantilla de Aplicación](https://github.com/aymericzip/intlayer-next-16-template) en GitHub.
30
+
31
+ ## ¿Qué es Intlayer?
32
+
33
+ **Intlayer** es una biblioteca innovadora y de código abierto para la internacionalización (i18n) diseñada para simplificar el soporte multilingüe en aplicaciones web modernas. Intlayer se integra perfectamente con el último framework **Next.js 16**, incluyendo su potente **App Router**. Está optimizado para trabajar con **Componentes del Servidor** para un renderizado eficiente y es totalmente compatible con [**Turbopack**](https://nextjs.org/docs/architecture/turbopack).
34
+
35
+ Con Intlayer, puedes:
36
+
37
+ - **Gestionar traducciones fácilmente** usando diccionarios declarativos a nivel de componente.
38
+ - **Localizar dinámicamente metadatos**, rutas y contenido.
39
+ - **Acceder a las traducciones tanto en componentes del lado del cliente como del servidor**.
40
+ - **Garantizar soporte para TypeScript** con tipos autogenerados, mejorando la autocompletación y la detección de errores.
41
+ - **Benefíciate de funciones avanzadas**, como la detección y el cambio dinámico de locales.
42
+
43
+ > Intlayer es compatible con Next.js 12, 13, 14 y 16. Si usas Next.js Page Router, puedes consultar esta [guía](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_with_nextjs_page_router.md). Para Next.js 12, 13, 14 con App Router, consulta esta [guía](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_with_nextjs_14.md).
44
+
45
+ ---
46
+
47
+ ## Guía paso a paso para configurar Intlayer en una aplicación Next.js
48
+
49
+ ### Paso 1: Instalar dependencias
50
+
51
+ Instala los paquetes necesarios usando npm:
52
+
53
+ ```bash packageManager="npm"
54
+ npm install intlayer next-intlayer
55
+ ```
56
+
57
+ ```bash packageManager="pnpm"
58
+ pnpm add intlayer next-intlayer
59
+ ```
60
+
61
+ ```bash packageManager="yarn"
62
+ yarn add intlayer next-intlayer
63
+ ```
64
+
65
+ - **intlayer**
66
+
67
+ El paquete principal que proporciona herramientas de internacionalización para la gestión de configuración, traducción, [declaración de contenido](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/content_file.md), transpilación y [comandos CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_cli.md).
68
+
69
+ - **next-intlayer**
70
+
71
+ El paquete que integra Intlayer con Next.js. Proporciona proveedores de contexto y hooks para la internacionalización en Next.js. Además, incluye el plugin de Next.js para integrar Intlayer con [Webpack](https://webpack.js.org/) o [Turbopack](https://nextjs.org/docs/app/api-reference/turbopack), así como un proxy para detectar la configuración regional preferida del usuario, gestionar cookies y manejar la redirección de URL.
72
+
73
+ ### Paso 2: Configura tu proyecto
74
+
75
+ Crea un archivo de configuración para configurar los idiomas de tu aplicación:
76
+
77
+ ```typescript fileName="intlayer.config.ts" codeFormat="typescript"
78
+ import { Locales, type IntlayerConfig } from "intlayer";
79
+
80
+ const config: IntlayerConfig = {
81
+ internationalization: {
82
+ locales: [
83
+ Locales.ENGLISH,
84
+ Locales.FRENCH,
85
+ Locales.SPANISH,
86
+ // Tus otros locales
87
+ ],
88
+ defaultLocale: Locales.ENGLISH,
89
+ },
90
+ };
91
+
92
+ export default config;
93
+ ```
94
+
95
+ ```javascript fileName="intlayer.config.mjs" codeFormat="esm"
96
+ import { Locales } from "intlayer";
97
+
98
+ /** @type {import('intlayer').IntlayerConfig} */
99
+ const config = {
100
+ internationalization: {
101
+ locales: [
102
+ Locales.ENGLISH,
103
+ Locales.FRENCH,
104
+ Locales.SPANISH,
105
+ // Tus otros locales
106
+ ],
107
+ defaultLocale: Locales.ENGLISH,
108
+ },
109
+ };
110
+
111
+ export default config;
112
+ ```
113
+
114
+ ```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
115
+ const { Locales } = require("intlayer");
116
+
117
+ /** @type {import('intlayer').IntlayerConfig} */
118
+ const config = {
119
+ internationalization: {
120
+ locales: [
121
+ Locales.ENGLISH,
122
+ Locales.FRENCH,
123
+ Locales.SPANISH,
124
+ // Tus otros locales
125
+ ],
126
+ defaultLocale: Locales.ENGLISH,
127
+ },
128
+ };
129
+
130
+ module.exports = config;
131
+ ```
132
+
133
+ > A través de este archivo de configuración, puedes configurar URLs localizadas, redirección de proxy, nombres de cookies, la ubicación y extensión de tus declaraciones de contenido, desactivar los registros de Intlayer en la consola, y más. Para una lista completa de los parámetros disponibles, consulta la [documentación de configuración](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/configuration.md).
134
+
135
+ ### Paso 3: Integra Intlayer en tu configuración de Next.js
136
+
137
+ Configura tu entorno Next.js para usar Intlayer:
138
+
139
+ ```typescript fileName="next.config.ts" codeFormat="typescript"
140
+ import type { NextConfig } from "next";
141
+ import { withIntlayer } from "next-intlayer/server";
142
+
143
+ const nextConfig: NextConfig = {
144
+ /* opciones de configuración aquí */
145
+ };
146
+
147
+ export default withIntlayer(nextConfig);
148
+ ```
149
+
150
+ ```typescript fileName="next.config.mjs" codeFormat="esm"
151
+ import { withIntlayer } from "next-intlayer/server";
152
+
153
+ /** @type {import('next').NextConfig} */
154
+ const nextConfig = {
155
+ /* opciones de configuración aquí */
156
+ };
157
+
158
+ export default withIntlayer(nextConfig);
159
+ ```
160
+
161
+ ```typescript fileName="next.config.cjs" codeFormat="commonjs"
162
+ const { withIntlayer } = require("next-intlayer/server");
163
+
164
+ /** @type {import('next').NextConfig} */
165
+ const nextConfig = {
166
+ /* opciones de configuración aquí */
167
+ };
168
+
169
+ module.exports = withIntlayer(nextConfig);
170
+ ```
171
+
172
+ > El plugin `withIntlayer()` de Next.js se utiliza para integrar Intlayer con Next.js. Garantiza la construcción de archivos de declaración de contenido y los supervisa en modo de desarrollo. Define variables de entorno de Intlayer dentro de los entornos de [Webpack](https://webpack.js.org/) o [Turbopack](https://nextjs.org/docs/app/api-reference/turbopack). Además, proporciona alias para optimizar el rendimiento y asegura la compatibilidad con componentes del servidor.
173
+
174
+ > La función `withIntlayer()` es una función que devuelve una promesa. Permite preparar los diccionarios de Intlayer antes de que comience la compilación. Si deseas usarla con otros plugins, puedes usar `await`. Ejemplo:
175
+ >
176
+ > ```tsx
177
+ > const nextConfig = await withIntlayer(nextConfig);
178
+ > const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);
179
+ >
180
+ > export default nextConfigWithOtherPlugins;
181
+ > ```
182
+ >
183
+ > Si deseas usarlo de manera sincrónica, puedes usar la función `withIntlayerSync()`. Ejemplo:
184
+ >
185
+ > ```tsx
186
+ > const nextConfig = withIntlayerSync(nextConfig);
187
+ > const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);
188
+ >
189
+ > export default nextConfigWithOtherPlugins;
190
+ > ```
191
+
192
+ ### Paso 4: Definir Rutas Dinámicas de Localización
193
+
194
+ Elimina todo lo que hay en `RootLayout` y reemplázalo con el siguiente código:
195
+
196
+ ```tsx {3} fileName="src/app/layout.tsx" codeFormat="typescript"
197
+ import type { PropsWithChildren, FC } from "react";
198
+ import "./globals.css";
199
+
200
+ const RootLayout: FC<PropsWithChildren> = ({ children }) => (
201
+ // Aún puedes envolver los children con otros proveedores, como `next-themes`, `react-query`, `framer-motion`, etc.
202
+ <>{children}</>
203
+ );
204
+
205
+ export default RootLayout;
206
+ ```
207
+
208
+ ```jsx {3} fileName="src/app/layout.mjx" codeFormat="esm"
209
+ import "./globals.css";
210
+
211
+ const RootLayout = ({ children }) => (
212
+ // Aún puedes envolver los children con otros proveedores, como `next-themes`, `react-query`, `framer-motion`, etc.
213
+ <>{children}</>
214
+ );
215
+
216
+ export default RootLayout;
217
+ ```
218
+
219
+ ```jsx {1,8} fileName="src/app/layout.csx" codeFormat="commonjs"
220
+ require("./globals.css");
221
+
222
+ const RootLayout = ({ children }) => (
223
+ // Aún puedes envolver los children con otros proveedores, como `next-themes`, `react-query`, `framer-motion`, etc.
224
+ <>{children}</>
225
+ );
226
+
227
+ module.exports = {
228
+ default: RootLayout,
229
+ generateStaticParams,
230
+ };
231
+ ```
232
+
233
+ > Mantener el componente `RootLayout` vacío permite establecer los atributos [`lang`](https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/lang) y [`dir`](https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/dir) en la etiqueta `<html>`.
234
+
235
+ Para implementar el enrutamiento dinámico, proporciona la ruta para la localización añadiendo un nuevo layout en tu directorio `[locale]`:
236
+
237
+ ```tsx fileName="src/app/[locale]/layout.tsx" codeFormat="typescript"
238
+ import type { NextLayoutIntlayer } from "next-intlayer";
239
+ import { Inter } from "next/font/google";
240
+ import { getHTMLTextDir } from "intlayer";
241
+
242
+ const inter = Inter({ subsets: ["latin"] });
243
+
244
+ const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
245
+ const { locale } = await params;
246
+ return (
247
+ <html lang={locale} dir={getHTMLTextDir(locale)}>
248
+ <body className={inter.className}>{children}</body>
249
+ </html>
250
+ );
251
+ };
252
+
253
+ export default LocaleLayout;
254
+ ```
255
+
256
+ ```jsx fileName="src/app/[locale]/layout.mjx" codeFormat="esm"
257
+ import { getHTMLTextDir } from "intlayer";
258
+
259
+ const inter = Inter({ subsets: ["latin"] });
260
+
261
+ const LocaleLayout = async ({ children, params: { locale } }) => {
262
+ const { locale } = await params;
263
+ return (
264
+ <html lang={locale} dir={getHTMLTextDir(locale)}>
265
+ <body className={inter.className}>{children}</body>
266
+ </html>
267
+ );
268
+ };
269
+
270
+ export default LocaleLayout;
271
+ ```
272
+
273
+ ```jsx fileName="src/app/[locale]/layout.csx" codeFormat="commonjs"
274
+ const { Inter } = require("next/font/google");
275
+ const { getHTMLTextDir } = require("intlayer");
276
+
277
+ const inter = Inter({ subsets: ["latin"] });
278
+
279
+ const LocaleLayout = async ({ children, params: { locale } }) => {
280
+ const { locale } = await params;
281
+ return (
282
+ <html lang={locale} dir={getHTMLTextDir(locale)}>
283
+ <body className={inter.className}>{children}</body>
284
+ </html>
285
+ );
286
+ };
287
+
288
+ module.exports = LocaleLayout;
289
+ ```
290
+
291
+ > El segmento de ruta `[locale]` se utiliza para definir la configuración regional. Ejemplo: `/en-US/about` se referirá a `en-US` y `/fr/about` a `fr`.
292
+
293
+ > En esta etapa, encontrará el error: `Error: Missing <html> and <body> tags in the root layout.`. Esto es esperado porque el archivo `/app/page.tsx` ya no se utiliza y puede ser eliminado. En su lugar, el segmento de ruta `[locale]` activará la página `/app/[locale]/page.tsx`. En consecuencia, las páginas serán accesibles a través de rutas como `/en`, `/fr`, `/es` en su navegador. Para establecer la configuración regional predeterminada como la página raíz, consulte la configuración del `proxy` en el paso 7.
294
+
295
+ Luego, implemente la función `generateStaticParams` en el Layout de su aplicación.
296
+
297
+ ```tsx {1} fileName="src/app/[locale]/layout.tsx" codeFormat="typescript"
298
+ export { generateStaticParams } from "next-intlayer"; // Línea para insertar
299
+
300
+ const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
301
+ /*... Resto del código*/
302
+ };
303
+
304
+ export default LocaleLayout;
305
+ ```
306
+
307
+ ```jsx {1} fileName="src/app/[locale]/layout.mjx" codeFormat="esm"
308
+ export { generateStaticParams } from "next-intlayer"; // Línea para insertar
309
+
310
+ const LocaleLayout = async ({ children, params: { locale } }) => {
311
+ /*... Resto del código*/
312
+ };
313
+
314
+ // ... Resto del código
315
+ ```
316
+
317
+ ```jsx {1,7} fileName="src/app/[locale]/layout.csx" codeFormat="commonjs"
318
+ const { generateStaticParams } = require("next-intlayer"); // Línea para insertar
319
+
320
+ const LocaleLayout = async ({ children, params: { locale } }) => {
321
+ /*... Resto del código*/
322
+ };
323
+
324
+ module.exports = { default: LocaleLayout, generateStaticParams };
325
+ ```
326
+
327
+ > `generateStaticParams` asegura que tu aplicación preconstruya las páginas necesarias para todos los locales, reduciendo el cálculo en tiempo de ejecución y mejorando la experiencia del usuario. Para más detalles, consulta la [documentación de Next.js sobre generateStaticParams](https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering#generate-static-params).
328
+
329
+ > Intlayer funciona con `export const dynamic = 'force-static';` para asegurar que las páginas se preconstruyan para todos los locales.
330
+
331
+ ### Paso 5: Declara Tu Contenido
332
+
333
+ Crea y gestiona tus declaraciones de contenido para almacenar traducciones:
334
+
335
+ ```tsx fileName="src/app/[locale]/page.content.ts" contentDeclarationFormat="typescript"
336
+ import { t, type Dictionary } from "intlayer";
337
+
338
+ const pageContent = {
339
+ key: "page",
340
+ content: {
341
+ getStarted: {
342
+ main: t({
343
+ en: "Get started by editing",
344
+ fr: "Commencez par éditer",
345
+ es: "Comience por editar",
346
+ }),
347
+ pageLink: "src/app/page.tsx",
348
+ },
349
+ },
350
+ } satisfies Dictionary;
351
+
352
+ export default pageContent;
353
+ ```
354
+
355
+ ```javascript fileName="src/app/[locale]/page.content.mjs" contentDeclarationFormat="esm"
356
+ import { t } from "intlayer";
357
+
358
+ /** @type {import('intlayer').Dictionary} */
359
+ const pageContent = {
360
+ key: "page",
361
+ content: {
362
+ getStarted: {
363
+ main: t({
364
+ en: "Get started by editing",
365
+ fr: "Commencez par éditer",
366
+ es: "Comience por editar",
367
+ }),
368
+ pageLink: "src/app/page.tsx",
369
+ },
370
+ },
371
+ };
372
+
373
+ export default pageContent;
374
+ ```
375
+
376
+ ```javascript fileName="src/app/[locale]/page.content.cjs" contentDeclarationFormat="commonjs"
377
+ const { t } = require("intlayer");
378
+
379
+ /** @type {import('intlayer').Dictionary} */
380
+ const pageContent = {
381
+ key: "page",
382
+ content: {
383
+ getStarted: {
384
+ main: t({
385
+ en: "Get started by editing",
386
+ fr: "Commencez par éditer",
387
+ es: "Comience por editar",
388
+ }),
389
+ pageLink: "src/app/page.tsx",
390
+ },
391
+ },
392
+ };
393
+
394
+ module.exports = pageContent;
395
+ ```
396
+
397
+ ```json fileName="src/app/[locale]/page.content.json" contentDeclarationFormat="json"
398
+ {
399
+ "$schema": "https://intlayer.org/schema.json",
400
+ "key": "page",
401
+ "content": {
402
+ "getStarted": {
403
+ "nodeType": "translation",
404
+ "translation": {
405
+ "en": "Get started by editing",
406
+ "fr": "Commencez par éditer",
407
+ "es": "Comience por editar"
408
+ }
409
+ },
410
+ "pageLink": "src/app/page.tsx"
411
+ }
412
+ }
413
+ ```
414
+
415
+ > Tus declaraciones de contenido pueden definirse en cualquier parte de tu aplicación siempre que estén incluidas en el directorio `contentDir` (por defecto, `./src`). Y coincidan con la extensión de archivo de declaración de contenido (por defecto, `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
416
+
417
+ > Para más detalles, consulta la [documentación de declaración de contenido](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/content_file.md).
418
+
419
+ ### Paso 6: Utiliza el contenido en tu código
420
+
421
+ Accede a tus diccionarios de contenido en toda tu aplicación:
422
+
423
+ ```tsx fileName="src/app/[locale]/page.tsx" codeFormat="typescript"
424
+ import type { FC } from "react";
425
+ import { ClientComponentExample } from "@components/ClientComponentExample";
426
+ import { ServerComponentExample } from "@components/ServerComponentExample";
427
+ import { type NextPageIntlayer, IntlayerClientProvider } from "next-intlayer";
428
+ import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
429
+
430
+ const PageContent: FC = () => {
431
+ const content = useIntlayer("page");
432
+
433
+ return (
434
+ <>
435
+ <p>{content.getStarted.main}</p>
436
+ <code>{content.getStarted.pageLink}</code>
437
+ </>
438
+ );
439
+ };
440
+
441
+ const Page: NextPageIntlayer = async ({ params }) => {
442
+ const { locale } = await params;
443
+
444
+ return (
445
+ <IntlayerServerProvider locale={locale}>
446
+ <PageContent />
447
+ <ServerComponentExample />
448
+
449
+ <IntlayerClientProvider locale={locale}>
450
+ <ClientComponentExample />
451
+ </IntlayerClientProvider>
452
+ </IntlayerServerProvider>
453
+ );
454
+ };
455
+
456
+ export default Page;
457
+ ```
458
+
459
+ ```jsx fileName="src/app/[locale]/page.mjx" codeFormat="esm"
460
+ import { ClientComponentExample } from "@components/ClientComponentExample";
461
+ import { ServerComponentExample } from "@components/ServerComponentExample";
462
+ import { IntlayerClientProvider } from "next-intlayer";
463
+ import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
464
+
465
+ const PageContent = () => {
466
+ const content = useIntlayer("page");
467
+
468
+ return (
469
+ <>
470
+ <p>{content.getStarted.main}</p>
471
+ <code>{content.getStarted.pageLink}</code>
472
+ </>
473
+ );
474
+ };
475
+
476
+ const Page = async ({ params }) => {
477
+ const { locale } = await params;
478
+
479
+ return (
480
+ <IntlayerServerProvider locale={locale}>
481
+ <PageContent />
482
+ <ServerComponentExample />
483
+
484
+ <IntlayerClientProvider locale={locale}>
485
+ <ClientComponentExample />
486
+ </IntlayerClientProvider>
487
+ </IntlayerServerProvider>
488
+ );
489
+ };
490
+
491
+ export default Page;
492
+ ```
493
+
494
+ ```jsx fileName="src/app/[locale]/page.csx" codeFormat="commonjs"
495
+ import { ClientComponentExample } from "@components/ClientComponentExample";
496
+ import { ServerComponentExample } from "@components/ServerComponentExample";
497
+ import { IntlayerClientProvider } from "next-intlayer";
498
+ import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
499
+
500
+ const PageContent = () => {
501
+ const content = useIntlayer("page");
502
+
503
+ return (
504
+ <>
505
+ <p>{content.getStarted.main}</p>
506
+ <code>{content.getStarted.pageLink}</code>
507
+ </>
508
+ );
509
+ };
510
+
511
+ const Page = async ({ params }) => {
512
+ const { locale } = await params;
513
+
514
+ return (
515
+ <IntlayerServerProvider locale={locale}>
516
+ <PageContent />
517
+ <ServerComponentExample />
518
+
519
+ <IntlayerClientProvider locale={locale}>
520
+ <ClientComponentExample />
521
+ </IntlayerClientProvider>
522
+ </IntlayerServerProvider>
523
+ );
524
+ };
525
+ ```
526
+
527
+ - **`IntlayerClientProvider`** se utiliza para proporcionar la configuración regional a los componentes del lado del cliente. Puede colocarse en cualquier componente padre, incluido el layout. Sin embargo, se recomienda colocarlo en un layout porque Next.js comparte el código del layout entre páginas, lo que lo hace más eficiente. Al usar `IntlayerClientProvider` en el layout, evitas reinicializarlo para cada página, mejorando el rendimiento y manteniendo un contexto de localización consistente en toda tu aplicación.
528
+ - **`IntlayerServerProvider`** se utiliza para proporcionar la configuración regional a los componentes hijos del servidor. No puede establecerse en el layout.
529
+
530
+ > El layout y la página no pueden compartir un contexto común del servidor porque el sistema de contexto del servidor se basa en un almacén de datos por solicitud (a través del mecanismo [React's cache](https://react.dev/reference/react/cache)), lo que provoca que cada "contexto" se recree para diferentes segmentos de la aplicación. Colocar el proveedor en un layout compartido rompería este aislamiento, impidiendo la correcta propagación de los valores del contexto del servidor a tus componentes del servidor.
531
+
532
+ > El layout y la página no pueden compartir un contexto de servidor común porque el sistema de contexto de servidor se basa en un almacén de datos por solicitud (a través del mecanismo de [caché de React](https://react.dev/reference/react/cache)), lo que provoca que cada "contexto" se vuelva a crear para diferentes segmentos de la aplicación. Colocar el proveedor en un layout compartido rompería este aislamiento, impidiendo la correcta propagación de los valores del contexto del servidor a tus componentes del servidor.
533
+
534
+ ```tsx {4,7} fileName="src/components/ClientComponentExample.tsx" codeFormat="typescript"
535
+ "use client";
536
+
537
+ import type { FC } from "react";
538
+ import { useIntlayer } from "next-intlayer";
539
+
540
+ export const ClientComponentExample: FC = () => {
541
+ const content = useIntlayer("client-component-example"); // Crear declaración de contenido relacionada
542
+
543
+ return (
544
+ <div>
545
+ <h2>{content.title}</h2>
546
+ <p>{content.content}</p>
547
+ </div>
548
+ );
549
+ };
550
+ ```
551
+
552
+ ```jsx {3,6} fileName="src/components/ClientComponentExample.mjx" codeFormat="esm"
553
+ "use client";
554
+
555
+ import { useIntlayer } from "next-intlayer";
556
+
557
+ const ClientComponentExample = () => {
558
+ const content = useIntlayer("client-component-example"); // Crear declaración de contenido relacionado
559
+
560
+ return (
561
+ <div>
562
+ <h2>{content.title}</h2>
563
+ <p>{content.content}</p>
564
+ </div>
565
+ );
566
+ };
567
+ ```
568
+
569
+ ```jsx {3,6} fileName="src/components/ClientComponentExample.csx" codeFormat="commonjs"
570
+ "use client";
571
+
572
+ const { useIntlayer } = require("next-intlayer");
573
+
574
+ const ClientComponentExample = () => {
575
+ const content = useIntlayer("client-component-example"); // Crear declaración de contenido relacionado
576
+
577
+ return (
578
+ <div>
579
+ <h2>{content.title}</h2>
580
+ <p>{content.content}</p>
581
+ </div>
582
+ );
583
+ };
584
+ ```
585
+
586
+ ```tsx {2} fileName="src/components/ServerComponentExample.tsx" codeFormat="typescript"
587
+ import type { FC } from "react";
588
+ import { useIntlayer } from "next-intlayer/server";
589
+
590
+ export const ServerComponentExample: FC = () => {
591
+ const content = useIntlayer("server-component-example"); // Crear declaración de contenido relacionado
592
+
593
+ return (
594
+ <div>
595
+ <h2>{content.title}</h2>
596
+ <p>{content.content}</p>
597
+ </div>
598
+ );
599
+ };
600
+ ```
601
+
602
+ ```jsx {1} fileName="src/components/ServerComponentExample.mjx" codeFormat="esm"
603
+ import { useIntlayer } from "next-intlayer/server";
604
+
605
+ const ServerComponentExample = () => {
606
+ const content = useIntlayer("server-component-example"); // Crear declaración de contenido relacionado
607
+
608
+ return (
609
+ <div>
610
+ <h2>{content.title}</h2>
611
+ <p>{content.content}</p>
612
+ </div>
613
+ );
614
+ };
615
+ ```
616
+
617
+ ```jsx {1} fileName="src/components/ServerComponentExample.csx" codeFormat="commonjs"
618
+ const { useIntlayer } = require("next-intlayer/server");
619
+
620
+ const ServerComponentExample = () => {
621
+ const content = useIntlayer("server-component-example"); // Crear declaración de contenido relacionada
622
+
623
+ return (
624
+ <div>
625
+ <h2>{content.title}</h2>
626
+ <p>{content.content}</p>
627
+ </div>
628
+ );
629
+ };
630
+ ```
631
+
632
+ > Si quieres usar tu contenido en un atributo de tipo `string`, como `alt`, `title`, `href`, `aria-label`, etc., debes llamar al valor de la función, así:
633
+
634
+ > ```jsx
635
+ > <img src={content.image.src.value} alt={content.image.value} />
636
+ > ```
637
+
638
+ > Para aprender más sobre el hook `useIntlayer`, consulta la [documentación](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/next-intlayer/useIntlayer.md).
639
+
640
+ ### (Opcional) Paso 7: Configurar Proxy para la Detección de Idioma
641
+
642
+ Configura un proxy para detectar el idioma preferido del usuario:
643
+
644
+ ```typescript fileName="src/proxy.ts" codeFormat="typescript"
645
+ export { intlayerProxy as proxy } from "next-intlayer/proxy";
646
+
647
+ export const config = {
648
+ matcher:
649
+ "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
650
+ };
651
+ ```
652
+
653
+ ```javascript fileName="src/proxy.mjs" codeFormat="esm"
654
+ export { intlayerProxy as proxy } from "next-intlayer/proxy";
655
+
656
+ export const config = {
657
+ matcher:
658
+ "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
659
+ };
660
+ ```
661
+
662
+ ```javascript fileName="src/proxy.cjs" codeFormat="commonjs"
663
+ const { intlayerProxy } = require("next-intlayer/proxy");
664
+
665
+ const config = {
666
+ matcher:
667
+ "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
668
+ };
669
+
670
+ module.exports = { proxy: intlayerProxy, config };
671
+ ```
672
+
673
+ > El `intlayerProxy` se utiliza para detectar la configuración regional preferida del usuario y redirigirlo a la URL apropiada según lo especificado en la [configuración](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/configuration.md). Además, permite guardar la configuración regional preferida del usuario en una cookie.
674
+
675
+ > Si necesitas encadenar varios proxies juntos (por ejemplo, `intlayerProxy` con autenticación o proxies personalizados), Intlayer ahora proporciona una ayuda llamada `multipleProxies`.
676
+
677
+ ```ts
678
+ import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";
679
+ import { customProxy } from "@utils/customProxy";
680
+
681
+ export const proxy = multipleProxies([intlayerProxy, customProxy]);
682
+ ```
683
+
684
+ ### (Opcional) Paso 8: Internacionalización de tus metadatos
685
+
686
+ En caso de que desees internacionalizar tus metadatos, como el título de tu página, puedes usar la función `generateMetadata` proporcionada por Next.js. Dentro, puedes obtener el contenido de la función `getIntlayer` para traducir tus metadatos.
687
+
688
+ ```typescript fileName="src/app/[locale]/metadata.content.ts" contentDeclarationFormat="typescript"
689
+ import { type Dictionary, t } from "intlayer";
690
+ import { Metadata } from "next";
691
+
692
+ const metadataContent = {
693
+ key: "page-metadata",
694
+ content: {
695
+ title: t({
696
+ en: "Create Next App",
697
+ fr: "Créer une application Next.js",
698
+ es: "Crear una aplicación Next.js",
699
+ }),
700
+ description: t({
701
+ en: "Generated by create next app",
702
+ fr: "Généré par create next app",
703
+ es: "Generado por create next app",
704
+ }),
705
+ },
706
+ } satisfies Dictionary<Metadata>;
707
+
708
+ export default metadataContent;
709
+ ```
710
+
711
+ ```javascript fileName="src/app/[locale]/metadata.content.mjs" contentDeclarationFormat="esm"
712
+ import { t } from "intlayer";
713
+
714
+ /** @type {import('intlayer').Dictionary<import('next').Metadata>} */
715
+ const metadataContent = {
716
+ key: "page-metadata",
717
+ content: {
718
+ title: t({
719
+ en: "Create Next App",
720
+ fr: "Créer une application Next.js",
721
+ es: "Crear una aplicación Next.js",
722
+ }),
723
+ description: t({
724
+ en: "Generated by create next app",
725
+ fr: "Généré par create next app",
726
+ es: "Generado por create next app",
727
+ }),
728
+ },
729
+ };
730
+
731
+ export default metadataContent;
732
+ ```
733
+
734
+ ```javascript fileName="src/app/[locale]/metadata.content.cjs" contentDeclarationFormat="commonjs"
735
+ const { t } = require("intlayer");
736
+
737
+ /** @type {import('intlayer').Dictionary<import('next').Metadata>} */
738
+ const metadataContent = {
739
+ key: "page-metadata",
740
+ content: {
741
+ title: t({
742
+ en: "Create Next App",
743
+ fr: "Créer une application Next.js",
744
+ es: "Crear una aplicación Next.js",
745
+ }),
746
+ description: t({
747
+ en: "Generated by create next app",
748
+ fr: "Généré par create next app",
749
+ es: "Generado por create next app",
750
+ }),
751
+ },
752
+ };
753
+
754
+ module.exports = metadataContent;
755
+ fr: "Généré par create next app",
756
+ es: "Generado por create next app",
757
+ }),
758
+ },
759
+ };
760
+
761
+ export default metadataContent;
762
+ ```
763
+
764
+ ```javascript fileName="src/app/[locale]/metadata.content.cjs" contentDeclarationFormat="commonjs"
765
+ const { t } = require("intlayer");
766
+
767
+ /** @type {import('intlayer').Dictionary<import('next').Metadata>} */
768
+ const metadataContent = {
769
+ key: "page-metadata",
770
+ content: {
771
+ title: t({
772
+ en: "Create Next App",
773
+ fr: "Créer une application Next.js",
774
+ es: "Crear una aplicación Next.js",
775
+ }),
776
+ description: t({
777
+ en: "Generated by create next app",
778
+ fr: "Généré par create next app",
779
+ es: "Generado por create next app",
780
+ }),
781
+ },
782
+ };
783
+
784
+ module.exports = metadataContent;
785
+ ```
786
+
787
+ ```json fileName="src/app/[locale]/metadata.content.json" contentDeclarationFormat="json"
788
+ {
789
+ "key": "page-metadata",
790
+ "content": {
791
+ "title": {
792
+ "nodeType": "translation",
793
+ "translation": {
794
+ "en": "Preact logo",
795
+ "fr": "Logo Preact",
796
+ "es": "Logo Preact"
797
+ }
798
+ },
799
+ "description": {
800
+ "nodeType": "translation",
801
+ "translation": {
802
+ "en": "Generated by create next app",
803
+ "fr": "Généré par create next app",
804
+ "es": "Generado por create next app"
805
+ }
806
+ }
807
+ }
808
+ }
809
+ ```
810
+
811
+ ````typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat="typescript"
812
+ import { getIntlayer, getMultilingualUrls } from "intlayer";
813
+ import type { Metadata } from "next";
814
+ import type { LocalPromiseParams } from "next-intlayer";
815
+
816
+ export const generateMetadata = async ({
817
+ params,
818
+ }: LocalPromiseParams): Promise<Metadata> => {
819
+ const { locale } = await params;
820
+
821
+ const metadata = getIntlayer("page-metadata", locale);
822
+
823
+ /**
824
+ * Genera un objeto que contiene todas las URLs para cada idioma.
825
+ *
826
+ * Ejemplo:
827
+ * ```ts
828
+ * getMultilingualUrls('/about');
829
+ *
830
+ * // Devuelve
831
+ * // {
832
+ * // en: '/about',
833
+ * // fr: '/fr/about',
834
+ * // es: '/es/about',
835
+ * // }
836
+ * ```
837
+ */
838
+ const multilingualUrls = getMultilingualUrls("/");
839
+
840
+ return {
841
+ ...metadata,
842
+ alternates: {
843
+ canonical: multilingualUrls[locale as keyof typeof multilingualUrls],
844
+ languages: { ...multilingualUrls, "x-default": "/" },
845
+ },
846
+ openGraph: {
847
+ url: multilingualUrls[locale],
848
+ },
849
+ };
850
+ };
851
+
852
+ // ... Resto del código
853
+ ````
854
+
855
+ ````javascript fileName="src/app/[locale]/layout.mjs or src/app/[locale]/page.mjs" codeFormat="esm"
856
+ import { getIntlayer, getMultilingualUrls } from "intlayer";
857
+
858
+ export const generateMetadata = async ({ params }) => {
859
+ const { locale } = await params;
860
+
861
+ const metadata = getIntlayer("page-metadata", locale);
862
+
863
+ /**
864
+ * Genera un objeto que contiene todas las URLs para cada localización.
865
+ *
866
+ * Ejemplo:
867
+ * ```ts
868
+ * getMultilingualUrls('/about');
869
+ *
870
+ * // Devuelve
871
+ * // {
872
+ * // en: '/about',
873
+ * // fr: '/fr/about',
874
+ * // es: '/es/about'
875
+ * // }
876
+ * ```
877
+ */
878
+ const multilingualUrls = getMultilingualUrls("/");
879
+
880
+ return {
881
+ ...metadata,
882
+ alternates: {
883
+ canonical: multilingualUrls[locale],
884
+ languages: { ...multilingualUrls, "x-default": "/" },
885
+ },
886
+ openGraph: {
887
+ url: multilingualUrls[locale],
888
+ },
889
+ };
890
+ };
891
+
892
+ // ... Resto del código
893
+ ````
894
+
895
+ ````javascript fileName="src/app/[locale]/layout.cjs or src/app/[locale]/page.cjs" codeFormat="commonjs"
896
+ const { getIntlayer, getMultilingualUrls } = require("intlayer");
897
+
898
+ const generateMetadata = async ({ params }) => {
899
+ const { locale } = await params;
900
+
901
+ const metadata = getIntlayer("page-metadata", locale);
902
+
903
+ /**
904
+ * Genera un objeto que contiene todas las URLs para cada localización.
905
+ *
906
+ * Ejemplo:
907
+ * ```ts
908
+ * getMultilingualUrls('/about');
909
+ *
910
+ * // Devuelve
911
+ * // {
912
+ * // en: '/about',
913
+ * // fr: '/fr/about',
914
+ * // es: '/es/about'
915
+ * // }
916
+ * ```
917
+ */
918
+ const multilingualUrls = getMultilingualUrls("/");
919
+
920
+ return {
921
+ ...metadata,
922
+ alternates: {
923
+ canonical: multilingualUrls[locale],
924
+ languages: { ...multilingualUrls, "x-default": "/" },
925
+ },
926
+ openGraph: {
927
+ url: multilingualUrls[locale],
928
+ },
929
+ };
930
+ };
931
+
932
+ module.exports = { generateMetadata };
933
+
934
+ // ... Resto del código
935
+ ````
936
+
937
+ > Tenga en cuenta que la función `getIntlayer` importada desde `next-intlayer` devuelve su contenido envuelto en un `IntlayerNode`, lo que permite la integración con el editor visual. En cambio, la función `getIntlayer` importada desde `intlayer` devuelve su contenido directamente sin propiedades adicionales.
938
+
939
+ Alternativamente, puedes usar la función `getTranslation` para declarar tus metadatos. Sin embargo, se recomienda usar archivos de declaración de contenido para automatizar la traducción de tus metadatos y externalizar el contenido en algún momento.
940
+
941
+ ````typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat="typescript"
942
+ import {
943
+ type IConfigLocales,
944
+ getTranslation,
945
+ getMultilingualUrls,
946
+ } from "intlayer";
947
+ import type { Metadata } from "next";
948
+ import type { LocalPromiseParams } from "next-intlayer";
949
+
950
+ export const generateMetadata = async ({
951
+ params,
952
+ }: LocalPromiseParams): Promise<Metadata> => {
953
+ const { locale } = await params;
954
+ const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale);
955
+
956
+ return {
957
+ title: t<string>({
958
+ en: "My title",
959
+ Alternativamente, puedes usar la función `getTranslation` para declarar tus metadatos. Sin embargo, se recomienda usar archivos de declaración de contenido para automatizar la traducción de tus metadatos y externalizar el contenido en algún momento.
960
+
961
+ ```typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat="typescript"
962
+ import {
963
+ type IConfigLocales,
964
+ getTranslation,
965
+ getMultilingualUrls,
966
+ } from "intlayer";
967
+ import type { Metadata } from "next";
968
+ import type { LocalPromiseParams } from "next-intlayer";
969
+
970
+ export const generateMetadata = async ({
971
+ params,
972
+ }: LocalPromiseParams): Promise<Metadata> => {
973
+ const { locale } = await params;
974
+ const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale);
975
+
976
+ return {
977
+ title: t<string>({
978
+ en: "My title",
979
+ fr: "Mon titre",
980
+ es: "Mi título",
981
+ }),
982
+ description: t({
983
+ en: "My description",
984
+ fr: "Ma description",
985
+ es: "Mi descripción",
986
+ }),
987
+ };
988
+ };
989
+
990
+ // ... Resto del código
991
+ ````
992
+
993
+ ```javascript fileName="src/app/[locale]/layout.mjs or src/app/[locale]/page.mjs" codeFormat="esm"
994
+ import { getTranslation, getMultilingualUrls } from "intlayer";
995
+
996
+ export const generateMetadata = async ({ params }) => {
997
+ const { locale } = await params;
998
+ const t = (content) => getTranslation(content, locale);
999
+
1000
+ return {
1001
+ title: t({
1002
+ en: "My title",
1003
+ fr: "Mon titre",
1004
+ es: "Mi título",
1005
+ }),
1006
+ description: t({
1007
+ en: "My description",
1008
+ fr: "Ma description",
1009
+ es: "Mi descripción",
1010
+ }),
1011
+ };
1012
+ };
1013
+
1014
+ // ... Resto del código
1015
+ ```
1016
+
1017
+ ```javascript fileName="src/app/[locale]/layout.cjs or src/app/[locale]/page.cjs" codeFormat="commonjs"
1018
+ const { getTranslation, getMultilingualUrls } = require("intlayer");
1019
+
1020
+ const generateMetadata = async ({ params }) => {
1021
+ const { locale } = await params;
1022
+
1023
+ const t = (content) => getTranslation(content, locale);
1024
+
1025
+ return {
1026
+ title: t({
1027
+ en: "My title",
1028
+ fr: "Mon titre",
1029
+ es: "Mi título",
1030
+ }),
1031
+ description: t({
1032
+ en: "My description",
1033
+ fr: "Ma description",
1034
+ es: "Mi descripción",
1035
+ }),
1036
+ };
1037
+ };
1038
+
1039
+ module.exports = { generateMetadata };
1040
+
1041
+ // ... Resto del código
1042
+ ```
1043
+
1044
+ > Aprende más sobre la optimización de metadatos [en la documentación oficial de Next.js](https://nextjs.org/docs/app/building-your-application/optimizing/metadata).
1045
+
1046
+ ````
1047
+
1048
+ ```javascript fileName="src/app/[locale]/layout.cjs or src/app/[locale]/page.cjs" codeFormat="commonjs"
1049
+ const { getTranslation, getMultilingualUrls } = require("intlayer");
1050
+
1051
+ const generateMetadata = async ({ params }) => {
1052
+ const { locale } = await params;
1053
+
1054
+ const t = (content) => getTranslation(content, locale);
1055
+
1056
+ return {
1057
+ title: t({
1058
+ en: "My title",
1059
+ fr: "Mon titre",
1060
+ es: "Mi título",
1061
+ }),
1062
+ description: t({
1063
+ en: "My description",
1064
+ fr: "Ma description",
1065
+ es: "Mi descripción",
1066
+ }),
1067
+ };
1068
+ };
1069
+
1070
+ module.exports = { generateMetadata };
1071
+
1072
+ // ... Resto del código
1073
+ ````
1074
+
1075
+ > Aprende más sobre la optimización de metadatos [en la documentación oficial de Next.js](https://nextjs.org/docs/app/building-your-application/optimizing/metadata).
1076
+
1077
+ ### (Opcional) Paso 9: Internacionalización de tu sitemap.xml y robots.txt
1078
+
1079
+ Para internacionalizar tu `sitemap.xml` y `robots.txt`, puedes usar la función `getMultilingualUrls` proporcionada por Intlayer. Esta función te permite generar URLs multilingües para tu sitemap.
1080
+
1081
+ ```tsx fileName="src/app/sitemap.ts" codeFormat="typescript"
1082
+ import { getMultilingualUrls } from "intlayer";
1083
+ import type { MetadataRoute } from "next";
1084
+
1085
+ const sitemap = (): MetadataRoute.Sitemap => [
1086
+ {
1087
+ url: "https://example.com",
1088
+ alternates: {
1089
+ languages: { ...getMultilingualUrls("https://example.com") },
1090
+ },
1091
+ },
1092
+ {
1093
+ url: "https://example.com/login",
1094
+ alternates: {
1095
+ languages: { ...getMultilingualUrls("https://example.com/login") },
1096
+ },
1097
+ },
1098
+ {
1099
+ url: "https://example.com/register",
1100
+ alternates: {
1101
+ languages: { ...getMultilingualUrls("https://example.com/register") },
1102
+ },
1103
+ },
1104
+ ];
1105
+
1106
+ export default sitemap;
1107
+ ```
1108
+
1109
+ ```jsx fileName="src/app/sitemap.mjx" codeFormat="esm"
1110
+ import { getMultilingualUrls } from "intlayer";
1111
+
1112
+ const sitemap = () => [
1113
+ {
1114
+ url: "https://example.com",
1115
+ alternates: {
1116
+ languages: { ...getMultilingualUrls("https://example.com") },
1117
+ },
1118
+ },
1119
+ {
1120
+ url: "https://example.com/login",
1121
+ alternates: {
1122
+ languages: { ...getMultilingualUrls("https://example.com/login") },
1123
+ },
1124
+ },
1125
+ {
1126
+ url: "https://example.com/register",
1127
+ alternates: {
1128
+ languages: { ...getMultilingualUrls("https://example.com/register") },
1129
+ },
1130
+ },
1131
+ ];
1132
+
1133
+ export default sitemap;
1134
+ ```
1135
+
1136
+ ```jsx fileName="src/app/sitemap.csx" codeFormat="commonjs"
1137
+ const { getMultilingualUrls } = require("intlayer");
1138
+
1139
+ const sitemap = () => [
1140
+ {
1141
+ url: "https://example.com",
1142
+ alternates: {
1143
+ languages: { ...getMultilingualUrls("https://example.com") },
1144
+ },
1145
+ },
1146
+ {
1147
+ url: "https://example.com/login",
1148
+ alternates: {
1149
+ languages: { ...getMultilingualUrls("https://example.com/login") },
1150
+ },
1151
+ },
1152
+ {
1153
+ url: "https://example.com/register",
1154
+ alternates: {
1155
+ languages: { ...getMultilingualUrls("https://example.com/register") },
1156
+ },
1157
+ },
1158
+ ];
1159
+
1160
+ module.exports = sitemap;
1161
+ ```
1162
+
1163
+ ```tsx fileName="src/app/robots.ts" codeFormat="typescript"
1164
+ import type { MetadataRoute } from "next";
1165
+ import { getMultilingualUrls } from "intlayer";
1166
+
1167
+ const getAllMultilingualUrls = (urls: string[]) =>
1168
+ urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);
1169
+
1170
+ // Configuración de reglas para robots.txt
1171
+ const robots = (): MetadataRoute.Robots => ({
1172
+ rules: {
1173
+ userAgent: "*", // Aplica a todos los agentes de usuario
1174
+ allow: ["/"], // Permite acceso a la raíz
1175
+ disallow: getAllMultilingualUrls(["/login", "/register"]), // Bloquea URLs multilingües de login y registro
1176
+ },
1177
+ host: "https://example.com",
1178
+ sitemap: `https://example.com/sitemap.xml`,
1179
+ });
1180
+
1181
+ export default robots;
1182
+ ```
1183
+
1184
+ ```jsx fileName="src/app/robots.mjx" codeFormat="esm"
1185
+ import { getMultilingualUrls } from "intlayer";
1186
+
1187
+ const getAllMultilingualUrls = (urls) =>
1188
+ urls.flatMap((url) => Object.values(getMultilingualUrls(url)));
1189
+
1190
+ const robots = () => ({
1191
+ rules: {
1192
+ userAgent: "*",
1193
+ allow: ["/"],
1194
+ disallow: getAllMultilingualUrls(["/login", "/register"]),
1195
+ },
1196
+ host: "https://example.com",
1197
+ sitemap: `https://example.com/sitemap.xml`,
1198
+ });
1199
+
1200
+ export default robots;
1201
+ ```
1202
+
1203
+ ```jsx fileName="src/app/robots.csx" codeFormat="commonjs"
1204
+ const { getMultilingualUrls } = require("intlayer");
1205
+
1206
+ const getAllMultilingualUrls = (urls) =>
1207
+ urls.flatMap((url) => Object.values(getMultilingualUrls(url)));
1208
+
1209
+ const robots = () => ({
1210
+ rules: {
1211
+ userAgent: "*",
1212
+ allow: ["/"],
1213
+ disallow: getAllMultilingualUrls(["/login", "/register"]),
1214
+ },
1215
+ host: "https://example.com",
1216
+ sitemap: `https://example.com/sitemap.xml`,
1217
+ });
1218
+
1219
+ module.exports = robots;
1220
+ ```
1221
+
1222
+ > Aprende más sobre la optimización del sitemap [en la documentación oficial de Next.js](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap). Aprende más sobre la optimización del archivo robots.txt [en la documentación oficial de Next.js](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/robots).
1223
+
1224
+ ### (Opcional) Paso 10: Cambia el idioma de tu contenido
1225
+
1226
+ Para cambiar el idioma de tu contenido en Next.js, la forma recomendada es usar el componente `Link` para redirigir a los usuarios a la página localizada correspondiente. El componente `Link` permite la precarga de la página, lo que ayuda a evitar una recarga completa de la página.
1227
+
1228
+ ```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
1229
+ "use client";
1230
+
1231
+ import type { FC } from "react";
1232
+ import {
1233
+ Locales,
1234
+ getHTMLTextDir,
1235
+ getLocaleName,
1236
+ getLocalizedUrl,
1237
+ } from "intlayer";
1238
+ import { useLocale } from "next-intlayer";
1239
+ import Link from "next/link";
1240
+
1241
+ export const LocaleSwitcher: FC = () => {
1242
+ const { locale, pathWithoutLocale, availableLocales, setLocale } =
1243
+ useLocale();
1244
+
1245
+ return (
1246
+ <div>
1247
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
1248
+ <div id="localePopover" popover="auto">
1249
+ {availableLocales.map((localeItem) => (
1250
+ <Link
1251
+ href={getLocalizedUrl(pathWithoutLocale, localeItem)}
1252
+ key={localeItem}
1253
+ aria-current={locale === localeItem ? "page" : undefined}
1254
+ onClick={() => setLocale(localeItem)}
1255
+ replace // Esto asegurará que el botón "volver" del navegador redirija a la página anterior
1256
+ >
1257
+ <span>
1258
+ {/* Local - p. ej., FR */}
1259
+ {localeItem}
1260
+ </span>
1261
+ <span>
1262
+ {/* Idioma en su propia localización - p. ej., Français */}
1263
+ {getLocaleName(localeItem, locale)}
1264
+ </span>
1265
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1266
+ {/* Idioma en la localización actual - p. ej., Francés con la localización actual configurada en Locales.SPANISH */}
1267
+ {getLocaleName(localeItem)}
1268
+ </span>
1269
+ <span dir="ltr" lang={Locales.ENGLISH}>
1270
+ {/* Idioma en inglés - p. ej., French */}
1271
+ {getLocaleName(localeItem, Locales.ENGLISH)}
1272
+ </span>
1273
+ </Link>
1274
+ ))}
1275
+ </div>
1276
+ </div>
1277
+ );
1278
+ };
1279
+ ```
1280
+
1281
+ ```jsx fileName="src/components/LocaleSwitcher.msx" codeFormat="esm"
1282
+ "use client";
1283
+
1284
+ import {
1285
+ Locales,
1286
+ getHTMLTextDir,
1287
+ getLocaleName,
1288
+ getLocalizedUrl,
1289
+ } from "intlayer";
1290
+ import { useLocale } from "next-intlayer";
1291
+ import Link from "next/link";
1292
+
1293
+ export const LocaleSwitcher = () => {
1294
+ const { locale, pathWithoutLocale, availableLocales, setLocale } =
1295
+ useLocale();
1296
+
1297
+ return (
1298
+ <div>
1299
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
1300
+ <div id="localePopover" popover="auto">
1301
+ {availableLocales.map((localeItem) => (
1302
+ <Link
1303
+ href={getLocalizedUrl(pathWithoutLocale, localeItem)}
1304
+ key={localeItem}
1305
+ aria-current={locale === localeItem ? "page" : undefined}
1306
+ onClick={() => setLocale(localeItem)}
1307
+ replace // Asegurará que el botón "volver" del navegador redirija a la página anterior
1308
+ >
1309
+ <span>
1310
+ {/* Local - p.ej. FR */}
1311
+ {localeItem}
1312
+ </span>
1313
+ <span>
1314
+ {/* Idioma en su propia Local - p.ej. Français */}
1315
+ {getLocaleName(localeItem, locale)}
1316
+ </span>
1317
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1318
+ {/* Idioma en la Local actual - p.ej. Francés con la local actual configurada a Locales.SPANISH */}
1319
+ {getLocaleName(localeItem)}
1320
+ </span>
1321
+ <span dir="ltr" lang={Locales.ENGLISH}>
1322
+ {/* Idioma en inglés - p.ej. French */}
1323
+ {getLocaleName(localeItem, Locales.ENGLISH)}
1324
+ </span>
1325
+ </Link>
1326
+ ))}
1327
+ </div>
1328
+ </div>
1329
+ );
1330
+ };
1331
+ ```
1332
+
1333
+ ```jsx fileName="src/components/LocaleSwitcher.csx" codeFormat="commonjs"
1334
+ "use client";
1335
+
1336
+ const {
1337
+ Locales,
1338
+ getHTMLTextDir,
1339
+ getLocaleName,
1340
+ getLocalizedUrl,
1341
+ } = require("intlayer");
1342
+ const { useLocale } = require("next-intlayer");
1343
+ const Link = require("next/link");
1344
+
1345
+ export const LocaleSwitcher = () => {
1346
+ const { locale, pathWithoutLocale, availableLocales, setLocale } =
1347
+ useLocale();
1348
+
1349
+ return (
1350
+ <div>
1351
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
1352
+ <div id="localePopover" popover="auto">
1353
+ {availableLocales.map((localeItem) => (
1354
+ <Link
1355
+ href={getLocalizedUrl(pathWithoutLocale, localeItem)}
1356
+ key={localeItem}
1357
+ aria-current={locale === localeItem ? "page" : undefined}
1358
+ onClick={() => setLocale(localeItem)}
1359
+ replace // Esto asegurará que el botón "volver" del navegador redirija a la página anterior
1360
+ >
1361
+ <span>
1362
+ {/* Localización - por ejemplo FR */}
1363
+ {localeItem}
1364
+ </span>
1365
+ <span>
1366
+ {/* Idioma en su propia localización - por ejemplo Français */}
1367
+ {getLocaleName(localeItem, locale)}
1368
+ </span>
1369
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1370
+ {/* Idioma en la localización actual - por ejemplo Francés con la localización actual configurada en Locales.SPANISH */}
1371
+ {getLocaleName(localeItem)}
1372
+ </span>
1373
+ <span dir="ltr" lang={Locales.ENGLISH}>
1374
+ {/* Idioma en inglés - por ejemplo, French */}
1375
+ {getLocaleName(localeItem, Locales.ENGLISH)}
1376
+ </span>
1377
+ </Link>
1378
+ ))}
1379
+ </div>
1380
+ </div>
1381
+ );
1382
+ };
1383
+ ```
1384
+
1385
+ > Una forma alternativa es usar la función `setLocale` proporcionada por el hook `useLocale`. Esta función no permitirá la precarga de la página. Consulta la [documentación del hook `useLocale`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/next-intlayer/useLocale.md) para más detalles.
1386
+
1387
+ > También puedes establecer una función en la opción `onLocaleChange` para activar una función personalizada cuando cambie la configuración regional.
1388
+
1389
+ ```tsx fileName="src/components/LocaleSwitcher.tsx"
1390
+ "use client";
1391
+
1392
+ import { useRouter } from "next/navigation";
1393
+ import { useLocale } from "next-intlayer";
1394
+ import { getLocalizedUrl } from "intlayer";
1395
+
1396
+ // ... Resto del código
1397
+
1398
+ const router = useRouter();
1399
+ const { setLocale } = useLocale({
1400
+ onLocaleChange: (locale) => {
1401
+ router.push(getLocalizedUrl(pathWithoutLocale, locale));
1402
+ },
1403
+ });
1404
+
1405
+ return (
1406
+ <button onClick={() => setLocale(Locales.FRENCH)}>Cambiar a francés</button>
1407
+ );
1408
+ ```
1409
+
1410
+ > Referencias de la documentación:
1411
+ >
1412
+ > - [`useLocale` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/next-intlayer/useLocale.md)
1413
+ > - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getLocaleName.md)
1414
+ > - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getLocalizedUrl.md)
1415
+ > - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getHTMLTextDir.md)
1416
+ > - [`hrefLang` attribute](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
1417
+ > - [`lang` attribute](https://developer.mozilla.org/es/docs/Web/HTML/Atributos_globales/lang)
1418
+ > - [`dir` attribute`](https://developer.mozilla.org/es/docs/Web/HTML/Atributos_globales/dir)
1419
+ > - [`aria-current` attribute`](https://developer.mozilla.org/es/docs/Web/Accessibility/ARIA/Atributos/aria-current)
1420
+
1421
+ ### (Opcional) Paso 11: Creación de un Componente de Enlace Localizado
1422
+
1423
+ Para asegurar que la navegación de tu aplicación respete la configuración regional actual, puedes crear un componente personalizado `Link`. Este componente antepone automáticamente a las URLs internas el idioma actual. Por ejemplo, cuando un usuario francófono hace clic en un enlace a la página "Acerca de", es redirigido a `/fr/about` en lugar de `/about`.
1424
+
1425
+ Este comportamiento es útil por varias razones:
1426
+
1427
+ - **SEO y experiencia del usuario**: Las URLs localizadas ayudan a los motores de búsqueda a indexar correctamente las páginas específicas por idioma y proporcionan a los usuarios contenido en su idioma preferido.
1428
+ - **Consistencia**: Al usar un enlace localizado en toda tu aplicación, garantizas que la navegación se mantenga dentro de la configuración regional actual, evitando cambios inesperados de idioma.
1429
+ - **Mantenibilidad**: Centralizar la lógica de localización en un solo componente simplifica la gestión de URLs, haciendo que tu base de código sea más fácil de mantener y ampliar a medida que tu aplicación crece.
1430
+
1431
+ A continuación se muestra la implementación de un componente `Link` localizado en TypeScript:
1432
+
1433
+ ```tsx fileName="src/components/Link.tsx" codeFormat="typescript"
1434
+ "use client";
1435
+
1436
+ import { getLocalizedUrl } from "intlayer";
1437
+ import NextLink, { type LinkProps as NextLinkProps } from "next/link";
1438
+ import { useLocale } from "next-intlayer";
1439
+ import type { PropsWithChildren, FC } from "react";
1440
+
1441
+ /**
1442
+ * Función utilitaria para verificar si una URL dada es externa.
1443
+ * Si la URL comienza con http:// o https://, se considera externa.
1444
+ */
1445
+ export const checkIsExternalLink = (href?: string): boolean =>
1446
+ /^https?:\/\//.test(href ?? "");
1447
+
1448
+ /**
1449
+ * Un componente Link personalizado que adapta el atributo href según la configuración regional actual.
1450
+ * Para enlaces internos, utiliza `getLocalizedUrl` para anteponer la configuración regional a la URL (por ejemplo, /fr/about).
1451
+ * Esto asegura que la navegación se mantenga dentro del mismo contexto regional.
1452
+ */
1453
+ export const Link: FC<PropsWithChildren<NextLinkProps>> = ({
1454
+ href,
1455
+ children,
1456
+ ...props
1457
+ }) => {
1458
+ const { locale } = useLocale();
1459
+ const isExternalLink = checkIsExternalLink(href.toString());
1460
+
1461
+ // Si el enlace es interno y se proporciona un href válido, obtiene la URL localizada.
1462
+ const hrefI18n: NextLinkProps["href"] =
1463
+ href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href;
1464
+
1465
+ return (
1466
+ <NextLink href={hrefI18n} {...props}>
1467
+ {children}
1468
+ </NextLink>
1469
+ );
1470
+ };
1471
+ ```
1472
+
1473
+ ```jsx fileName="src/components/Link.mjx" codeFormat="esm"
1474
+ "use client";
1475
+
1476
+ import { getLocalizedUrl } from "intlayer";
1477
+ import NextLink from "next/link";
1478
+ import { useLocale } from "next-intlayer";
1479
+
1480
+ /**
1481
+ * Función utilitaria para verificar si una URL dada es externa.
1482
+ * Si la URL comienza con http:// o https://, se considera externa.
1483
+ */
1484
+ export const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
1485
+
1486
+ /**
1487
+ * Un componente Link personalizado que adapta el atributo href según la localización actual.
1488
+ * Para enlaces internos, utiliza `getLocalizedUrl` para prefijar la URL con la localización (por ejemplo, /fr/about).
1489
+ * Esto asegura que la navegación se mantenga dentro del mismo contexto de localización.
1490
+ */
1491
+ export const Link = ({ href, children, ...props }) => {
1492
+ const { locale } = useLocale();
1493
+ const isExternalLink = checkIsExternalLink(href.toString());
1494
+
1495
+ // Si el enlace es interno y se proporciona un href válido, obtener la URL localizada.
1496
+ const hrefI18n =
1497
+ href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href;
1498
+
1499
+ return (
1500
+ <NextLink href={hrefI18n} {...props}>
1501
+ {children}
1502
+ </NextLink>
1503
+ );
1504
+ };
1505
+ ```
1506
+
1507
+ ```jsx fileName="src/components/Link.csx" codeFormat="commonjs"
1508
+ "use client";
1509
+
1510
+ const { getLocalizedUrl } = require("intlayer");
1511
+ const NextLink = require("next/link");
1512
+ const { useLocale } = require("next-intlayer");
1513
+
1514
+ /**
1515
+ * Función utilitaria para verificar si una URL dada es externa.
1516
+ * Si la URL comienza con http:// o https://, se considera externa.
1517
+ */
1518
+ const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
1519
+
1520
+ /**
1521
+ * Un componente Link personalizado que adapta el atributo href según la configuración regional actual.
1522
+ * Para enlaces internos, utiliza `getLocalizedUrl` para anteponer la configuración regional a la URL (por ejemplo, /fr/about).
1523
+ * Esto asegura que la navegación se mantenga dentro del mismo contexto regional.
1524
+ */
1525
+ const Link = ({ href, children, ...props }) => {
1526
+ const { locale } = useLocale();
1527
+ const isExternalLink = checkIsExternalLink(href.toString());
1528
+
1529
+ // Si el enlace es interno y se proporciona un href válido, obtiene la URL localizada.
1530
+ const hrefI18n =
1531
+ href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href;
1532
+
1533
+ return (
1534
+ <NextLink href={hrefI18n} {...props}>
1535
+ {children}
1536
+ </NextLink>
1537
+ );
1538
+ };
1539
+ ```
1540
+
1541
+ #### Cómo Funciona
1542
+
1543
+ - **Detección de Enlaces Externos**:
1544
+ La función auxiliar `checkIsExternalLink` determina si una URL es externa. Los enlaces externos se dejan sin cambios porque no necesitan localización.
1545
+
1546
+ - **Recuperar la configuración regional actual**:
1547
+ El hook `useLocale` proporciona la configuración regional actual (por ejemplo, `fr` para francés).
1548
+
1549
+ - **Localizar la URL**:
1550
+ Para enlaces internos (es decir, no externos), se utiliza `getLocalizedUrl` para prefijar automáticamente la URL con la configuración regional actual. Esto significa que si tu usuario está en francés, pasar `/about` como `href` se transformará en `/fr/about`.
1551
+
1552
+ - **Devolver el enlace**:
1553
+ El componente devuelve un elemento `<a>` con la URL localizada, asegurando que la navegación sea coherente con la configuración regional.
1554
+
1555
+ Al integrar este componente `Link` en toda su aplicación, mantiene una experiencia de usuario coherente y consciente del idioma, al mismo tiempo que se beneficia de una mejor SEO y usabilidad.
1556
+
1557
+ ### (Opcional) Paso 12: Obtener la configuración regional actual en las Acciones del Servidor
1558
+
1559
+ Si necesita la configuración regional activa dentro de una Acción del Servidor (por ejemplo, para localizar correos electrónicos o ejecutar lógica dependiente del idioma), llame a `getLocale` desde `next-intlayer/server`:
1560
+
1561
+ ```tsx fileName="src/app/actions/getLocale.ts" codeFormat="typescript"
1562
+ "use server";
1563
+
1564
+ import { getLocale } from "next-intlayer/server";
1565
+
1566
+ export const myServerAction = async () => {
1567
+ const locale = await getLocale();
1568
+
1569
+ // Hacer algo con la configuración regional
1570
+ };
1571
+ ```
1572
+
1573
+ > La función `getLocale` sigue una estrategia en cascada para determinar la configuración regional del usuario:
1574
+ >
1575
+ > 1. Primero, verifica en los encabezados de la solicitud si hay un valor de configuración regional que pueda haber sido establecido por el proxy
1576
+ > 2. Si no se encuentra una configuración regional en los encabezados, busca una configuración regional almacenada en las cookies
1577
+ > 3. Si no se encuentra ninguna cookie, intenta detectar el idioma preferido del usuario a partir de la configuración de su navegador
1578
+ > 4. Como último recurso, utiliza la configuración regional predeterminada configurada en la aplicación
1579
+ >
1580
+ > Esto asegura que se seleccione la configuración regional más apropiada según el contexto disponible.
1581
+
1582
+ ### (Opcional) Paso 13: Optimiza el tamaño de tu paquete
1583
+
1584
+ Al usar `next-intlayer`, los diccionarios se incluyen en el paquete para cada página por defecto. Para optimizar el tamaño del paquete, Intlayer proporciona un plugin SWC opcional que reemplaza inteligentemente las llamadas a `useIntlayer` usando macros. Esto asegura que los diccionarios solo se incluyan en los paquetes de las páginas que realmente los usan.
1585
+
1586
+ Para habilitar esta optimización, instala el paquete `@intlayer/swc`. Una vez instalado, `next-intlayer` detectará y usará automáticamente el plugin:
1587
+
1588
+ ```bash packageManager="npm"
1589
+ npm install @intlayer/swc --save-dev
1590
+ ```
1591
+
1592
+ ```bash packageManager="pnpm"
1593
+ pnpm add @intlayer/swc --save-dev
1594
+ ```
1595
+
1596
+ ```bash packageManager="yarn"
1597
+ yarn add @intlayer/swc --save-dev
1598
+ ```
1599
+
1600
+ > Nota: Esta optimización solo está disponible para Next.js 13 y versiones superiores.
1601
+
1602
+ > Nota: Este paquete no se instala por defecto porque los plugins SWC aún son experimentales en Next.js. Esto podría cambiar en el futuro.
1603
+
1604
+ ### Supervisar cambios en los diccionarios con Turbopack
1605
+
1606
+ Cuando se usa Turbopack como servidor de desarrollo con el comando `next dev`, los cambios en los diccionarios no se detectan automáticamente por defecto.
1607
+
1608
+ Esta limitación ocurre porque Turbopack no puede ejecutar plugins de webpack en paralelo para monitorear cambios en tus archivos de contenido. Para solucionar esto, necesitarás usar el comando `intlayer watch` para ejecutar simultáneamente el servidor de desarrollo y el observador de compilación de Intlayer.
1609
+
1610
+ ```json5 fileName="package.json"
1611
+ {
1612
+ // ... Tus configuraciones existentes en package.json
1613
+ "scripts": {
1614
+ // ... Tus configuraciones existentes de scripts
1615
+ "dev": "intlayer watch --with 'next dev'",
1616
+ },
1617
+ }
1618
+ ```
1619
+
1620
+ > Si estás usando next-intlayer@<=6.x.x, necesitas mantener el flag `--turbopack` para que la aplicación Next.js 16 funcione correctamente con Turbopack. Recomendamos usar next-intlayer@>=7.x.x para evitar esta limitación.
1621
+
1622
+ ### Configurar TypeScript
1623
+
1624
+ Intlayer usa la ampliación de módulos para aprovechar las ventajas de TypeScript y fortalecer tu base de código.
1625
+
1626
+ ![Autocompletado](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)
1627
+
1628
+ ![Error de traducción](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)
1629
+
1630
+ Asegúrate de que tu configuración de TypeScript incluya los tipos autogenerados.
1631
+
1632
+ ```json5 fileName="tsconfig.json"
1633
+ {
1634
+ // ... Tus configuraciones existentes de TypeScript
1635
+ "include": [
1636
+ // ... Tus configuraciones existentes de TypeScript
1637
+ ".intlayer/**/*.ts", // Include the auto-generated types
1638
+ ],
1639
+ }
1640
+ ```
1641
+
1642
+ ### Configuración de Git
1643
+
1644
+ Se recomienda ignorar los archivos generados por Intlayer. Esto te permite evitar comprometerlos en tu repositorio Git.
1645
+
1646
+ Para hacerlo, puedes agregar las siguientes instrucciones a tu archivo `.gitignore`:
1647
+
1648
+ ```plaintext fileName=".gitignore"
1649
+ # Ignorar los archivos generados por Intlayer
1650
+ .intlayer
1651
+ ```
1652
+
1653
+ ### Extensión para VS Code
1654
+
1655
+ Para mejorar tu experiencia de desarrollo con Intlayer, puedes instalar la **Extensión oficial de Intlayer para VS Code**.
1656
+
1657
+ [Instalar desde el Marketplace de VS Code](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
1658
+
1659
+ Esta extensión proporciona:
1660
+
1661
+ - **Autocompletado** para las claves de traducción.
1662
+ - **Detección de errores en tiempo real** para traducciones faltantes.
1663
+ - **Vistas previas en línea** del contenido traducido.
1664
+ - **Acciones rápidas** para crear y actualizar traducciones fácilmente.
1665
+
1666
+ Para más detalles sobre cómo usar la extensión, consulta la [documentación de la extensión Intlayer para VS Code](https://intlayer.org/doc/vs-code-extension).
1667
+
1668
+ ### Ir más allá
1669
+
1670
+ Para ir más allá, puedes implementar el [editor visual](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_visual_editor.md) o externalizar tu contenido usando el [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_CMS.md).