@intlayer/docs 8.0.0 → 8.0.1-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/generated/docs.entry.cjs +160 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +160 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +8 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_adonisjs.md +394 -0
- package/docs/ar/intlayer_with_hono.md +223 -0
- package/docs/ar/intlayer_with_vite+preact.md +317 -675
- package/docs/ar/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ar/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ar/packages/adonis-intlayer/t.md +149 -0
- package/docs/ar/packages/hono-intlayer/exports.md +59 -0
- package/docs/ar/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ar/packages/hono-intlayer/t.md +268 -0
- package/docs/de/intlayer_with_adonisjs.md +392 -0
- package/docs/de/intlayer_with_hono.md +418 -0
- package/docs/de/intlayer_with_vite+preact.md +272 -632
- package/docs/de/packages/adonis-intlayer/exports.md +50 -0
- package/docs/de/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/de/packages/adonis-intlayer/t.md +149 -0
- package/docs/de/packages/hono-intlayer/exports.md +59 -0
- package/docs/de/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/de/packages/hono-intlayer/t.md +316 -0
- package/docs/en/index.md +8 -0
- package/docs/en/intlayer_with_adonisjs.md +388 -0
- package/docs/en/intlayer_with_hono.md +418 -0
- package/docs/en/intlayer_with_vite+preact.md +171 -556
- package/docs/en/introduction.md +1 -0
- package/docs/en/packages/adonis-intlayer/exports.md +50 -0
- package/docs/en/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/en/packages/adonis-intlayer/t.md +149 -0
- package/docs/en/packages/hono-intlayer/exports.md +59 -0
- package/docs/en/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/en/packages/hono-intlayer/t.md +316 -0
- package/docs/en-GB/intlayer_with_adonisjs.md +394 -0
- package/docs/en-GB/intlayer_with_hono.md +418 -0
- package/docs/en-GB/intlayer_with_vite+preact.md +236 -583
- package/docs/en-GB/packages/adonis-intlayer/exports.md +50 -0
- package/docs/en-GB/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/en-GB/packages/adonis-intlayer/t.md +149 -0
- package/docs/en-GB/packages/hono-intlayer/exports.md +59 -0
- package/docs/en-GB/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/en-GB/packages/hono-intlayer/t.md +316 -0
- package/docs/es/intlayer_with_adonisjs.md +388 -0
- package/docs/es/intlayer_with_hono.md +418 -0
- package/docs/es/intlayer_with_vite+preact.md +286 -650
- package/docs/es/packages/adonis-intlayer/exports.md +50 -0
- package/docs/es/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/es/packages/adonis-intlayer/t.md +149 -0
- package/docs/es/packages/hono-intlayer/exports.md +59 -0
- package/docs/es/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/es/packages/hono-intlayer/t.md +316 -0
- package/docs/fr/intlayer_with_adonisjs.md +388 -0
- package/docs/fr/intlayer_with_hono.md +418 -0
- package/docs/fr/intlayer_with_vite+preact.md +274 -614
- package/docs/fr/packages/adonis-intlayer/exports.md +50 -0
- package/docs/fr/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/fr/packages/adonis-intlayer/t.md +149 -0
- package/docs/fr/packages/hono-intlayer/exports.md +59 -0
- package/docs/fr/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/fr/packages/hono-intlayer/t.md +316 -0
- package/docs/hi/intlayer_with_adonisjs.md +394 -0
- package/docs/hi/intlayer_with_hono.md +227 -0
- package/docs/hi/intlayer_with_vite+preact.md +304 -680
- package/docs/hi/packages/adonis-intlayer/exports.md +50 -0
- package/docs/hi/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/hi/packages/adonis-intlayer/t.md +149 -0
- package/docs/hi/packages/hono-intlayer/exports.md +59 -0
- package/docs/hi/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/hi/packages/hono-intlayer/t.md +268 -0
- package/docs/id/intlayer_with_adonisjs.md +394 -0
- package/docs/id/intlayer_with_hono.md +227 -0
- package/docs/id/intlayer_with_vite+preact.md +297 -697
- package/docs/id/packages/adonis-intlayer/exports.md +50 -0
- package/docs/id/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/id/packages/adonis-intlayer/t.md +149 -0
- package/docs/id/packages/hono-intlayer/exports.md +59 -0
- package/docs/id/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/id/packages/hono-intlayer/t.md +268 -0
- package/docs/it/intlayer_with_adonisjs.md +394 -0
- package/docs/it/intlayer_with_hono.md +227 -0
- package/docs/it/intlayer_with_vite+preact.md +290 -659
- package/docs/it/packages/adonis-intlayer/exports.md +50 -0
- package/docs/it/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/it/packages/adonis-intlayer/t.md +149 -0
- package/docs/it/packages/hono-intlayer/exports.md +59 -0
- package/docs/it/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/it/packages/hono-intlayer/t.md +268 -0
- package/docs/ja/intlayer_with_adonisjs.md +394 -0
- package/docs/ja/intlayer_with_hono.md +227 -0
- package/docs/ja/intlayer_with_vite+preact.md +307 -662
- package/docs/ja/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ja/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ja/packages/adonis-intlayer/t.md +149 -0
- package/docs/ja/packages/hono-intlayer/exports.md +59 -0
- package/docs/ja/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ja/packages/hono-intlayer/t.md +268 -0
- package/docs/ko/intlayer_with_adonisjs.md +394 -0
- package/docs/ko/intlayer_with_hono.md +227 -0
- package/docs/ko/intlayer_with_vite+preact.md +303 -703
- package/docs/ko/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ko/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ko/packages/adonis-intlayer/t.md +149 -0
- package/docs/ko/packages/hono-intlayer/exports.md +59 -0
- package/docs/ko/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ko/packages/hono-intlayer/t.md +268 -0
- package/docs/pl/intlayer_with_adonisjs.md +394 -0
- package/docs/pl/intlayer_with_hono.md +227 -0
- package/docs/pl/intlayer_with_vite+preact.md +289 -690
- package/docs/pl/packages/adonis-intlayer/exports.md +50 -0
- package/docs/pl/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/pl/packages/adonis-intlayer/t.md +149 -0
- package/docs/pl/packages/hono-intlayer/exports.md +59 -0
- package/docs/pl/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/pl/packages/hono-intlayer/t.md +268 -0
- package/docs/pt/intlayer_with_adonisjs.md +394 -0
- package/docs/pt/intlayer_with_hono.md +227 -0
- package/docs/pt/intlayer_with_vite+preact.md +275 -637
- package/docs/pt/packages/adonis-intlayer/exports.md +50 -0
- package/docs/pt/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/pt/packages/adonis-intlayer/t.md +149 -0
- package/docs/pt/packages/hono-intlayer/exports.md +59 -0
- package/docs/pt/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/pt/packages/hono-intlayer/t.md +268 -0
- package/docs/ru/intlayer_with_adonisjs.md +393 -0
- package/docs/ru/intlayer_with_hono.md +223 -0
- package/docs/ru/intlayer_with_vite+preact.md +319 -683
- package/docs/ru/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ru/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ru/packages/adonis-intlayer/t.md +149 -0
- package/docs/ru/packages/hono-intlayer/exports.md +59 -0
- package/docs/ru/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ru/packages/hono-intlayer/t.md +268 -0
- package/docs/tr/intlayer_with_adonisjs.md +394 -0
- package/docs/tr/intlayer_with_hono.md +227 -0
- package/docs/tr/intlayer_with_vite+preact.md +332 -665
- package/docs/tr/packages/adonis-intlayer/exports.md +50 -0
- package/docs/tr/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/tr/packages/adonis-intlayer/t.md +149 -0
- package/docs/tr/packages/hono-intlayer/exports.md +59 -0
- package/docs/tr/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/tr/packages/hono-intlayer/t.md +268 -0
- package/docs/uk/intlayer_with_adonisjs.md +394 -0
- package/docs/uk/intlayer_with_hono.md +227 -0
- package/docs/uk/intlayer_with_vite+preact.md +228 -626
- package/docs/uk/packages/adonis-intlayer/exports.md +50 -0
- package/docs/uk/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/uk/packages/adonis-intlayer/t.md +149 -0
- package/docs/uk/packages/hono-intlayer/exports.md +59 -0
- package/docs/uk/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/uk/packages/hono-intlayer/t.md +268 -0
- package/docs/vi/intlayer_with_adonisjs.md +394 -0
- package/docs/vi/intlayer_with_hono.md +227 -0
- package/docs/vi/intlayer_with_vite+preact.md +294 -679
- package/docs/vi/packages/adonis-intlayer/exports.md +50 -0
- package/docs/vi/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/vi/packages/adonis-intlayer/t.md +149 -0
- package/docs/vi/packages/hono-intlayer/exports.md +59 -0
- package/docs/vi/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/vi/packages/hono-intlayer/t.md +268 -0
- package/docs/zh/intlayer_with_adonisjs.md +393 -0
- package/docs/zh/intlayer_with_hono.md +418 -0
- package/docs/zh/intlayer_with_vite+preact.md +338 -743
- package/docs/zh/packages/adonis-intlayer/exports.md +50 -0
- package/docs/zh/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/zh/packages/adonis-intlayer/t.md +149 -0
- package/docs/zh/packages/hono-intlayer/exports.md +59 -0
- package/docs/zh/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/zh/packages/hono-intlayer/t.md +294 -0
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +160 -0
|
@@ -47,7 +47,7 @@ history:
|
|
|
47
47
|
|
|
48
48
|
> Este paquete está en desarrollo. Consulta el [issue](https://github.com/aymericzip/intlayer/issues/118) para más información. Muestra tu interés en Intlayer para Preact dando like al issue.
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
See [Plantilla de Aplicación](https://github.com/aymericzip/intlayer-vite-preact-template) en GitHub.
|
|
51
51
|
|
|
52
52
|
## ¿Qué es Intlayer?
|
|
53
53
|
|
|
@@ -92,8 +92,6 @@ bun add vite-intlayer --dev
|
|
|
92
92
|
bunx intlayer init
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
- **intlayer**
|
|
96
|
-
|
|
97
95
|
- **intlayer**
|
|
98
96
|
|
|
99
97
|
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/get_started.md), transpilación y [comandos CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_cli.md).
|
|
@@ -121,6 +119,10 @@ const config: IntlayerConfig = {
|
|
|
121
119
|
],
|
|
122
120
|
defaultLocale: Locales.ENGLISH,
|
|
123
121
|
},
|
|
122
|
+
routing: {
|
|
123
|
+
mode: "prefix-no-default", // Por defecto: prefijo para todos los locales excepto el predeterminado
|
|
124
|
+
storage: ["cookie", "header"], // Por defecto: guardar locale en cookie y detectar del header
|
|
125
|
+
},
|
|
124
126
|
};
|
|
125
127
|
|
|
126
128
|
export default config;
|
|
@@ -140,6 +142,10 @@ const config = {
|
|
|
140
142
|
],
|
|
141
143
|
defaultLocale: Locales.ENGLISH,
|
|
142
144
|
},
|
|
145
|
+
routing: {
|
|
146
|
+
mode: "prefix-no-default", // Por defecto: prefijo para todos los locales excepto el predeterminado
|
|
147
|
+
storage: ["cookie", "header"], // Por defecto: guardar locale en cookie y detectar del header
|
|
148
|
+
},
|
|
143
149
|
};
|
|
144
150
|
|
|
145
151
|
export default config;
|
|
@@ -159,12 +165,16 @@ const config = {
|
|
|
159
165
|
],
|
|
160
166
|
defaultLocale: Locales.ENGLISH,
|
|
161
167
|
},
|
|
168
|
+
routing: {
|
|
169
|
+
mode: "prefix-no-default", // Por defecto: prefijo para todos los locales excepto el predeterminado
|
|
170
|
+
storage: ["cookie", "header"], // Por defecto: guardar locale en cookie y detectar del header
|
|
171
|
+
},
|
|
162
172
|
};
|
|
163
173
|
|
|
164
174
|
module.exports = config;
|
|
165
175
|
```
|
|
166
176
|
|
|
167
|
-
> A través de este archivo de configuración, puedes configurar URLs localizadas,
|
|
177
|
+
> A través de este archivo de configuración, puedes configurar URLs localizadas, modos de enrutamiento, opciones de almacenamiento, nombres de cookies, la ubicación y extensión de tus declaraciones de contenido, deshabilitar los logs 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).
|
|
168
178
|
|
|
169
179
|
### Paso 3: Integra Intlayer en tu configuración de Vite
|
|
170
180
|
|
|
@@ -238,7 +248,7 @@ const appContent = {
|
|
|
238
248
|
edit: t<ComponentChildren>({
|
|
239
249
|
en: (
|
|
240
250
|
<>
|
|
241
|
-
|
|
251
|
+
Edit <code>src/app.tsx</code> and save to test HMR
|
|
242
252
|
</>
|
|
243
253
|
),
|
|
244
254
|
fr: (
|
|
@@ -254,7 +264,7 @@ const appContent = {
|
|
|
254
264
|
}),
|
|
255
265
|
|
|
256
266
|
readTheDocs: t({
|
|
257
|
-
en: "
|
|
267
|
+
en: "Click on the Vite and Preact logos to learn more",
|
|
258
268
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
259
269
|
es: "Haz clic en los logotipos de Vite y Preact para obtener más información",
|
|
260
270
|
}),
|
|
@@ -292,13 +302,13 @@ const appContent = {
|
|
|
292
302
|
}),
|
|
293
303
|
|
|
294
304
|
edit: t({
|
|
295
|
-
en: "
|
|
305
|
+
en: "Edit src/app.jsx and save to test HMR",
|
|
296
306
|
fr: "Éditez src/app.jsx et enregistrez pour tester HMR",
|
|
297
307
|
es: "Edita src/app.jsx y guarda para probar HMR",
|
|
298
308
|
}),
|
|
299
309
|
|
|
300
310
|
readTheDocs: t({
|
|
301
|
-
en: "
|
|
311
|
+
en: "Click on the Vite and Preact logos to learn more",
|
|
302
312
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
303
313
|
es: "Haz clic en los logotipos de Vite y Preact para obtener más información",
|
|
304
314
|
}),
|
|
@@ -393,23 +403,7 @@ module.exports = appContent;
|
|
|
393
403
|
"nodeType": "translation",
|
|
394
404
|
"translation": {
|
|
395
405
|
"en": "Edit src/app.tsx and save to test HMR",
|
|
396
|
-
"fr": "Éditez src/app.tsx et enregistrez
|
|
397
|
-
"es": "Edita src/app.tsx y guarda para probar HMR"
|
|
398
|
-
}
|
|
399
|
-
},
|
|
400
|
-
"readTheDocs": {
|
|
401
|
-
"nodeType": "translation",
|
|
402
|
-
"translation": {
|
|
403
|
-
"en": "Click on the Vite and Preact logos to learn more",
|
|
404
|
-
"fr": "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
405
|
-
"es": "Haga clic en los logotipos de Vite y Preact para obtener más información"
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
"translation": {
|
|
411
|
-
"en": "Edit src/app.tsx and save to test HMR",
|
|
412
|
-
"fr": "Éditez src/app.tsx et enregistrez pour tester HMR",
|
|
406
|
+
"fr": "Éditez src/app.tsx et enregistrez para probar HMR",
|
|
413
407
|
"es": "Edita src/app.tsx y guarda para probar HMR"
|
|
414
408
|
}
|
|
415
409
|
},
|
|
@@ -469,6 +463,12 @@ const AppContent: FunctionalComponent = () => {
|
|
|
469
463
|
</button>
|
|
470
464
|
<p>{content.edit}</p>
|
|
471
465
|
</div>
|
|
466
|
+
{/* Contenido Markdown */}
|
|
467
|
+
<div>{content.myMarkdownContent}</div>
|
|
468
|
+
|
|
469
|
+
{/* Contenido HTML */}
|
|
470
|
+
<div>{content.myHtmlContent}</div>
|
|
471
|
+
|
|
472
472
|
<p class="read-the-docs">{content.readTheDocs}</p>
|
|
473
473
|
</>
|
|
474
474
|
);
|
|
@@ -645,9 +645,9 @@ module.exports = LocaleSwitcher;
|
|
|
645
645
|
|
|
646
646
|
> Para aprender más sobre el hook `useLocale`, consulta la [documentación](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/react-intlayer/useLocale.md) (La API es similar para `preact-intlayer`).
|
|
647
647
|
|
|
648
|
-
### (Opcional) Paso 7:
|
|
648
|
+
### (Opcional) Paso 7: Agregar enrutamiento localizado a su aplicación
|
|
649
649
|
|
|
650
|
-
El propósito de este paso es crear rutas únicas para cada idioma. Esto es útil para SEO y URLs amigables
|
|
650
|
+
El propósito de este paso es crear rutas únicas para cada idioma. Esto es útil para SEO y URLs amigables para el SEO.
|
|
651
651
|
Ejemplo:
|
|
652
652
|
|
|
653
653
|
```plaintext
|
|
@@ -656,406 +656,107 @@ Ejemplo:
|
|
|
656
656
|
- https://example.com/fr/about
|
|
657
657
|
```
|
|
658
658
|
|
|
659
|
-
> Por defecto, las rutas no tienen prefijo para
|
|
660
|
-
|
|
661
|
-
Para agregar enrutamiento localizado a su aplicación, puede crear un componente `LocaleRouter` que envuelva las rutas de su aplicación y gestione el enrutamiento basado en la configuración regional. Aquí hay un ejemplo usando [preact-iso](https://github.com/preactjs/preact-iso):
|
|
659
|
+
> Por defecto, las rutas no tienen prefijo para el idioma predeterminado. Si desea prefijar el idioma predeterminado, puede establecer la opción `routing.mode` en `"prefix-all"` en su configuración. Consulte la [documentación de configuración](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/configuration.md) para obtener más información.
|
|
662
660
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
```bash packageManager="npm"
|
|
666
|
-
npm install preact-iso
|
|
667
|
-
npx intlayer init
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
```bash packageManager="pnpm"
|
|
671
|
-
pnpm add preact-iso
|
|
672
|
-
pnpm intlayer init
|
|
673
|
-
```
|
|
674
|
-
|
|
675
|
-
```bash packageManager="yarn"
|
|
676
|
-
yarn add preact-iso
|
|
677
|
-
```
|
|
661
|
+
Para agregar enrutamiento localizado a su aplicación, puede crear un componente `LocaleRouter` que envuelva las rutas de su aplicación y maneje el enrutamiento basado en el idioma. Aquí hay un ejemplo usando [preact-iso](https://github.com/preactjs/preact-iso):
|
|
678
662
|
|
|
679
663
|
```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
|
|
680
|
-
import {
|
|
681
|
-
import { ComponentChildren, FunctionalComponent } from "preact";
|
|
664
|
+
import { localeMap } from "intlayer";
|
|
682
665
|
import { IntlayerProvider } from "preact-intlayer";
|
|
683
|
-
import { LocationProvider,
|
|
684
|
-
import {
|
|
685
|
-
|
|
686
|
-
const { internationalization, middleware } = configuration;
|
|
687
|
-
const { locales, defaultLocale } = internationalization;
|
|
666
|
+
import { LocationProvider, Router, Route } from "preact-iso";
|
|
667
|
+
import type { ComponentChildren, FunctionalComponent } from "preact";
|
|
688
668
|
|
|
689
|
-
const Navigate: FunctionalComponent<{ to: string; replace?: boolean }> = ({
|
|
690
|
-
to,
|
|
691
|
-
replace,
|
|
692
|
-
}) => {
|
|
693
|
-
const { route } = useLocation();
|
|
694
|
-
useEffect(() => {
|
|
695
|
-
route(to, replace);
|
|
696
|
-
}, [to, replace, route]);
|
|
697
|
-
return null;
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
669
|
/**
|
|
702
|
-
* Un componente
|
|
703
|
-
* Gestiona la detección y validación de la configuración regional basada en la URL.
|
|
704
|
-
*/
|
|
705
|
-
const AppLocalized: FunctionalComponent<{
|
|
706
|
-
children: ComponentChildren;
|
|
707
|
-
locale?: Locales;
|
|
708
|
-
}> = ({ children, locale }) => {
|
|
709
|
-
const { path: pathname, url } = useLocation();
|
|
710
|
-
|
|
711
|
-
if (!url) {
|
|
712
|
-
return null;
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
const search = url.substring(pathname.length);
|
|
716
|
-
|
|
717
|
-
// Determina la configuración regional actual, usando la predeterminada si no se proporciona
|
|
718
|
-
const currentLocale = locale ?? defaultLocale;
|
|
719
|
-
|
|
720
|
-
// Elimina el prefijo de la configuración regional del path para construir una ruta base
|
|
721
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
722
|
-
pathname // Ruta URL actual
|
|
723
|
-
);
|
|
724
|
-
|
|
725
|
-
/**
|
|
726
|
-
* Si middleware.prefixDefault es verdadero, el locale por defecto siempre debe tener prefijo.
|
|
727
|
-
*/
|
|
728
|
-
if (middleware.prefixDefault) {
|
|
729
|
-
// Validar el locale
|
|
730
|
-
if (!locale || !locales.includes(locale)) {
|
|
731
|
-
// Redirigir al locale por defecto con la ruta actualizada
|
|
732
|
-
return (
|
|
733
|
-
<Navigate
|
|
734
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
735
|
-
replace // Reemplazar la entrada actual del historial con la nueva
|
|
736
|
-
/>
|
|
737
|
-
);
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
// Envolver los children con IntlayerProvider y establecer el locale actual
|
|
741
|
-
return (
|
|
742
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
743
|
-
);
|
|
744
|
-
} else {
|
|
745
|
-
/**
|
|
746
|
-
* Cuando middleware.prefixDefault es falso, el locale por defecto no tiene prefijo.
|
|
747
|
-
* Asegúrese de que la configuración regional actual sea válida y no sea la configuración regional predeterminada.
|
|
748
|
-
*/
|
|
749
|
-
if (
|
|
750
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
751
|
-
!locales
|
|
752
|
-
.filter(
|
|
753
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Excluir la configuración regional predeterminada
|
|
754
|
-
)
|
|
755
|
-
.includes(currentLocale) // Verificar si la configuración regional actual está en la lista de configuraciones regionales válidas
|
|
756
|
-
) {
|
|
757
|
-
// Redirigir a la ruta sin el prefijo de configuración regional
|
|
758
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
// Envolver los hijos con IntlayerProvider y establecer la configuración regional actual
|
|
762
|
-
return (
|
|
763
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
764
|
-
);
|
|
765
|
-
}
|
|
766
|
-
};
|
|
767
|
-
|
|
768
|
-
const RouterContent: FunctionalComponent<{
|
|
769
|
-
children: ComponentChildren;
|
|
770
|
-
}> = ({ children }) => {
|
|
771
|
-
const { path } = useLocation();
|
|
772
|
-
|
|
773
|
-
if (!path) {
|
|
774
|
-
return null;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
const pathLocale = path.split("/")[1] as Locales;
|
|
778
|
-
|
|
779
|
-
const isLocaleRoute = locales
|
|
780
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
781
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
782
|
-
|
|
783
|
-
if (isLocaleRoute) {
|
|
784
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
return (
|
|
788
|
-
<AppLocalized
|
|
789
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
790
|
-
>
|
|
791
|
-
{children}
|
|
792
|
-
</AppLocalized>
|
|
793
|
-
);
|
|
794
|
-
};
|
|
795
|
-
|
|
796
|
-
/**
|
|
797
|
-
* Un componente de enrutador que configura rutas específicas por locale.
|
|
670
|
+
* Un componente de enrutador que configura rutas específicas para cada idioma.
|
|
798
671
|
* Utiliza preact-iso para gestionar la navegación y renderizar componentes localizados.
|
|
799
672
|
*/
|
|
800
673
|
export const LocaleRouter: FunctionalComponent<{
|
|
801
674
|
children: ComponentChildren;
|
|
802
675
|
}> = ({ children }) => (
|
|
803
676
|
<LocationProvider>
|
|
804
|
-
<
|
|
677
|
+
<Router>
|
|
678
|
+
{localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
679
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
680
|
+
.map(({ locale, urlPrefix }) => (
|
|
681
|
+
<Route
|
|
682
|
+
key={locale}
|
|
683
|
+
path={`${urlPrefix}/:rest*`}
|
|
684
|
+
component={() => (
|
|
685
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
686
|
+
)}
|
|
687
|
+
/>
|
|
688
|
+
))}
|
|
689
|
+
</Router>
|
|
805
690
|
</LocationProvider>
|
|
806
691
|
);
|
|
807
692
|
```
|
|
808
693
|
|
|
809
694
|
```jsx fileName="src/components/LocaleRouter.jsx" codeFormat="esm"
|
|
810
|
-
|
|
811
|
-
import { configuration, getPathWithoutLocale } from "intlayer";
|
|
695
|
+
import { localeMap } from "intlayer";
|
|
812
696
|
import { IntlayerProvider } from "preact-intlayer";
|
|
813
|
-
import { LocationProvider,
|
|
814
|
-
import { useEffect } from "preact/hooks";
|
|
815
|
-
import { h } from "preact"; // Requerido para JSX
|
|
816
|
-
|
|
817
|
-
// Desestructurando la configuración de Intlayer
|
|
818
|
-
const { internationalization, middleware } = configuration;
|
|
819
|
-
const { locales, defaultLocale } = internationalization;
|
|
820
|
-
|
|
821
|
-
const Navigate = ({ to, replace }) => {
|
|
822
|
-
const { route } = useLocation();
|
|
823
|
-
useEffect(() => {
|
|
824
|
-
route(to, replace);
|
|
825
|
-
}, [to, replace, route]);
|
|
826
|
-
return null;
|
|
827
|
-
};
|
|
697
|
+
import { LocationProvider, Router, Route } from "preact-iso";
|
|
828
698
|
|
|
829
699
|
/**
|
|
830
|
-
* Un componente
|
|
831
|
-
* Gestiona la detección y validación del idioma basado en la URL.
|
|
832
|
-
*/
|
|
833
|
-
const AppLocalized = ({ children, locale }) => {
|
|
834
|
-
const { path: pathname, url } = useLocation();
|
|
835
|
-
|
|
836
|
-
if (!url) {
|
|
837
|
-
return null;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
const search = url.substring(pathname.length);
|
|
841
|
-
|
|
842
|
-
// Determina el idioma actual, usando el predeterminado si no se proporciona
|
|
843
|
-
const currentLocale = locale ?? defaultLocale;
|
|
844
|
-
|
|
845
|
-
// Elimina el prefijo del idioma de la ruta para construir una ruta base
|
|
846
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
847
|
-
pathname // Ruta actual de la URL
|
|
848
|
-
);
|
|
849
|
-
|
|
850
|
-
/**
|
|
851
|
-
* Si middleware.prefixDefault es true, el idioma predeterminado siempre debe tener prefijo.
|
|
852
|
-
*/
|
|
853
|
-
if (middleware.prefixDefault) {
|
|
854
|
-
// Validar la localización
|
|
855
|
-
if (!locale || !locales.includes(locale)) {
|
|
856
|
-
// Redirigir a la localización por defecto con la ruta actualizada
|
|
857
|
-
return (
|
|
858
|
-
<Navigate
|
|
859
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
860
|
-
replace // Reemplazar la entrada actual del historial con la nueva
|
|
861
|
-
/>
|
|
862
|
-
);
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
// Envolver los hijos con IntlayerProvider y establecer la localización actual
|
|
866
|
-
return (
|
|
867
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
868
|
-
);
|
|
869
|
-
} else {
|
|
870
|
-
/**
|
|
871
|
-
* Cuando middleware.prefixDefault es falso, la localización por defecto no se antepone.
|
|
872
|
-
* Asegurarse de que la localización actual sea válida y no la localización por defecto.
|
|
873
|
-
*/
|
|
874
|
-
if (
|
|
875
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
876
|
-
!locales
|
|
877
|
-
.filter(
|
|
878
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Excluir la configuración regional predeterminada
|
|
879
|
-
)
|
|
880
|
-
.includes(currentLocale) // Verificar si la configuración regional actual está en la lista de configuraciones regionales válidas
|
|
881
|
-
) {
|
|
882
|
-
// Redirigir a la ruta sin el prefijo de configuración regional
|
|
883
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
// Envolver los hijos con IntlayerProvider y establecer la configuración regional actual
|
|
887
|
-
return (
|
|
888
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
889
|
-
);
|
|
890
|
-
}
|
|
891
|
-
};
|
|
892
|
-
|
|
893
|
-
const RouterContent = ({ children }) => {
|
|
894
|
-
const { path } = useLocation();
|
|
895
|
-
|
|
896
|
-
if (!path) {
|
|
897
|
-
return null;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
const pathLocale = path.split("/")[1];
|
|
901
|
-
|
|
902
|
-
const isLocaleRoute = locales
|
|
903
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
904
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
905
|
-
|
|
906
|
-
if (isLocaleRoute) {
|
|
907
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
return (
|
|
911
|
-
<AppLocalized
|
|
912
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
913
|
-
>
|
|
914
|
-
{children}
|
|
915
|
-
</AppLocalized>
|
|
916
|
-
);
|
|
917
|
-
};
|
|
918
|
-
|
|
919
|
-
/**
|
|
920
|
-
* Un componente de enrutador que configura rutas específicas por locale.
|
|
700
|
+
* Un componente de enrutador que configura rutas específicas para cada idioma.
|
|
921
701
|
* Utiliza preact-iso para gestionar la navegación y renderizar componentes localizados.
|
|
922
702
|
*/
|
|
923
703
|
export const LocaleRouter = ({ children }) => (
|
|
924
704
|
<LocationProvider>
|
|
925
|
-
<
|
|
705
|
+
<Router>
|
|
706
|
+
{localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
707
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
708
|
+
.map(({ locale, urlPrefix }) => (
|
|
709
|
+
<Route
|
|
710
|
+
key={locale}
|
|
711
|
+
path={`${urlPrefix}/:rest*`}
|
|
712
|
+
component={() => (
|
|
713
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
714
|
+
)}
|
|
715
|
+
/>
|
|
716
|
+
))}
|
|
717
|
+
</Router>
|
|
926
718
|
</LocationProvider>
|
|
927
719
|
);
|
|
928
720
|
```
|
|
929
721
|
|
|
930
722
|
```jsx fileName="src/components/LocaleRouter.cjsx" codeFormat="commonjs"
|
|
931
|
-
|
|
932
|
-
const { configuration, getPathWithoutLocale } = require("intlayer");
|
|
723
|
+
const { localeMap } = require("intlayer");
|
|
933
724
|
const { IntlayerProvider } = require("preact-intlayer");
|
|
934
|
-
const { LocationProvider,
|
|
935
|
-
const { useEffect } = require("preact/hooks");
|
|
936
|
-
const { h } = require("preact"); // Requerido para JSX
|
|
937
|
-
|
|
938
|
-
// Desestructurando configuración de Intlayer
|
|
939
|
-
const { internationalization, middleware } = configuration;
|
|
940
|
-
const { locales, defaultLocale } = internationalization;
|
|
941
|
-
|
|
942
|
-
const Navigate = ({ to, replace }) => {
|
|
943
|
-
const { route } = useLocation();
|
|
944
|
-
useEffect(() => {
|
|
945
|
-
route(to, replace);
|
|
946
|
-
}, [to, replace, route]);
|
|
947
|
-
return null;
|
|
948
|
-
};
|
|
725
|
+
const { LocationProvider, Router, Route } = require("preact-iso");
|
|
949
726
|
|
|
950
727
|
/**
|
|
951
|
-
* Un componente
|
|
952
|
-
*
|
|
728
|
+
* Un componente de enrutador que configura rutas específicas para cada idioma.
|
|
729
|
+
* Utiliza preact-iso para gestionar la navegación y renderizar componentes localizados.
|
|
953
730
|
*/
|
|
954
|
-
const
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
);
|
|
970
|
-
|
|
971
|
-
/**
|
|
972
|
-
* Si middleware.prefixDefault es true, la configuración regional predeterminada siempre debe tener prefijo.
|
|
973
|
-
*/
|
|
974
|
-
if (middleware.prefixDefault) {
|
|
975
|
-
// Validar la configuración regional
|
|
976
|
-
if (!locale || !locales.includes(locale)) {
|
|
977
|
-
// Redirigir a la configuración regional predeterminada con la ruta actualizada
|
|
978
|
-
return (
|
|
979
|
-
<Navigate
|
|
980
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
981
|
-
replace // Reemplaza la entrada actual del historial con la nueva
|
|
982
|
-
/>
|
|
983
|
-
);
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
// Envuelve los hijos con IntlayerProvider y establece la localidad actual
|
|
987
|
-
return (
|
|
988
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
989
|
-
);
|
|
990
|
-
} else {
|
|
991
|
-
/**
|
|
992
|
-
* Cuando middleware.prefixDefault es falso, la localidad por defecto no se antepone.
|
|
993
|
-
* Asegúrate de que la localidad actual sea válida y no la localidad por defecto.
|
|
994
|
-
*/
|
|
995
|
-
if (
|
|
996
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
997
|
-
!locales
|
|
998
|
-
.filter(
|
|
999
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Excluir la localidad por defecto
|
|
731
|
+
const LocaleRouter = ({ children }) =>
|
|
732
|
+
h(
|
|
733
|
+
LocationProvider,
|
|
734
|
+
{},
|
|
735
|
+
h(
|
|
736
|
+
Router,
|
|
737
|
+
{},
|
|
738
|
+
localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
739
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
740
|
+
.map(({ locale, urlPrefix }) =>
|
|
741
|
+
h(Route, {
|
|
742
|
+
key: locale,
|
|
743
|
+
path: `${urlPrefix}/:rest*`,
|
|
744
|
+
component: () => h(IntlayerProvider, { locale }, children),
|
|
745
|
+
})
|
|
1000
746
|
)
|
|
1001
|
-
|
|
1002
|
-
) {
|
|
1003
|
-
// Redirige a la ruta sin el prefijo de localidad
|
|
1004
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
// Envuelve los hijos con IntlayerProvider y establece la localidad actual
|
|
1008
|
-
return (
|
|
1009
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
1010
|
-
);
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1013
|
-
|
|
1014
|
-
const RouterContent = ({ children }) => {
|
|
1015
|
-
const { path } = useLocation();
|
|
1016
|
-
|
|
1017
|
-
if (!path) {
|
|
1018
|
-
return null;
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
const pathLocale = path.split("/")[1];
|
|
1022
|
-
|
|
1023
|
-
const isLocaleRoute = locales
|
|
1024
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
1025
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
1026
|
-
|
|
1027
|
-
if (isLocaleRoute) {
|
|
1028
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
return (
|
|
1032
|
-
<AppLocalized
|
|
1033
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
1034
|
-
>
|
|
1035
|
-
{children}
|
|
1036
|
-
</AppLocalized>
|
|
747
|
+
)
|
|
1037
748
|
);
|
|
1038
|
-
};
|
|
1039
|
-
|
|
1040
|
-
/**
|
|
1041
|
-
* Un componente de enrutador que configura rutas específicas por idioma.
|
|
1042
|
-
* Utiliza preact-iso para gestionar la navegación y renderizar componentes localizados.
|
|
1043
|
-
*/
|
|
1044
|
-
const LocaleRouter = ({ children }) => (
|
|
1045
|
-
<LocationProvider>
|
|
1046
|
-
<RouterContent>{children}</RouterContent>
|
|
1047
|
-
</LocationProvider>
|
|
1048
|
-
);
|
|
1049
749
|
|
|
1050
750
|
module.exports = { LocaleRouter };
|
|
1051
751
|
```
|
|
1052
752
|
|
|
1053
|
-
Luego,
|
|
753
|
+
Luego, puede usar el componente `LocaleRouter` en su aplicación:
|
|
1054
754
|
|
|
1055
755
|
```tsx fileName="src/app.tsx" codeFormat="typescript"
|
|
1056
756
|
import { LocaleRouter } from "./components/LocaleRouter";
|
|
1057
757
|
import type { FunctionalComponent } from "preact";
|
|
1058
|
-
|
|
758
|
+
|
|
759
|
+
// ... Su componente AppContent
|
|
1059
760
|
|
|
1060
761
|
const App: FunctionalComponent = () => (
|
|
1061
762
|
<LocaleRouter>
|
|
@@ -1068,7 +769,8 @@ export default App;
|
|
|
1068
769
|
|
|
1069
770
|
```jsx fileName="src/app.jsx" codeFormat="esm"
|
|
1070
771
|
import { LocaleRouter } from "./components/LocaleRouter";
|
|
1071
|
-
|
|
772
|
+
|
|
773
|
+
// ... Su componente AppContent
|
|
1072
774
|
|
|
1073
775
|
const App = () => (
|
|
1074
776
|
<LocaleRouter>
|
|
@@ -1081,7 +783,8 @@ export default App;
|
|
|
1081
783
|
|
|
1082
784
|
```jsx fileName="src/app.cjsx" codeFormat="commonjs"
|
|
1083
785
|
const { LocaleRouter } = require("./components/LocaleRouter");
|
|
1084
|
-
|
|
786
|
+
|
|
787
|
+
// ... Su componente AppContent
|
|
1085
788
|
|
|
1086
789
|
const App = () => (
|
|
1087
790
|
<LocaleRouter>
|
|
@@ -1092,47 +795,12 @@ const App = () => (
|
|
|
1092
795
|
module.exports = App;
|
|
1093
796
|
```
|
|
1094
797
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
1098
|
-
import { defineConfig } from "vite";
|
|
1099
|
-
import preact from "@preact/preset-vite";
|
|
1100
|
-
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1101
|
-
|
|
1102
|
-
// https://vitejs.dev/config/
|
|
1103
|
-
export default defineConfig({
|
|
1104
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1105
|
-
});
|
|
1106
|
-
```
|
|
1107
|
-
|
|
1108
|
-
```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
|
|
1109
|
-
import { defineConfig } from "vite";
|
|
1110
|
-
import preact from "@preact/preset-vite";
|
|
1111
|
-
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1112
|
-
|
|
1113
|
-
// https://vitejs.dev/config/
|
|
1114
|
-
export default defineConfig({
|
|
1115
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1116
|
-
});
|
|
1117
|
-
```
|
|
1118
|
-
|
|
1119
|
-
```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
|
|
1120
|
-
const { defineConfig } = require("vite");
|
|
1121
|
-
const preact = require("@preact/preset-vite");
|
|
1122
|
-
const { intlayer, intlayerProxy } = require("vite-intlayer");
|
|
1123
|
-
|
|
1124
|
-
// https://vitejs.dev/config/
|
|
1125
|
-
module.exports = defineConfig({
|
|
1126
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1127
|
-
});
|
|
1128
|
-
```
|
|
1129
|
-
|
|
1130
|
-
### (Opcional) Paso 8: Cambiar la URL cuando cambia la configuración regional
|
|
798
|
+
### (Opcional) Paso 8: Cambiar la URL cuando cambia el idioma
|
|
1131
799
|
|
|
1132
|
-
Para cambiar la URL cuando cambia
|
|
800
|
+
Para cambiar la URL cuando cambia el idioma, puede usar la propiedad `onLocaleChange` proporcionada por el hook `useLocale`. Paralelamente, puede usar el método `route` de `useLocation` de `preact-iso` para actualizar la ruta de la URL.
|
|
1133
801
|
|
|
1134
802
|
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
|
|
1135
|
-
import { useLocation
|
|
803
|
+
import { useLocation } from "preact-iso";
|
|
1136
804
|
import {
|
|
1137
805
|
Locales,
|
|
1138
806
|
getHTMLTextDir,
|
|
@@ -1143,13 +811,12 @@ import { useLocale } from "preact-intlayer";
|
|
|
1143
811
|
import type { FunctionalComponent } from "preact";
|
|
1144
812
|
|
|
1145
813
|
const LocaleSwitcher: FunctionalComponent = () => {
|
|
1146
|
-
const
|
|
814
|
+
const { url, route } = useLocation();
|
|
1147
815
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1148
816
|
onLocaleChange: (newLocale) => {
|
|
1149
|
-
|
|
1150
|
-
// Construir la URL con la configuración regional actualizada
|
|
817
|
+
// Construir la URL con el idioma actualizado
|
|
1151
818
|
// Ejemplo: /es/about?foo=bar
|
|
1152
|
-
const pathWithLocale = getLocalizedUrl(
|
|
819
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1153
820
|
|
|
1154
821
|
// Actualizar la ruta de la URL
|
|
1155
822
|
route(pathWithLocale, true); // true para reemplazar
|
|
@@ -1162,7 +829,7 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
1162
829
|
<div id="localePopover" popover="auto">
|
|
1163
830
|
{availableLocales.map((localeItem) => (
|
|
1164
831
|
<a
|
|
1165
|
-
href={getLocalizedUrl(
|
|
832
|
+
href={getLocalizedUrl(url, localeItem)}
|
|
1166
833
|
hreflang={localeItem}
|
|
1167
834
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1168
835
|
onClick={(e) => {
|
|
@@ -1173,19 +840,19 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
1173
840
|
key={localeItem}
|
|
1174
841
|
>
|
|
1175
842
|
<span>
|
|
1176
|
-
{/* Idioma
|
|
843
|
+
{/* Idioma - p.ej. FR */}
|
|
1177
844
|
{localeItem}
|
|
1178
845
|
</span>
|
|
1179
846
|
<span>
|
|
1180
|
-
{/* Idioma en su propio idioma
|
|
847
|
+
{/* Idioma en su propio idioma - p.ej. Français */}
|
|
1181
848
|
{getLocaleName(localeItem, localeItem)}
|
|
1182
849
|
</span>
|
|
1183
850
|
<span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
|
|
1184
|
-
{/* Idioma en el idioma
|
|
851
|
+
{/* Idioma en el idioma actual - p.ej. Francés con el idioma actual establecido en Locales.SPANISH */}
|
|
1185
852
|
{getLocaleName(localeItem, locale)}
|
|
1186
853
|
</span>
|
|
1187
854
|
<span dir="ltr" lang={Locales.ENGLISH}>
|
|
1188
|
-
{/* Idioma en inglés -
|
|
855
|
+
{/* Idioma en inglés - p.ej. French */}
|
|
1189
856
|
{getLocaleName(localeItem, Locales.ENGLISH)}
|
|
1190
857
|
</span>
|
|
1191
858
|
</a>
|
|
@@ -1199,7 +866,7 @@ export default LocaleSwitcher;
|
|
|
1199
866
|
```
|
|
1200
867
|
|
|
1201
868
|
```jsx fileName="src/components/LocaleSwitcher.jsx" codeFormat="esm"
|
|
1202
|
-
import { useLocation
|
|
869
|
+
import { useLocation } from "preact-iso";
|
|
1203
870
|
import {
|
|
1204
871
|
Locales,
|
|
1205
872
|
getHTMLTextDir,
|
|
@@ -1207,14 +874,12 @@ import {
|
|
|
1207
874
|
getLocalizedUrl,
|
|
1208
875
|
} from "intlayer";
|
|
1209
876
|
import { useLocale } from "preact-intlayer";
|
|
1210
|
-
import { h } from "preact"; // Para JSX
|
|
1211
877
|
|
|
1212
878
|
const LocaleSwitcher = () => {
|
|
1213
|
-
const
|
|
879
|
+
const { url, route } = useLocation();
|
|
1214
880
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1215
881
|
onLocaleChange: (newLocale) => {
|
|
1216
|
-
const
|
|
1217
|
-
const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
|
|
882
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1218
883
|
route(pathWithLocale, true);
|
|
1219
884
|
},
|
|
1220
885
|
});
|
|
@@ -1225,7 +890,7 @@ const LocaleSwitcher = () => {
|
|
|
1225
890
|
<div id="localePopover" popover="auto">
|
|
1226
891
|
{availableLocales.map((localeItem) => (
|
|
1227
892
|
<a
|
|
1228
|
-
href={getLocalizedUrl(
|
|
893
|
+
href={getLocalizedUrl(url, localeItem)}
|
|
1229
894
|
hreflang={localeItem}
|
|
1230
895
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1231
896
|
onClick={(e) => {
|
|
@@ -1253,7 +918,7 @@ export default LocaleSwitcher;
|
|
|
1253
918
|
```
|
|
1254
919
|
|
|
1255
920
|
```jsx fileName="src/components/LocaleSwitcher.cjsx" codeFormat="commonjs"
|
|
1256
|
-
const { useLocation
|
|
921
|
+
const { useLocation } = require("preact-iso");
|
|
1257
922
|
const {
|
|
1258
923
|
Locales,
|
|
1259
924
|
getHTMLTextDir,
|
|
@@ -1261,80 +926,74 @@ const {
|
|
|
1261
926
|
getLocalizedUrl,
|
|
1262
927
|
} = require("intlayer");
|
|
1263
928
|
const { useLocale } = require("preact-intlayer");
|
|
1264
|
-
const { h } = require("preact"); // Para JSX
|
|
1265
929
|
|
|
1266
930
|
const LocaleSwitcher = () => {
|
|
1267
|
-
const
|
|
931
|
+
const { url, route } = useLocation();
|
|
1268
932
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1269
933
|
onLocaleChange: (newLocale) => {
|
|
1270
|
-
const
|
|
1271
|
-
const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
|
|
934
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1272
935
|
route(pathWithLocale, true);
|
|
1273
936
|
},
|
|
1274
937
|
});
|
|
1275
938
|
|
|
1276
|
-
return (
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
939
|
+
return h(
|
|
940
|
+
"div",
|
|
941
|
+
{},
|
|
942
|
+
h("button", { popovertarget: "localePopover" }, getLocaleName(locale)),
|
|
943
|
+
h(
|
|
944
|
+
"div",
|
|
945
|
+
{ id: "localePopover", popover: "auto" },
|
|
946
|
+
availableLocales.map((localeItem) =>
|
|
947
|
+
h(
|
|
948
|
+
"a",
|
|
949
|
+
{
|
|
950
|
+
href: getLocalizedUrl(url, localeItem),
|
|
951
|
+
hreflang: localeItem,
|
|
952
|
+
"aria-current": locale === localeItem ? "page" : undefined,
|
|
953
|
+
onClick: (e) => {
|
|
1286
954
|
e.preventDefault();
|
|
1287
955
|
setLocale(localeItem);
|
|
1288
|
-
}
|
|
1289
|
-
key
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
956
|
+
},
|
|
957
|
+
key: localeItem,
|
|
958
|
+
},
|
|
959
|
+
h("span", {}, localeItem),
|
|
960
|
+
h("span", {}, getLocaleName(localeItem, localeItem)),
|
|
961
|
+
h(
|
|
962
|
+
"span",
|
|
963
|
+
{ dir: getHTMLTextDir(localeItem), lang: localeItem },
|
|
964
|
+
getLocaleName(localeItem, locale)
|
|
965
|
+
),
|
|
966
|
+
h(
|
|
967
|
+
"span",
|
|
968
|
+
{ dir: "ltr", lang: Locales.ENGLISH },
|
|
969
|
+
getLocaleName(localeItem, Locales.ENGLISH)
|
|
970
|
+
)
|
|
971
|
+
)
|
|
972
|
+
)
|
|
973
|
+
)
|
|
1303
974
|
);
|
|
1304
975
|
};
|
|
1305
976
|
|
|
1306
977
|
module.exports = LocaleSwitcher;
|
|
1307
978
|
```
|
|
1308
979
|
|
|
1309
|
-
> Referencias de documentación:
|
|
980
|
+
> Referencias de la documentación:
|
|
1310
981
|
>
|
|
1311
|
-
> > - [`useLocale`
|
|
1312
|
-
> > - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getLocaleName.md)
|
|
1313
|
-
> > - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getLocalizedUrl.md)
|
|
1314
|
-
> > - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getHTMLTextDir.md)
|
|
1315
|
-
> > - [atributo `hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
|
|
1316
|
-
> > - [atributo `lang`](https://developer.mozilla.org/es/docs/Web/HTML/Atributos_globales/lang)
|
|
1317
|
-
> > - [atributo `dir`](https://developer.mozilla.org/es/docs/Web/HTML/Atributos_globales/dir)
|
|
1318
|
-
> > - [atributo `aria-current`](https://developer.mozilla.org/es/docs/Web/Accessibility/ARIA/Atributos/aria-current)
|
|
1319
|
-
> > - [API Popover](https://developer.mozilla.org/es/docs/Web/API/Popover_API) la.org/en-US/docs/Web/HTML/Global_attributes/dir)> - [atributo `aria-current`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [API Popover](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
|
|
1320
|
-
|
|
1321
|
-
A continuación se muestra el **Paso 9** actualizado con explicaciones adicionales y ejemplos de código refinados:
|
|
1322
|
-
|
|
1323
|
-
---
|
|
982
|
+
> > - [Hook `useLocale`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/react-intlayer/useLocale.md) (la API es similar para `preact-intlayer`)> - [Hook `getLocaleName`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getLocaleName.md)> - [Hook `getLocalizedUrl`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getLocalizedUrl.md)> - [Hook `getHTMLTextDir`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/packages/intlayer/getHTMLTextDir.md)> - [Atributo `hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)> - [Atributo `lang`](https://developer.mozilla.org/es/docs/Web/HTML/Global_attributes/lang)> - [Atributo `dir`](https://developer.mozilla.org/es/docs/Web/HTML/Global_attributes/dir)> - [Atributo `aria-current`](https://developer.mozilla.org/es/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [API Popover](https://developer.mozilla.org/es/docs/Web/API/Popover_API)
|
|
1324
983
|
|
|
1325
984
|
### (Opcional) Paso 9: Cambiar los atributos de idioma y dirección del HTML
|
|
1326
985
|
|
|
1327
|
-
Cuando
|
|
986
|
+
Cuando su aplicación soporta varios idiomas, es fundamental actualizar los atributos `lang` y `dir` de la etiqueta `<html>` para que coincidan con el idioma actual. Al hacerlo, se garantiza:
|
|
1328
987
|
|
|
1329
|
-
- **Accesibilidad**: Los lectores de pantalla y tecnologías de asistencia dependen del atributo `lang` correcto para pronunciar e interpretar el contenido con precisión.
|
|
1330
|
-
- **Renderizado de texto**: El atributo `dir` (dirección)
|
|
1331
|
-
- **SEO**: Los motores de búsqueda utilizan el atributo `lang` para determinar el idioma de su página,
|
|
988
|
+
- **Accesibilidad**: Los lectores de pantalla y las tecnologías de asistencia dependen del atributo `lang` correcto para pronunciar e interpretar el contenido con precisión.
|
|
989
|
+
- **Renderizado de texto**: El atributo `dir` (dirección) garantiza que el texto se represente en el orden adecuado (p. ej., de izquierda a derecha para el inglés, de derecha a izquierda para el árabe o el hebreo), lo cual es esencial para la legibilidad.
|
|
990
|
+
- **SEO**: Los motores de búsqueda utilizan el atributo `lang` para determinar el idioma de su página, lo que ayuda a ofrecer el contenido localizado adecuado en los resultados de búsqueda.
|
|
1332
991
|
|
|
1333
|
-
Al actualizar estos atributos dinámicamente cuando cambia
|
|
992
|
+
Al actualizar estos atributos dinámicamente cuando cambia el idioma, garantiza una experiencia coherente y accesible para los usuarios en todos los idiomas admitidos.
|
|
1334
993
|
|
|
1335
994
|
#### Implementación del Hook
|
|
1336
995
|
|
|
1337
|
-
Cree un hook personalizado para gestionar los atributos HTML. El hook escucha los cambios de
|
|
996
|
+
Cree un hook personalizado para gestionar los atributos HTML. El hook escucha los cambios de idioma y actualiza los atributos en consecuencia:
|
|
1338
997
|
|
|
1339
998
|
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat="typescript"
|
|
1340
999
|
import { useEffect } from "preact/hooks";
|
|
@@ -1342,20 +1001,20 @@ import { useLocale } from "preact-intlayer";
|
|
|
1342
1001
|
import { getHTMLTextDir } from "intlayer";
|
|
1343
1002
|
|
|
1344
1003
|
/**
|
|
1345
|
-
* Actualiza los atributos `lang` y `dir` del elemento <html> según
|
|
1004
|
+
* Actualiza los atributos `lang` y `dir` del elemento HTML <html> según el idioma actual.
|
|
1346
1005
|
* - `lang`: Informa a los navegadores y motores de búsqueda sobre el idioma de la página.
|
|
1347
|
-
* - `dir`: Asegura el orden
|
|
1006
|
+
* - `dir`: Asegura el orden de lectura correcto (p. ej., 'ltr' para el inglés, 'rtl' para el árabe).
|
|
1348
1007
|
*
|
|
1349
|
-
* Esta actualización dinámica es esencial para
|
|
1008
|
+
* Esta actualización dinámica es esencial para el renderizado correcto del texto, la accesibilidad y el SEO.
|
|
1350
1009
|
*/
|
|
1351
1010
|
export const useI18nHTMLAttributes = () => {
|
|
1352
1011
|
const { locale } = useLocale();
|
|
1353
1012
|
|
|
1354
1013
|
useEffect(() => {
|
|
1355
|
-
//
|
|
1014
|
+
// Actualizar el atributo de idioma al idioma actual.
|
|
1356
1015
|
document.documentElement.lang = locale;
|
|
1357
1016
|
|
|
1358
|
-
//
|
|
1017
|
+
// Establecer la dirección del texto según el idioma actual.
|
|
1359
1018
|
document.documentElement.dir = getHTMLTextDir(locale);
|
|
1360
1019
|
}, [locale]);
|
|
1361
1020
|
};
|
|
@@ -1367,7 +1026,7 @@ import { useLocale } from "preact-intlayer";
|
|
|
1367
1026
|
import { getHTMLTextDir } from "intlayer";
|
|
1368
1027
|
|
|
1369
1028
|
/**
|
|
1370
|
-
* Actualiza los atributos `lang` y `dir` del elemento HTML <html> según
|
|
1029
|
+
* Actualiza los atributos `lang` y `dir` del elemento HTML <html> según el idioma actual.
|
|
1371
1030
|
*/
|
|
1372
1031
|
export const useI18nHTMLAttributes = () => {
|
|
1373
1032
|
const { locale } = useLocale();
|
|
@@ -1385,7 +1044,7 @@ const { useLocale } = require("preact-intlayer");
|
|
|
1385
1044
|
const { getHTMLTextDir } = require("intlayer");
|
|
1386
1045
|
|
|
1387
1046
|
/**
|
|
1388
|
-
* Actualiza los atributos `lang` y `dir` del elemento HTML <html> según
|
|
1047
|
+
* Actualiza los atributos `lang` y `dir` del elemento HTML <html> según el idioma actual.
|
|
1389
1048
|
*/
|
|
1390
1049
|
const useI18nHTMLAttributes = () => {
|
|
1391
1050
|
const { locale } = useLocale();
|
|
@@ -1399,9 +1058,9 @@ const useI18nHTMLAttributes = () => {
|
|
|
1399
1058
|
module.exports = { useI18nHTMLAttributes };
|
|
1400
1059
|
```
|
|
1401
1060
|
|
|
1402
|
-
#### Uso del Hook en
|
|
1061
|
+
#### Uso del Hook en su Aplicación
|
|
1403
1062
|
|
|
1404
|
-
|
|
1063
|
+
Integre el hook en su componente principal para que los atributos HTML se actualicen cada vez que cambie el idioma:
|
|
1405
1064
|
|
|
1406
1065
|
```tsx fileName="src/app.tsx" codeFormat="typescript"
|
|
1407
1066
|
import type { FunctionalComponent } from "preact";
|
|
@@ -1411,10 +1070,10 @@ import "./app.css";
|
|
|
1411
1070
|
// Definición de AppContent del Paso 5
|
|
1412
1071
|
|
|
1413
1072
|
const AppWithHooks: FunctionalComponent = () => {
|
|
1414
|
-
// Aplicar el hook para actualizar los atributos lang y dir de la etiqueta <html> según
|
|
1073
|
+
// Aplicar el hook para actualizar los atributos lang y dir de la etiqueta <html> según el idioma.
|
|
1415
1074
|
useI18nHTMLAttributes();
|
|
1416
1075
|
|
|
1417
|
-
// Suponiendo que AppContent es
|
|
1076
|
+
// Suponiendo que AppContent es su componente principal de visualización de contenido del Paso 5
|
|
1418
1077
|
return <AppContent />;
|
|
1419
1078
|
};
|
|
1420
1079
|
|
|
@@ -1467,215 +1126,192 @@ const App = () => (
|
|
|
1467
1126
|
module.exports = App;
|
|
1468
1127
|
```
|
|
1469
1128
|
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
- Asegurará que el atributo de **idioma** (`lang`) refleje correctamente la configuración regional actual, lo cual es importante para el SEO y el comportamiento del navegador.
|
|
1473
|
-
- Ajustará la **dirección del texto** (`dir`) según la configuración regional, mejorando la legibilidad y usabilidad para idiomas con diferentes órdenes de lectura.
|
|
1474
|
-
- Proporcionar una experiencia más **accesible**, ya que las tecnologías de asistencia dependen de estos atributos para funcionar de manera óptima.
|
|
1129
|
+
### (Opcional) Paso 10: Crear un Componente de Enlace Localizado
|
|
1475
1130
|
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
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.
|
|
1131
|
+
Para garantizar que la navegación de su aplicación respete el idioma actual, puede crear un componente `Link` personalizado. Este componente añade automáticamente el prefijo del idioma actual a las URL internas.
|
|
1479
1132
|
|
|
1480
1133
|
Este comportamiento es útil por varias razones:
|
|
1481
1134
|
|
|
1482
|
-
- **SEO y Experiencia
|
|
1483
|
-
- **Consistencia**: Al
|
|
1484
|
-
- **Mantenibilidad**: Centralizar la lógica de localización en un
|
|
1135
|
+
- **SEO y Experiencia del Usuario**: Las URL localizadas ayudan a los motores de búsqueda a indexar correctamente las páginas específicas de un idioma y proporcionan a los usuarios contenido en su idioma preferido.
|
|
1136
|
+
- **Consistencia**: Al utilizar un enlace localizado en toda su aplicación, garantiza que la navegación se mantenga dentro del idioma actual, evitando cambios de idioma inesperados.
|
|
1137
|
+
- **Mantenibilidad**: Centralizar la lógica de localización en un único componente simplifica la gestión de las URL.
|
|
1485
1138
|
|
|
1486
|
-
|
|
1139
|
+
A continuación se muestra la implementación de un componente `Link` localizado en Preact:
|
|
1487
1140
|
|
|
1488
|
-
```tsx fileName="src/components/
|
|
1141
|
+
```tsx fileName="src/components/Link.tsx" codeFormat="typescript"
|
|
1489
1142
|
import { getLocalizedUrl } from "intlayer";
|
|
1490
|
-
import { useLocale
|
|
1491
|
-
|
|
1492
|
-
import type { JSX } from "preact";
|
|
1493
|
-
import { forwardRef } from "preact/compat"; // Para reenviar refs
|
|
1143
|
+
import { useLocale } from "preact-intlayer";
|
|
1144
|
+
import { forwardRef } from "preact/compat";
|
|
1145
|
+
import type { JSX } from "preact";
|
|
1494
1146
|
|
|
1495
|
-
export interface
|
|
1147
|
+
export interface LinkProps extends JSX.HTMLAttributes<HTMLAnchorElement> {
|
|
1496
1148
|
href: string;
|
|
1497
|
-
replace?: boolean; // Opcional: para reemplazar el estado del historial
|
|
1498
1149
|
}
|
|
1499
1150
|
|
|
1500
1151
|
/**
|
|
1501
|
-
* Función
|
|
1152
|
+
* Función de utilidad para comprobar si una URL determinada es externa.
|
|
1502
1153
|
* Si la URL comienza con http:// o https://, se considera externa.
|
|
1503
1154
|
*/
|
|
1504
1155
|
export const checkIsExternalLink = (href?: string): boolean =>
|
|
1505
1156
|
/^https?:\/\//.test(href ?? "");
|
|
1506
1157
|
|
|
1507
1158
|
/**
|
|
1508
|
-
* Un componente Link personalizado que adapta el atributo href según
|
|
1509
|
-
* Para enlaces internos, utiliza `getLocalizedUrl` para
|
|
1510
|
-
* Esto
|
|
1511
|
-
* Utiliza una etiqueta estándar <a> pero puede activar la navegación del lado del cliente usando `route` de preact-iso.
|
|
1159
|
+
* Un componente Link personalizado que adapta el atributo href según el idioma actual.
|
|
1160
|
+
* Para los enlaces internos, utiliza `getLocalizedUrl` para prefijar la URL con el idioma (p. ej., /fr/about).
|
|
1161
|
+
* Esto garantiza que la navegación se mantenga dentro del mismo contexto de idioma.
|
|
1512
1162
|
*/
|
|
1513
|
-
export const
|
|
1514
|
-
({ href, children,
|
|
1163
|
+
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
1164
|
+
({ href, children, ...props }, ref) => {
|
|
1515
1165
|
const { locale } = useLocale();
|
|
1516
|
-
const location = useLocation(); // de preact-iso
|
|
1517
1166
|
const isExternalLink = checkIsExternalLink(href);
|
|
1518
1167
|
|
|
1168
|
+
// Si el enlace es interno y se proporciona un href válido, obtener la URL localizada.
|
|
1519
1169
|
const hrefI18n =
|
|
1520
1170
|
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1521
1171
|
|
|
1522
|
-
const handleClick = (event: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {
|
|
1523
|
-
if (onClick) {
|
|
1524
|
-
onClick(event);
|
|
1525
|
-
}
|
|
1526
|
-
if (
|
|
1527
|
-
!isExternalLink &&
|
|
1528
|
-
href && // Asegura que href esté definido
|
|
1529
|
-
event.button === 0 && // Clic izquierdo
|
|
1530
|
-
!event.metaKey &&
|
|
1531
|
-
!event.ctrlKey &&
|
|
1532
|
-
!event.shiftKey &&
|
|
1533
|
-
!event.altKey && // Verificación estándar de modificadores
|
|
1534
|
-
!props.target // No apunta a una nueva pestaña/ventana
|
|
1535
|
-
) {
|
|
1536
|
-
event.preventDefault();
|
|
1537
|
-
if (location.url !== hrefI18n) {
|
|
1538
|
-
// Navega solo si la URL es diferente
|
|
1539
|
-
route(hrefI18n, replace); // Usa route de preact-iso
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1542
|
-
};
|
|
1543
|
-
|
|
1544
1172
|
return (
|
|
1545
|
-
<a href={hrefI18n} ref={ref}
|
|
1173
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1546
1174
|
{children}
|
|
1547
1175
|
</a>
|
|
1548
1176
|
);
|
|
1549
1177
|
}
|
|
1550
1178
|
);
|
|
1179
|
+
|
|
1180
|
+
Link.displayName = "Link";
|
|
1551
1181
|
```
|
|
1552
1182
|
|
|
1553
|
-
```jsx fileName="src/components/
|
|
1183
|
+
```jsx fileName="src/components/Link.jsx" codeFormat="esm"
|
|
1554
1184
|
import { getLocalizedUrl } from "intlayer";
|
|
1555
1185
|
import { useLocale } from "preact-intlayer";
|
|
1556
|
-
import { useLocation, route } from "preact-iso"; // Importar desde preact-iso
|
|
1557
1186
|
import { forwardRef } from "preact/compat";
|
|
1558
|
-
import { h } from "preact"; // Para JSX
|
|
1559
1187
|
|
|
1188
|
+
/**
|
|
1189
|
+
* Función de utilidad para comprobar si una URL determinada es externa.
|
|
1190
|
+
* Si la URL comienza con http:// o https://, se considera externa.
|
|
1191
|
+
*/
|
|
1560
1192
|
export const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
|
|
1561
1193
|
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1194
|
+
/**
|
|
1195
|
+
* Un componente Link personalizado que adapta el atributo href según el idioma actual.
|
|
1196
|
+
* Para los enlaces internos, utiliza `getLocalizedUrl` para prefijar la URL con el idioma (p. ej., /fr/about).
|
|
1197
|
+
* Esto garantiza que la navegación se mantenga dentro del mismo contexto de idioma.
|
|
1198
|
+
*/
|
|
1199
|
+
export const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1200
|
+
const { locale } = useLocale();
|
|
1201
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1567
1202
|
|
|
1568
|
-
|
|
1569
|
-
|
|
1203
|
+
// Si el enlace es interno y se proporciona un href válido, obtener la URL localizada.
|
|
1204
|
+
const hrefI18n =
|
|
1205
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1570
1206
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
href &&
|
|
1578
|
-
event.button === 0 &&
|
|
1579
|
-
!event.metaKey &&
|
|
1580
|
-
!event.ctrlKey &&
|
|
1581
|
-
!event.shiftKey &&
|
|
1582
|
-
!event.altKey &&
|
|
1583
|
-
!props.target
|
|
1584
|
-
) {
|
|
1585
|
-
event.preventDefault();
|
|
1586
|
-
if (location.url !== hrefI18n) {
|
|
1587
|
-
route(hrefI18n, replace);
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
};
|
|
1207
|
+
return (
|
|
1208
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1209
|
+
{children}
|
|
1210
|
+
</a>
|
|
1211
|
+
);
|
|
1212
|
+
});
|
|
1591
1213
|
|
|
1592
|
-
|
|
1593
|
-
<a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
|
|
1594
|
-
{children}
|
|
1595
|
-
</a>
|
|
1596
|
-
);
|
|
1597
|
-
}
|
|
1598
|
-
);
|
|
1214
|
+
Link.displayName = "Link";
|
|
1599
1215
|
```
|
|
1600
1216
|
|
|
1601
|
-
```jsx fileName="src/components/
|
|
1217
|
+
```jsx fileName="src/components/Link.cjsx" codeFormat="commonjs"
|
|
1602
1218
|
const { getLocalizedUrl } = require("intlayer");
|
|
1603
1219
|
const { useLocale } = require("preact-intlayer");
|
|
1604
|
-
const { useLocation, route } = require("preact-iso"); // Importado desde preact-iso
|
|
1605
1220
|
const { forwardRef } = require("preact/compat");
|
|
1606
|
-
const { h } = require("preact"); // Para JSX
|
|
1607
1221
|
|
|
1222
|
+
/**
|
|
1223
|
+
* Función de utilidad para comprobar si una URL determinada es externa.
|
|
1224
|
+
* Si la URL comienza con http:// o https://, se considera externa.
|
|
1225
|
+
*/
|
|
1608
1226
|
const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
|
|
1609
1227
|
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
!props.target
|
|
1634
|
-
) {
|
|
1635
|
-
event.preventDefault();
|
|
1636
|
-
if (location.url !== hrefI18n) {
|
|
1637
|
-
route(hrefI18n, replace);
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
};
|
|
1228
|
+
/**
|
|
1229
|
+
* Un componente Link personalizado que adapta el atributo href según el idioma actual.
|
|
1230
|
+
* Para los enlaces internos, utiliza `getLocalizedUrl` para prefijar la URL con el idioma (p. ej., /fr/about).
|
|
1231
|
+
* Esto garantiza que la navegación se mantenga dentro del mismo contexto de idioma.
|
|
1232
|
+
*/
|
|
1233
|
+
const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1234
|
+
const { locale } = useLocale();
|
|
1235
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1236
|
+
|
|
1237
|
+
// Si el enlace es interno y se proporciona un href válido, obtener la URL localizada.
|
|
1238
|
+
const hrefI18n =
|
|
1239
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1240
|
+
|
|
1241
|
+
return h(
|
|
1242
|
+
"a",
|
|
1243
|
+
{
|
|
1244
|
+
href: hrefI18n,
|
|
1245
|
+
ref: ref,
|
|
1246
|
+
...props,
|
|
1247
|
+
},
|
|
1248
|
+
children
|
|
1249
|
+
);
|
|
1250
|
+
});
|
|
1641
1251
|
|
|
1642
|
-
|
|
1643
|
-
<a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
|
|
1644
|
-
{children}
|
|
1645
|
-
</a>
|
|
1646
|
-
);
|
|
1647
|
-
}
|
|
1648
|
-
);
|
|
1252
|
+
Link.displayName = "Link";
|
|
1649
1253
|
|
|
1650
|
-
module.exports = {
|
|
1254
|
+
module.exports = { Link, checkIsExternalLink };
|
|
1651
1255
|
```
|
|
1652
1256
|
|
|
1653
1257
|
#### Cómo Funciona
|
|
1654
1258
|
|
|
1655
1259
|
- **Detección de Enlaces Externos**:
|
|
1656
|
-
La función
|
|
1657
|
-
- **
|
|
1658
|
-
El hook `useLocale` proporciona
|
|
1260
|
+
La función de ayuda `checkIsExternalLink` determina si una URL es externa. Los enlaces externos se dejan sin cambios porque no necesitan localización.
|
|
1261
|
+
- **Recuperación del Idioma Actual**:
|
|
1262
|
+
El hook `useLocale` proporciona el idioma actual (p. ej., `fr` para el francés).
|
|
1659
1263
|
- **Localización de la URL**:
|
|
1660
|
-
Para enlaces internos, `getLocalizedUrl`
|
|
1661
|
-
- **
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1264
|
+
Para los enlaces internos (es decir, no externos), se utiliza `getLocalizedUrl` para prefijar automáticamente la URL con el idioma actual. Esto significa que si su usuario está en francés, pasar `/about` como `href` lo transformará a `/fr/about`.
|
|
1265
|
+
- **Devolución del Enlace**:
|
|
1266
|
+
El componente devuelve un elemento `<a>` con la URL localizada, garantizando que la navegación sea coherente con el idioma.
|
|
1267
|
+
|
|
1268
|
+
### (Opcional) Paso 11: Renderizar Markdown y HTML
|
|
1269
|
+
|
|
1270
|
+
Intlayer admite el renderizado de contenido Markdown y HTML en Preact.
|
|
1271
|
+
|
|
1272
|
+
Puede personalizar el renderizado del contenido Markdown y HTML utilizando el método `.use()`. Este método le permite anular el renderizado predeterminado de etiquetas específicas.
|
|
1273
|
+
|
|
1274
|
+
```tsx
|
|
1275
|
+
import { useIntlayer } from "preact-intlayer";
|
|
1276
|
+
|
|
1277
|
+
const { myMarkdownContent, myHtmlContent } = useIntlayer("my-component");
|
|
1278
|
+
|
|
1279
|
+
// ...
|
|
1280
|
+
|
|
1281
|
+
return (
|
|
1282
|
+
<div>
|
|
1283
|
+
{/* Renderizado básico */}
|
|
1284
|
+
{myMarkdownContent}
|
|
1285
|
+
|
|
1286
|
+
{/* Renderizado personalizado para Markdown */}
|
|
1287
|
+
{myMarkdownContent.use({
|
|
1288
|
+
h1: (props) => <h1 style={{ color: "red" }} {...props} />,
|
|
1289
|
+
})}
|
|
1290
|
+
|
|
1291
|
+
{/* Renderizado básico para HTML */}
|
|
1292
|
+
{myHtmlContent}
|
|
1293
|
+
|
|
1294
|
+
{/* Renderizado personalizado para HTML */}
|
|
1295
|
+
{myHtmlContent.use({
|
|
1296
|
+
b: (props) => <strong style={{ color: "blue" }} {...props} />,
|
|
1297
|
+
})}
|
|
1298
|
+
</div>
|
|
1299
|
+
);
|
|
1300
|
+
```
|
|
1665
1301
|
|
|
1666
1302
|
### Configurar TypeScript
|
|
1667
1303
|
|
|
1668
|
-
Intlayer utiliza la ampliación de módulos para aprovechar
|
|
1304
|
+
Intlayer utiliza la ampliación de módulos para aprovechar las ventajas de TypeScript y fortalecer su base de código.
|
|
1669
1305
|
|
|
1670
|
-

|
|
1671
1307
|
|
|
1672
|
-

|
|
1673
1309
|
|
|
1674
|
-
|
|
1310
|
+
Asegúrese de que su configuración de TypeScript incluya los tipos autogenerados.
|
|
1675
1311
|
|
|
1676
1312
|
```json5 fileName="tsconfig.json"
|
|
1677
1313
|
{
|
|
1678
|
-
// ...
|
|
1314
|
+
// ... Sus configuraciones de TypeScript existentes
|
|
1679
1315
|
"compilerOptions": {
|
|
1680
1316
|
// ...
|
|
1681
1317
|
"jsx": "react-jsx",
|
|
@@ -1683,19 +1319,19 @@ Asegúrate de que tu configuración de TypeScript incluya los tipos autogenerado
|
|
|
1683
1319
|
// ...
|
|
1684
1320
|
},
|
|
1685
1321
|
"include": [
|
|
1686
|
-
// ...
|
|
1322
|
+
// ... Sus configuraciones de TypeScript existentes
|
|
1687
1323
|
".intlayer/**/*.ts", // Incluir los tipos autogenerados
|
|
1688
1324
|
],
|
|
1689
1325
|
}
|
|
1690
1326
|
```
|
|
1691
1327
|
|
|
1692
|
-
>
|
|
1328
|
+
> Asegúrese de que su `tsconfig.json` esté configurado para Preact, especialmente `jsx` y `jsxImportSource` o `jsxFactory`/`jsxFragmentFactory` para versiones anteriores de Preact si no utiliza los valores predeterminados de `preset-vite`.
|
|
1693
1329
|
|
|
1694
1330
|
### Configuración de Git
|
|
1695
1331
|
|
|
1696
|
-
Se recomienda ignorar los archivos generados por Intlayer. Esto
|
|
1332
|
+
Se recomienda ignorar los archivos generados por Intlayer. Esto le permite evitar comprometerlos en su repositorio Git.
|
|
1697
1333
|
|
|
1698
|
-
Para
|
|
1334
|
+
Para hacerlo, puede agregar las siguientes instrucciones a su archivo `.gitignore`:
|
|
1699
1335
|
|
|
1700
1336
|
```plaintext
|
|
1701
1337
|
# Ignorar los archivos generados por Intlayer
|
|
@@ -1704,9 +1340,9 @@ Para hacer esto, puedes agregar las siguientes instrucciones a tu archivo `.giti
|
|
|
1704
1340
|
|
|
1705
1341
|
### Extensión de VS Code
|
|
1706
1342
|
|
|
1707
|
-
Para mejorar
|
|
1343
|
+
Para mejorar su experiencia de desarrollo con Intlayer, puede instalar la **Extensión oficial de Intlayer para VS Code**.
|
|
1708
1344
|
|
|
1709
|
-
[Instalar desde el
|
|
1345
|
+
[Instalar desde el VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
|
|
1710
1346
|
|
|
1711
1347
|
Esta extensión proporciona:
|
|
1712
1348
|
|
|
@@ -1715,12 +1351,12 @@ Esta extensión proporciona:
|
|
|
1715
1351
|
- **Vistas previas en línea** del contenido traducido.
|
|
1716
1352
|
- **Acciones rápidas** para crear y actualizar traducciones fácilmente.
|
|
1717
1353
|
|
|
1718
|
-
Para más detalles sobre cómo usar la extensión,
|
|
1354
|
+
Para más detalles sobre cómo usar la extensión, consulte la [documentación de la extensión de Intlayer para VS Code](https://intlayer.org/doc/vs-code-extension).
|
|
1719
1355
|
|
|
1720
1356
|
---
|
|
1721
1357
|
|
|
1722
1358
|
### Ir Más Allá
|
|
1723
1359
|
|
|
1724
|
-
Para ir más allá,
|
|
1360
|
+
Para ir más allá, puede implementar el [editor visual](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_visual_editor.md) o externalizar su contenido utilizando el [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_CMS.md).
|
|
1725
1361
|
|
|
1726
1362
|
---
|