@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
|
@@ -24,7 +24,7 @@ history:
|
|
|
24
24
|
changes: Histórico inicial
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
# Traduza seu Vite
|
|
27
|
+
# Traduza seu site Vite e Preact usando o Intlayer | Internacionalização (i18n)
|
|
28
28
|
|
|
29
29
|
<Tabs defaultTab="video">
|
|
30
30
|
<Tab label="Video" value="video">
|
|
@@ -45,9 +45,9 @@ history:
|
|
|
45
45
|
</Tab>
|
|
46
46
|
</Tabs>
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
## Tabela de Conteúdos
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
<TOC/>
|
|
51
51
|
|
|
52
52
|
## O que é o Intlayer?
|
|
53
53
|
|
|
@@ -56,7 +56,7 @@ Veja o [Modelo de Aplicação](https://github.com/aymericzip/intlayer-vite-preac
|
|
|
56
56
|
Com o Intlayer, você pode:
|
|
57
57
|
|
|
58
58
|
- **Gerenciar traduções facilmente** usando dicionários declarativos no nível do componente.
|
|
59
|
-
- **Localizar dinamicamente
|
|
59
|
+
- **Localizar dinamicamente metadatos**, rotas e conteúdo.
|
|
60
60
|
- **Garantir suporte ao TypeScript** com tipos gerados automaticamente, melhorando o autocompletar e a detecção de erros.
|
|
61
61
|
- **Beneficie de recursos avançados**, como detecção e troca dinâmica de localidade.
|
|
62
62
|
|
|
@@ -64,6 +64,8 @@ Com o Intlayer, você pode:
|
|
|
64
64
|
|
|
65
65
|
## Guia Passo a Passo para Configurar o Intlayer em uma Aplicação Vite e Preact
|
|
66
66
|
|
|
67
|
+
Veja o [Modelo de Aplicação](https://github.com/aymericzip/intlayer-vite-preact-template) no GitHub.
|
|
68
|
+
|
|
67
69
|
### Passo 1: Instalar Dependências
|
|
68
70
|
|
|
69
71
|
Instale os pacotes necessários usando npm:
|
|
@@ -94,9 +96,7 @@ bunx intlayer init
|
|
|
94
96
|
|
|
95
97
|
- **intlayer**
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
O pacote principal que fornece ferramentas de internacionalização para gerenciamento de configuração, tradução, [declaração de conteúdo](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/get_started.md), transpiração e [comandos CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_cli.md).
|
|
99
|
+
O pacote principal que fornece ferramentas de internacionalização para gerenciamento de configuração, tradução, [declaração de conteúdo](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/content_file.md), transpiração e [comandos CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/cli/index.md).
|
|
100
100
|
|
|
101
101
|
- **preact-intlayer**
|
|
102
102
|
O pacote que integra o Intlayer com a aplicação Preact. Ele fornece provedores de contexto e hooks para internacionalização em Preact.
|
|
@@ -121,6 +121,10 @@ const config: IntlayerConfig = {
|
|
|
121
121
|
],
|
|
122
122
|
defaultLocale: Locales.ENGLISH,
|
|
123
123
|
},
|
|
124
|
+
routing: {
|
|
125
|
+
mode: "prefix-no-default", // Padrão: prefixar todos os locais exceto o padrão
|
|
126
|
+
storage: ["cookie", "header"], // Padrão: armazenar locale no cookie e detectar pelo header
|
|
127
|
+
},
|
|
124
128
|
};
|
|
125
129
|
|
|
126
130
|
export default config;
|
|
@@ -140,6 +144,10 @@ const config = {
|
|
|
140
144
|
],
|
|
141
145
|
defaultLocale: Locales.ENGLISH,
|
|
142
146
|
},
|
|
147
|
+
routing: {
|
|
148
|
+
mode: "prefix-no-default", // Padrão: prefixar todos os locais exceto o padrão
|
|
149
|
+
storage: ["cookie", "header"], // Padrão: armazenar locale no cookie e detectar pelo header
|
|
150
|
+
},
|
|
143
151
|
};
|
|
144
152
|
|
|
145
153
|
export default config;
|
|
@@ -159,12 +167,16 @@ const config = {
|
|
|
159
167
|
],
|
|
160
168
|
defaultLocale: Locales.ENGLISH,
|
|
161
169
|
},
|
|
170
|
+
routing: {
|
|
171
|
+
mode: "prefix-no-default", // Padrão: prefixar todos os locais exceto o padrão
|
|
172
|
+
storage: ["cookie", "header"], // Padrão: armazenar locale no cookie e detectar pelo header
|
|
173
|
+
},
|
|
162
174
|
};
|
|
163
175
|
|
|
164
176
|
module.exports = config;
|
|
165
177
|
```
|
|
166
178
|
|
|
167
|
-
> Através deste arquivo de configuração, você pode configurar URLs localizadas,
|
|
179
|
+
> Através deste arquivo de configuração, você pode configurar URLs localizadas, modos de roteamento, opções de armazenamento, nomes de cookies, a localização e extensão das suas declarações de conteúdo, desabilitar logs do Intlayer no console e muito mais. Para uma lista completa dos parâmetros disponíveis, consulte a [documentação de configuração](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/configuration.md).
|
|
168
180
|
|
|
169
181
|
### Passo 3: Integre o Intlayer na Sua Configuração do Vite
|
|
170
182
|
|
|
@@ -238,7 +250,7 @@ const appContent = {
|
|
|
238
250
|
edit: t<ComponentChildren>({
|
|
239
251
|
en: (
|
|
240
252
|
<>
|
|
241
|
-
|
|
253
|
+
Edit <code>src/app.tsx</code> and save to test HMR
|
|
242
254
|
</>
|
|
243
255
|
),
|
|
244
256
|
fr: (
|
|
@@ -254,7 +266,7 @@ const appContent = {
|
|
|
254
266
|
}),
|
|
255
267
|
|
|
256
268
|
readTheDocs: t({
|
|
257
|
-
en: "
|
|
269
|
+
en: "Click on the Vite and Preact logos to learn more",
|
|
258
270
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
259
271
|
es: "Haga clic en los logotipos de Vite y Preact para obtener más información",
|
|
260
272
|
}),
|
|
@@ -275,13 +287,11 @@ const appContent = {
|
|
|
275
287
|
viteLogo: t({
|
|
276
288
|
en: "Vite logo",
|
|
277
289
|
fr: "Logo Vite",
|
|
278
|
-
pt: "Logo Vite",
|
|
279
290
|
es: "Logo Vite",
|
|
280
291
|
}),
|
|
281
292
|
preactLogo: t({
|
|
282
293
|
en: "Preact logo",
|
|
283
294
|
fr: "Logo Preact",
|
|
284
|
-
pt: "Logo Preact",
|
|
285
295
|
es: "Logo Preact",
|
|
286
296
|
}),
|
|
287
297
|
|
|
@@ -290,24 +300,19 @@ const appContent = {
|
|
|
290
300
|
count: t({
|
|
291
301
|
en: "count is ",
|
|
292
302
|
fr: "le compte est ",
|
|
293
|
-
pt: "a contagem é ",
|
|
294
303
|
es: "el recuento es ",
|
|
295
304
|
}),
|
|
296
305
|
|
|
297
306
|
edit: t({
|
|
298
307
|
en: "Edit src/app.jsx and save to test HMR",
|
|
299
308
|
fr: "Éditez src/app.jsx et enregistrez pour tester HMR",
|
|
300
|
-
pt: "Edite src/app.jsx e salve para testar HMR",
|
|
301
|
-
es: "Edita src/app.jsx y guarda para probar HMR",
|
|
302
|
-
}),
|
|
303
309
|
es: "Edita src/app.jsx y guarda para probar HMR",
|
|
304
310
|
}),
|
|
305
311
|
|
|
306
312
|
readTheDocs: t({
|
|
307
|
-
en: "
|
|
313
|
+
en: "Click on the Vite and Preact logos to learn more",
|
|
308
314
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
309
|
-
es: "Haga clic en los logotipos de Vite y Preact para obtener
|
|
310
|
-
pt: "Clique nos logos do Vite e do Preact para saber mais",
|
|
315
|
+
es: "Haga clic en los logotipos de Vite y Preact para obtener mais informações",
|
|
311
316
|
}),
|
|
312
317
|
},
|
|
313
318
|
};
|
|
@@ -327,13 +332,11 @@ const appContent = {
|
|
|
327
332
|
en: "Vite logo",
|
|
328
333
|
fr: "Logo Vite",
|
|
329
334
|
es: "Logo Vite",
|
|
330
|
-
pt: "Logo Vite",
|
|
331
335
|
}),
|
|
332
336
|
preactLogo: t({
|
|
333
337
|
en: "Preact logo",
|
|
334
338
|
fr: "Logo Preact",
|
|
335
339
|
es: "Logo Preact",
|
|
336
|
-
pt: "Logo Preact",
|
|
337
340
|
}),
|
|
338
341
|
|
|
339
342
|
title: "Vite + Preact",
|
|
@@ -342,21 +345,18 @@ const appContent = {
|
|
|
342
345
|
en: "count is ",
|
|
343
346
|
fr: "le compte est ",
|
|
344
347
|
es: "el recuento es ",
|
|
345
|
-
pt: "a contagem é ",
|
|
346
348
|
}),
|
|
347
349
|
|
|
348
350
|
edit: t({
|
|
349
351
|
en: "Edit src/app.tsx and save to test HMR",
|
|
350
352
|
fr: "Éditez src/app.tsx et enregistrez pour tester HMR",
|
|
351
353
|
es: "Edita src/app.tsx y guarda para probar HMR",
|
|
352
|
-
pt: "Edite src/app.tsx e salve para testar HMR",
|
|
353
354
|
}),
|
|
354
355
|
|
|
355
356
|
readTheDocs: t({
|
|
356
357
|
en: "Click on the Vite and Preact logos to learn more",
|
|
357
358
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
358
|
-
es: "Haga clic en los logotipos de Vite
|
|
359
|
-
pt: "Clique nos logos do Vite e do Preact para saber mais",
|
|
359
|
+
es: "Haga clic en los logotipos de Vite e Preact para saber mais",
|
|
360
360
|
}),
|
|
361
361
|
},
|
|
362
362
|
};
|
|
@@ -374,8 +374,7 @@ module.exports = appContent;
|
|
|
374
374
|
"translation": {
|
|
375
375
|
"en": "Vite logo",
|
|
376
376
|
"fr": "Logo Vite",
|
|
377
|
-
"es": "Logo Vite"
|
|
378
|
-
"pt": "Logo Vite"
|
|
377
|
+
"es": "Logo Vite"
|
|
379
378
|
}
|
|
380
379
|
},
|
|
381
380
|
"preactLogo": {
|
|
@@ -383,8 +382,7 @@ module.exports = appContent;
|
|
|
383
382
|
"translation": {
|
|
384
383
|
"en": "Preact logo",
|
|
385
384
|
"fr": "Logo Preact",
|
|
386
|
-
"es": "Logo Preact"
|
|
387
|
-
"pt": "Logo Preact"
|
|
385
|
+
"es": "Logo Preact"
|
|
388
386
|
}
|
|
389
387
|
},
|
|
390
388
|
"title": {
|
|
@@ -392,8 +390,7 @@ module.exports = appContent;
|
|
|
392
390
|
"translation": {
|
|
393
391
|
"en": "Vite + Preact",
|
|
394
392
|
"fr": "Vite + Preact",
|
|
395
|
-
"es": "Vite + Preact"
|
|
396
|
-
"pt": "Vite + Preact"
|
|
393
|
+
"es": "Vite + Preact"
|
|
397
394
|
}
|
|
398
395
|
},
|
|
399
396
|
"count": {
|
|
@@ -401,8 +398,7 @@ module.exports = appContent;
|
|
|
401
398
|
"translation": {
|
|
402
399
|
"en": "count is ",
|
|
403
400
|
"fr": "le compte est ",
|
|
404
|
-
"es": "el recuento es "
|
|
405
|
-
"pt": "a contagem é "
|
|
401
|
+
"es": "el recuento es "
|
|
406
402
|
}
|
|
407
403
|
},
|
|
408
404
|
"edit": {
|
|
@@ -410,8 +406,7 @@ module.exports = appContent;
|
|
|
410
406
|
"translation": {
|
|
411
407
|
"en": "Edit src/app.tsx and save to test HMR",
|
|
412
408
|
"fr": "Éditez src/app.tsx et enregistrez pour tester HMR",
|
|
413
|
-
"es": "Edita src/app.tsx y guarda para probar HMR"
|
|
414
|
-
"pt": "Edite src/app.tsx e salve para testar HMR"
|
|
409
|
+
"es": "Edita src/app.tsx y guarda para probar HMR"
|
|
415
410
|
}
|
|
416
411
|
},
|
|
417
412
|
"readTheDocs": {
|
|
@@ -419,8 +414,7 @@ module.exports = appContent;
|
|
|
419
414
|
"translation": {
|
|
420
415
|
"en": "Click on the Vite and Preact logos to learn more",
|
|
421
416
|
"fr": "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
422
|
-
"es": "Haga clic en los logotipos de Vite y Preact para obtener más información"
|
|
423
|
-
"pt": "Clique nos logos do Vite e do Preact para saber mais"
|
|
417
|
+
"es": "Haga clic en los logotipos de Vite y Preact para obtener más información"
|
|
424
418
|
}
|
|
425
419
|
}
|
|
426
420
|
}
|
|
@@ -429,7 +423,7 @@ module.exports = appContent;
|
|
|
429
423
|
|
|
430
424
|
> Suas declarações de conteúdo podem ser definidas em qualquer lugar da sua aplicação, desde que estejam incluídas no diretório `contentDir` (por padrão, `./src`). E correspondam à extensão do arquivo de declaração de conteúdo (por padrão, `.content.{json,ts,tsx,js,jsx,mjs,cjs}`).
|
|
431
425
|
|
|
432
|
-
> Para mais detalhes, consulte a [documentação de declaração de conteúdo](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/
|
|
426
|
+
> Para mais detalhes, consulte a [documentação de declaração de conteúdo](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/content_file.md).
|
|
433
427
|
|
|
434
428
|
> Se seu arquivo de conteúdo incluir código TSX, pode ser necessário importar `import { h } from "preact";` ou garantir que sua pragma JSX esteja corretamente configurada para Preact.
|
|
435
429
|
|
|
@@ -471,6 +465,12 @@ const AppContent: FunctionalComponent = () => {
|
|
|
471
465
|
</button>
|
|
472
466
|
<p>{content.edit}</p>
|
|
473
467
|
</div>
|
|
468
|
+
{/* Conteúdo Markdown */}
|
|
469
|
+
<div>{content.myMarkdownContent}</div>
|
|
470
|
+
|
|
471
|
+
{/* Conteúdo HTML */}
|
|
472
|
+
<div>{content.myHtmlContent}</div>
|
|
473
|
+
|
|
474
474
|
<p class="read-the-docs">{content.readTheDocs}</p>
|
|
475
475
|
</>
|
|
476
476
|
);
|
|
@@ -647,7 +647,7 @@ module.exports = LocaleSwitcher;
|
|
|
647
647
|
|
|
648
648
|
> Para saber mais sobre o hook `useLocale`, consulte a [documentação](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/react-intlayer/useLocale.md) (A API é semelhante para `preact-intlayer`).
|
|
649
649
|
|
|
650
|
-
### (Opcional) Passo 7:
|
|
650
|
+
### (Opcional) Passo 7: Adicionar roteamento localizado à sua aplicação
|
|
651
651
|
|
|
652
652
|
O objetivo deste passo é criar rotas únicas para cada idioma. Isso é útil para SEO e URLs amigáveis para SEO.
|
|
653
653
|
Exemplo:
|
|
@@ -658,141 +658,15 @@ Exemplo:
|
|
|
658
658
|
- https://example.com/fr/about
|
|
659
659
|
```
|
|
660
660
|
|
|
661
|
-
> Por padrão, as rotas não são prefixadas para o idioma padrão. Se você quiser prefixar o idioma padrão, pode definir a opção `
|
|
661
|
+
> Por padrão, as rotas não são prefixadas para o idioma padrão. Se você quiser prefixar o idioma padrão, pode definir a opção `routing.mode` como `"prefix-all"` na sua configuração. Veja a [documentação de configuração](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/configuration.md) para mais informações.
|
|
662
662
|
|
|
663
|
-
Para adicionar roteamento localizado à sua aplicação, você pode criar um componente `LocaleRouter` que envolva as rotas da sua aplicação e gerencie o roteamento baseado no idioma. Aqui está um exemplo usando [preact-iso](https://github.com/preactjs/preact-iso):
|
|
664
|
-
|
|
665
|
-
Primeiro, instale o `preact-iso`:
|
|
666
|
-
|
|
667
|
-
```bash packageManager="npm"
|
|
668
|
-
npm install preact-iso
|
|
669
|
-
npx intlayer init
|
|
670
|
-
```
|
|
671
|
-
|
|
672
|
-
```bash packageManager="pnpm"
|
|
673
|
-
pnpm add preact-iso
|
|
674
|
-
pnpm intlayer init
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
```bash packageManager="yarn"
|
|
678
|
-
yarn add preact-iso
|
|
679
|
-
```
|
|
663
|
+
Para adicionar roteamento localizado à sua aplicação, você pode criar um componente `LocaleRouter` que envolva as rotas da sua aplicação e gerencie o roteamento baseado no idioma. Aqui está um exemplo usando [preact-iso](https://github.com/preactjs/preact-iso) :
|
|
680
664
|
|
|
681
665
|
```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
|
|
682
|
-
import {
|
|
683
|
-
import { ComponentChildren, FunctionalComponent } from "preact";
|
|
666
|
+
import { localeMap } from "intlayer";
|
|
684
667
|
import { IntlayerProvider } from "preact-intlayer";
|
|
685
|
-
import { LocationProvider,
|
|
686
|
-
import {
|
|
687
|
-
|
|
688
|
-
const { internationalization, middleware } = configuration;
|
|
689
|
-
const { locales, defaultLocale } = internationalization;
|
|
690
|
-
|
|
691
|
-
const Navigate: FunctionalComponent<{ to: string; replace?: boolean }> = ({
|
|
692
|
-
to,
|
|
693
|
-
replace,
|
|
694
|
-
}) => {
|
|
695
|
-
const { route } = useLocation();
|
|
696
|
-
useEffect(() => {
|
|
697
|
-
route(to, replace);
|
|
698
|
-
}, [to, replace, route]);
|
|
699
|
-
return null;
|
|
700
|
-
};
|
|
701
|
-
|
|
702
|
-
/**
|
|
703
|
-
* Um componente que gerencia a localização e envolve os filhos com o contexto de idioma apropriado.
|
|
704
|
-
* Ele gerencia a detecção e validação do idioma baseado na URL.
|
|
705
|
-
*/
|
|
706
|
-
const AppLocalized: FunctionalComponent<{
|
|
707
|
-
children: ComponentChildren;
|
|
708
|
-
locale?: Locales;
|
|
709
|
-
}> = ({ children, locale }) => {
|
|
710
|
-
const { path: pathname, url } = useLocation();
|
|
711
|
-
|
|
712
|
-
if (!url) {
|
|
713
|
-
return null;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
const search = url.substring(pathname.length);
|
|
717
|
-
|
|
718
|
-
// Determina o idioma atual, usando o padrão caso não seja fornecido
|
|
719
|
-
const currentLocale = locale ?? defaultLocale;
|
|
720
|
-
|
|
721
|
-
// Remove o prefixo do idioma do caminho para construir um caminho base
|
|
722
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
723
|
-
pathname // Caminho atual da URL
|
|
724
|
-
);
|
|
725
|
-
|
|
726
|
-
/**
|
|
727
|
-
* Se middleware.prefixDefault for verdadeiro, o locale padrão deve sempre ser prefixado.
|
|
728
|
-
*/
|
|
729
|
-
if (middleware.prefixDefault) {
|
|
730
|
-
// Validar o locale
|
|
731
|
-
if (!locale || !locales.includes(locale)) {
|
|
732
|
-
// Redirecionar para o locale padrão com o caminho atualizado
|
|
733
|
-
return (
|
|
734
|
-
<Navigate
|
|
735
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
736
|
-
replace // Substituir a entrada atual do histórico pela nova
|
|
737
|
-
/>
|
|
738
|
-
);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
// Envolver os filhos com o IntlayerProvider e definir o locale atual
|
|
742
|
-
return (
|
|
743
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
744
|
-
);
|
|
745
|
-
} else {
|
|
746
|
-
/**
|
|
747
|
-
* Quando middleware.prefixDefault for falso, o locale padrão não é prefixado.
|
|
748
|
-
* Garantir que o idioma atual seja válido e não o idioma padrão.
|
|
749
|
-
*/
|
|
750
|
-
if (
|
|
751
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
752
|
-
!locales
|
|
753
|
-
.filter(
|
|
754
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Excluir o idioma padrão
|
|
755
|
-
)
|
|
756
|
-
.includes(currentLocale) // Verificar se o idioma atual está na lista de idiomas válidos
|
|
757
|
-
) {
|
|
758
|
-
// Redirecionar para o caminho sem prefixo de idioma
|
|
759
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// Envolver os filhos com o IntlayerProvider e definir o idioma atual
|
|
763
|
-
return (
|
|
764
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
765
|
-
);
|
|
766
|
-
}
|
|
767
|
-
};
|
|
768
|
-
|
|
769
|
-
const RouterContent: FunctionalComponent<{
|
|
770
|
-
children: ComponentChildren;
|
|
771
|
-
}> = ({ children }) => {
|
|
772
|
-
const { path } = useLocation();
|
|
773
|
-
|
|
774
|
-
if (!path) {
|
|
775
|
-
return null;
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
const pathLocale = path.split("/")[1] as Locales;
|
|
779
|
-
|
|
780
|
-
const isLocaleRoute = locales
|
|
781
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
782
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
783
|
-
|
|
784
|
-
if (isLocaleRoute) {
|
|
785
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
return (
|
|
789
|
-
<AppLocalized
|
|
790
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
791
|
-
>
|
|
792
|
-
{children}
|
|
793
|
-
</AppLocalized>
|
|
794
|
-
);
|
|
795
|
-
};
|
|
668
|
+
import { LocationProvider, Router, Route } from "preact-iso";
|
|
669
|
+
import type { ComponentChildren, FunctionalComponent } from "preact";
|
|
796
670
|
|
|
797
671
|
/**
|
|
798
672
|
* Um componente de roteador que configura rotas específicas para cada locale.
|
|
@@ -802,261 +676,89 @@ export const LocaleRouter: FunctionalComponent<{
|
|
|
802
676
|
children: ComponentChildren;
|
|
803
677
|
}> = ({ children }) => (
|
|
804
678
|
<LocationProvider>
|
|
805
|
-
<
|
|
679
|
+
<Router>
|
|
680
|
+
{localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
681
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
682
|
+
.map(({ locale, urlPrefix }) => (
|
|
683
|
+
<Route
|
|
684
|
+
key={locale}
|
|
685
|
+
path={`${urlPrefix}/:rest*`}
|
|
686
|
+
component={() => (
|
|
687
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
688
|
+
)}
|
|
689
|
+
/>
|
|
690
|
+
))}
|
|
691
|
+
</Router>
|
|
806
692
|
</LocationProvider>
|
|
807
693
|
);
|
|
808
694
|
```
|
|
809
695
|
|
|
810
696
|
```jsx fileName="src/components/LocaleRouter.jsx" codeFormat="esm"
|
|
811
|
-
|
|
812
|
-
import { configuration, getPathWithoutLocale } from "intlayer";
|
|
697
|
+
import { localeMap } from "intlayer";
|
|
813
698
|
import { IntlayerProvider } from "preact-intlayer";
|
|
814
|
-
import { LocationProvider,
|
|
815
|
-
import { useEffect } from "preact/hooks";
|
|
816
|
-
import { h } from "preact"; // Necessário para JSX
|
|
817
|
-
|
|
818
|
-
// Desestruturando a configuração do Intlayer
|
|
819
|
-
const { internationalization, middleware } = configuration;
|
|
820
|
-
const { locales, defaultLocale } = internationalization;
|
|
821
|
-
|
|
822
|
-
const Navigate = ({ to, replace }) => {
|
|
823
|
-
const { route } = useLocation();
|
|
824
|
-
useEffect(() => {
|
|
825
|
-
route(to, replace);
|
|
826
|
-
}, [to, replace, route]);
|
|
827
|
-
return null;
|
|
828
|
-
};
|
|
699
|
+
import { LocationProvider, Router, Route } from "preact-iso";
|
|
829
700
|
|
|
830
701
|
/**
|
|
831
|
-
* Um componente
|
|
832
|
-
* Ele gerencia a detecção e validação da localidade baseada na URL.
|
|
833
|
-
*/
|
|
834
|
-
const AppLocalized = ({ children, locale }) => {
|
|
835
|
-
const { path: pathname, url } = useLocation();
|
|
836
|
-
|
|
837
|
-
if (!url) {
|
|
838
|
-
return null;
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
const search = url.substring(pathname.length);
|
|
842
|
-
|
|
843
|
-
// Determina a localidade atual, usando a localidade padrão caso não seja fornecida
|
|
844
|
-
const currentLocale = locale ?? defaultLocale;
|
|
845
|
-
|
|
846
|
-
// Remove o prefixo da localidade do caminho para construir um caminho base
|
|
847
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
848
|
-
pathname // Caminho atual da URL
|
|
849
|
-
);
|
|
850
|
-
|
|
851
|
-
/**
|
|
852
|
-
* Se middleware.prefixDefault for verdadeiro, a localidade padrão deve sempre ser prefixada.
|
|
853
|
-
*/
|
|
854
|
-
if (middleware.prefixDefault) {
|
|
855
|
-
// Validar a localidade
|
|
856
|
-
if (!locale || !locales.includes(locale)) {
|
|
857
|
-
// Redirecionar para a localidade padrão com o caminho atualizado
|
|
858
|
-
return (
|
|
859
|
-
<Navigate
|
|
860
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
861
|
-
replace // Substituir a entrada atual do histórico pela nova
|
|
862
|
-
/>
|
|
863
|
-
);
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
// Envolver os filhos com o IntlayerProvider e definir a localidade atual
|
|
867
|
-
return (
|
|
868
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
869
|
-
);
|
|
870
|
-
} else {
|
|
871
|
-
/**
|
|
872
|
-
* Quando middleware.prefixDefault é falso, a localidade padrão não é prefixada.
|
|
873
|
-
* Garantir que a localidade atual seja válida e não seja a localidade padrão.
|
|
874
|
-
*/
|
|
875
|
-
if (
|
|
876
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
877
|
-
!locales
|
|
878
|
-
.filter(
|
|
879
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Excluir a localidade padrão
|
|
880
|
-
)
|
|
881
|
-
.includes(currentLocale) // Verificar se a localidade atual está na lista de localidades válidas
|
|
882
|
-
) {
|
|
883
|
-
// Redirecionar para o caminho sem prefixo de localidade
|
|
884
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
// Envolver os filhos com o IntlayerProvider e definir a localidade atual
|
|
888
|
-
return (
|
|
889
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
890
|
-
);
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
|
-
|
|
894
|
-
const RouterContent = ({ children }) => {
|
|
895
|
-
const { path } = useLocation();
|
|
896
|
-
|
|
897
|
-
if (!path) {
|
|
898
|
-
return null;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
const pathLocale = path.split("/")[1];
|
|
902
|
-
|
|
903
|
-
const isLocaleRoute = locales
|
|
904
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
905
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
906
|
-
|
|
907
|
-
if (isLocaleRoute) {
|
|
908
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
return (
|
|
912
|
-
<AppLocalized
|
|
913
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
914
|
-
>
|
|
915
|
-
{children}
|
|
916
|
-
</AppLocalized>
|
|
917
|
-
);
|
|
918
|
-
};
|
|
919
|
-
|
|
920
|
-
/**
|
|
921
|
-
* Um componente de roteador que configura rotas específicas por localidade.
|
|
702
|
+
* Um componente de roteador que configura rotas específicas para cada locale.
|
|
922
703
|
* Ele usa preact-iso para gerenciar a navegação e renderizar componentes localizados.
|
|
923
704
|
*/
|
|
924
705
|
export const LocaleRouter = ({ children }) => (
|
|
925
706
|
<LocationProvider>
|
|
926
|
-
<
|
|
707
|
+
<Router>
|
|
708
|
+
{localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
709
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
710
|
+
.map(({ locale, urlPrefix }) => (
|
|
711
|
+
<Route
|
|
712
|
+
key={locale}
|
|
713
|
+
path={`${urlPrefix}/:rest*`}
|
|
714
|
+
component={() => (
|
|
715
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
716
|
+
)}
|
|
717
|
+
/>
|
|
718
|
+
))}
|
|
719
|
+
</Router>
|
|
927
720
|
</LocationProvider>
|
|
928
721
|
);
|
|
929
722
|
```
|
|
930
723
|
|
|
931
724
|
```jsx fileName="src/components/LocaleRouter.cjsx" codeFormat="commonjs"
|
|
932
|
-
|
|
933
|
-
const { configuration, getPathWithoutLocale } = require("intlayer");
|
|
725
|
+
const { localeMap } = require("intlayer");
|
|
934
726
|
const { IntlayerProvider } = require("preact-intlayer");
|
|
935
|
-
const { LocationProvider,
|
|
936
|
-
const { useEffect } = require("preact/hooks");
|
|
937
|
-
const { h } = require("preact"); // Necessário para JSX
|
|
938
|
-
|
|
939
|
-
// Desestruturando configuração do Intlayer
|
|
940
|
-
const { internationalization, middleware } = configuration;
|
|
941
|
-
const { locales, defaultLocale } = internationalization;
|
|
942
|
-
|
|
943
|
-
const Navigate = ({ to, replace }) => {
|
|
944
|
-
const { route } = useLocation();
|
|
945
|
-
useEffect(() => {
|
|
946
|
-
route(to, replace);
|
|
947
|
-
}, [to, replace, route]);
|
|
948
|
-
return null;
|
|
949
|
-
};
|
|
727
|
+
const { LocationProvider, Router, Route } = require("preact-iso");
|
|
950
728
|
|
|
951
729
|
/**
|
|
952
|
-
* Um componente
|
|
953
|
-
* Ele
|
|
730
|
+
* Um componente de roteador que configura rotas específicas para cada locale.
|
|
731
|
+
* Ele usa preact-iso para gerenciar a navegação e renderizar componentes localizados.
|
|
954
732
|
*/
|
|
955
|
-
const
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
);
|
|
971
|
-
|
|
972
|
-
/**
|
|
973
|
-
* Se middleware.prefixDefault for true, a localidade padrão deve sempre ser prefixada.
|
|
974
|
-
*/
|
|
975
|
-
if (middleware.prefixDefault) {
|
|
976
|
-
// Valida a localidade
|
|
977
|
-
if (!locale || !locales.includes(locale)) {
|
|
978
|
-
// Redireciona para a localidade padrão com o caminho atualizado
|
|
979
|
-
return (
|
|
980
|
-
<Navigate
|
|
981
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
982
|
-
replace // Substitui a entrada atual do histórico pela nova
|
|
983
|
-
/>
|
|
984
|
-
);
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// Envolve os filhos com o IntlayerProvider e define o locale atual
|
|
988
|
-
return (
|
|
989
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
990
|
-
);
|
|
991
|
-
} else {
|
|
992
|
-
/**
|
|
993
|
-
* Quando middleware.prefixDefault é falso, o locale padrão não é prefixado.
|
|
994
|
-
* Assegure que o locale atual é válido e não é o locale padrão.
|
|
995
|
-
*/
|
|
996
|
-
if (
|
|
997
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
998
|
-
!locales
|
|
999
|
-
.filter(
|
|
1000
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Exclui o locale padrão
|
|
733
|
+
const LocaleRouter = ({ children }) =>
|
|
734
|
+
h(
|
|
735
|
+
LocationProvider,
|
|
736
|
+
{},
|
|
737
|
+
h(
|
|
738
|
+
Router,
|
|
739
|
+
{},
|
|
740
|
+
localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
741
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
742
|
+
.map(({ locale, urlPrefix }) =>
|
|
743
|
+
h(Route, {
|
|
744
|
+
key: locale,
|
|
745
|
+
path: `${urlPrefix}/:rest*`,
|
|
746
|
+
component: () => h(IntlayerProvider, { locale }, children),
|
|
747
|
+
})
|
|
1001
748
|
)
|
|
1002
|
-
|
|
1003
|
-
) {
|
|
1004
|
-
// Redireciona para o caminho sem o prefixo da localidade
|
|
1005
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
// Envolve os filhos com o IntlayerProvider e define a localidade atual
|
|
1009
|
-
return (
|
|
1010
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
1011
|
-
);
|
|
1012
|
-
}
|
|
1013
|
-
};
|
|
1014
|
-
|
|
1015
|
-
const RouterContent = ({ children }) => {
|
|
1016
|
-
const { path } = useLocation();
|
|
1017
|
-
|
|
1018
|
-
if (!path) {
|
|
1019
|
-
return null;
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
const pathLocale = path.split("/")[1];
|
|
1023
|
-
|
|
1024
|
-
const isLocaleRoute = locales
|
|
1025
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
1026
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
1027
|
-
|
|
1028
|
-
if (isLocaleRoute) {
|
|
1029
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
return (
|
|
1033
|
-
<AppLocalized
|
|
1034
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
1035
|
-
>
|
|
1036
|
-
{children}
|
|
1037
|
-
</AppLocalized>
|
|
749
|
+
)
|
|
1038
750
|
);
|
|
1039
|
-
};
|
|
1040
|
-
|
|
1041
|
-
/**
|
|
1042
|
-
* Um componente de roteador que configura rotas específicas por locale.
|
|
1043
|
-
* Ele usa preact-iso para gerenciar a navegação e renderizar componentes localizados.
|
|
1044
|
-
*/
|
|
1045
|
-
const LocaleRouter = ({ children }) => (
|
|
1046
|
-
<LocationProvider>
|
|
1047
|
-
<RouterContent>{children}</RouterContent>
|
|
1048
|
-
</LocationProvider>
|
|
1049
|
-
);
|
|
1050
751
|
|
|
1051
752
|
module.exports = { LocaleRouter };
|
|
1052
753
|
```
|
|
1053
754
|
|
|
1054
|
-
|
|
755
|
+
Em seguida, você pode usar o componente `LocaleRouter` na sua aplicação:
|
|
1055
756
|
|
|
1056
757
|
```tsx fileName="src/app.tsx" codeFormat="typescript"
|
|
1057
758
|
import { LocaleRouter } from "./components/LocaleRouter";
|
|
1058
759
|
import type { FunctionalComponent } from "preact";
|
|
1059
|
-
|
|
760
|
+
|
|
761
|
+
// ... Seu componente AppContent
|
|
1060
762
|
|
|
1061
763
|
const App: FunctionalComponent = () => (
|
|
1062
764
|
<LocaleRouter>
|
|
@@ -1069,7 +771,8 @@ export default App;
|
|
|
1069
771
|
|
|
1070
772
|
```jsx fileName="src/app.jsx" codeFormat="esm"
|
|
1071
773
|
import { LocaleRouter } from "./components/LocaleRouter";
|
|
1072
|
-
|
|
774
|
+
|
|
775
|
+
// ... Seu componente AppContent
|
|
1073
776
|
|
|
1074
777
|
const App = () => (
|
|
1075
778
|
<LocaleRouter>
|
|
@@ -1082,7 +785,8 @@ export default App;
|
|
|
1082
785
|
|
|
1083
786
|
```jsx fileName="src/app.cjsx" codeFormat="commonjs"
|
|
1084
787
|
const { LocaleRouter } = require("./components/LocaleRouter");
|
|
1085
|
-
|
|
788
|
+
|
|
789
|
+
// ... Seu componente AppContent
|
|
1086
790
|
|
|
1087
791
|
const App = () => (
|
|
1088
792
|
<LocaleRouter>
|
|
@@ -1093,47 +797,12 @@ const App = () => (
|
|
|
1093
797
|
module.exports = App;
|
|
1094
798
|
```
|
|
1095
799
|
|
|
1096
|
-
Em paralelo, você também pode usar o `intlayerProxy` para adicionar roteamento no lado do servidor à sua aplicação. Este plugin detectará automaticamente o locale atual com base na URL e definirá o cookie de locale apropriado. Se nenhum locale for especificado, o plugin determinará o locale mais adequado com base nas preferências de idioma do navegador do usuário. Se nenhum locale for detectado, ele redirecionará para o locale padrão.
|
|
1097
|
-
|
|
1098
|
-
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
1099
|
-
import { defineConfig } from "vite";
|
|
1100
|
-
import preact from "@preact/preset-vite";
|
|
1101
|
-
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1102
|
-
|
|
1103
|
-
// https://vitejs.dev/config/
|
|
1104
|
-
export default defineConfig({
|
|
1105
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1106
|
-
});
|
|
1107
|
-
```
|
|
1108
|
-
|
|
1109
|
-
```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
|
|
1110
|
-
import { defineConfig } from "vite";
|
|
1111
|
-
import preact from "@preact/preset-vite";
|
|
1112
|
-
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1113
|
-
|
|
1114
|
-
// https://vitejs.dev/config/
|
|
1115
|
-
export default defineConfig({
|
|
1116
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1117
|
-
});
|
|
1118
|
-
```
|
|
1119
|
-
|
|
1120
|
-
```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
|
|
1121
|
-
const { defineConfig } = require("vite");
|
|
1122
|
-
const preact = require("@preact/preset-vite");
|
|
1123
|
-
const { intlayer, intlayerProxy } = require("vite-intlayer");
|
|
1124
|
-
|
|
1125
|
-
// https://vitejs.dev/config/
|
|
1126
|
-
module.exports = defineConfig({
|
|
1127
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1128
|
-
});
|
|
1129
|
-
```
|
|
1130
|
-
|
|
1131
800
|
### (Opcional) Passo 8: Alterar a URL quando o idioma mudar
|
|
1132
801
|
|
|
1133
|
-
Para alterar a URL quando o locale mudar, você pode usar a prop `onLocaleChange` fornecida pelo hook `useLocale`. Em paralelo, você pode usar `
|
|
802
|
+
Para alterar a URL quando o locale mudar, você pode usar a prop `onLocaleChange` fornecida pelo hook `useLocale`. Em paralelo, você pode usar o método `route` do `useLocation` do `preact-iso` para atualizar o caminho da URL.
|
|
1134
803
|
|
|
1135
804
|
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
|
|
1136
|
-
import { useLocation
|
|
805
|
+
import { useLocation } from "preact-iso";
|
|
1137
806
|
import {
|
|
1138
807
|
Locales,
|
|
1139
808
|
getHTMLTextDir,
|
|
@@ -1144,13 +813,12 @@ import { useLocale } from "preact-intlayer";
|
|
|
1144
813
|
import type { FunctionalComponent } from "preact";
|
|
1145
814
|
|
|
1146
815
|
const LocaleSwitcher: FunctionalComponent = () => {
|
|
1147
|
-
const
|
|
816
|
+
const { url, route } = useLocation();
|
|
1148
817
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1149
818
|
onLocaleChange: (newLocale) => {
|
|
1150
|
-
const currentFullPath = location.url; // preact-iso fornece a URL completa
|
|
1151
819
|
// Construir a URL com o locale atualizado
|
|
1152
820
|
// Exemplo: /es/about?foo=bar
|
|
1153
|
-
const pathWithLocale = getLocalizedUrl(
|
|
821
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1154
822
|
|
|
1155
823
|
// Atualizar o caminho da URL
|
|
1156
824
|
route(pathWithLocale, true); // true para substituir
|
|
@@ -1163,7 +831,7 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
1163
831
|
<div id="localePopover" popover="auto">
|
|
1164
832
|
{availableLocales.map((localeItem) => (
|
|
1165
833
|
<a
|
|
1166
|
-
href={getLocalizedUrl(
|
|
834
|
+
href={getLocalizedUrl(url, localeItem)}
|
|
1167
835
|
hreflang={localeItem}
|
|
1168
836
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1169
837
|
onClick={(e) => {
|
|
@@ -1200,7 +868,7 @@ export default LocaleSwitcher;
|
|
|
1200
868
|
```
|
|
1201
869
|
|
|
1202
870
|
```jsx fileName="src/components/LocaleSwitcher.jsx" codeFormat="esm"
|
|
1203
|
-
import { useLocation
|
|
871
|
+
import { useLocation } from "preact-iso";
|
|
1204
872
|
import {
|
|
1205
873
|
Locales,
|
|
1206
874
|
getHTMLTextDir,
|
|
@@ -1208,14 +876,12 @@ import {
|
|
|
1208
876
|
getLocalizedUrl,
|
|
1209
877
|
} from "intlayer";
|
|
1210
878
|
import { useLocale } from "preact-intlayer";
|
|
1211
|
-
import { h } from "preact"; // Para JSX
|
|
1212
879
|
|
|
1213
880
|
const LocaleSwitcher = () => {
|
|
1214
|
-
const
|
|
881
|
+
const { url, route } = useLocation();
|
|
1215
882
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1216
883
|
onLocaleChange: (newLocale) => {
|
|
1217
|
-
const
|
|
1218
|
-
const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
|
|
884
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1219
885
|
route(pathWithLocale, true);
|
|
1220
886
|
},
|
|
1221
887
|
});
|
|
@@ -1226,7 +892,7 @@ const LocaleSwitcher = () => {
|
|
|
1226
892
|
<div id="localePopover" popover="auto">
|
|
1227
893
|
{availableLocales.map((localeItem) => (
|
|
1228
894
|
<a
|
|
1229
|
-
href={getLocalizedUrl(
|
|
895
|
+
href={getLocalizedUrl(url, localeItem)}
|
|
1230
896
|
hreflang={localeItem}
|
|
1231
897
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1232
898
|
onClick={(e) => {
|
|
@@ -1254,7 +920,7 @@ export default LocaleSwitcher;
|
|
|
1254
920
|
```
|
|
1255
921
|
|
|
1256
922
|
```jsx fileName="src/components/LocaleSwitcher.cjsx" codeFormat="commonjs"
|
|
1257
|
-
const { useLocation
|
|
923
|
+
const { useLocation } = require("preact-iso");
|
|
1258
924
|
const {
|
|
1259
925
|
Locales,
|
|
1260
926
|
getHTMLTextDir,
|
|
@@ -1262,45 +928,51 @@ const {
|
|
|
1262
928
|
getLocalizedUrl,
|
|
1263
929
|
} = require("intlayer");
|
|
1264
930
|
const { useLocale } = require("preact-intlayer");
|
|
1265
|
-
const { h } = require("preact"); // Para JSX
|
|
1266
931
|
|
|
1267
932
|
const LocaleSwitcher = () => {
|
|
1268
|
-
const
|
|
933
|
+
const { url, route } = useLocation();
|
|
1269
934
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1270
935
|
onLocaleChange: (newLocale) => {
|
|
1271
|
-
const
|
|
1272
|
-
const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
|
|
936
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1273
937
|
route(pathWithLocale, true);
|
|
1274
938
|
},
|
|
1275
939
|
});
|
|
1276
940
|
|
|
1277
|
-
return (
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
941
|
+
return h(
|
|
942
|
+
"div",
|
|
943
|
+
{},
|
|
944
|
+
h("button", { popovertarget: "localePopover" }, getLocaleName(locale)),
|
|
945
|
+
h(
|
|
946
|
+
"div",
|
|
947
|
+
{ id: "localePopover", popover: "auto" },
|
|
948
|
+
availableLocales.map((localeItem) =>
|
|
949
|
+
h(
|
|
950
|
+
"a",
|
|
951
|
+
{
|
|
952
|
+
href: getLocalizedUrl(url, localeItem),
|
|
953
|
+
hreflang: localeItem,
|
|
954
|
+
"aria-current": locale === localeItem ? "page" : undefined,
|
|
955
|
+
onClick: (e) => {
|
|
1287
956
|
e.preventDefault();
|
|
1288
957
|
setLocale(localeItem);
|
|
1289
|
-
}
|
|
1290
|
-
key
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
958
|
+
},
|
|
959
|
+
key: localeItem,
|
|
960
|
+
},
|
|
961
|
+
h("span", {}, localeItem),
|
|
962
|
+
h("span", {}, getLocaleName(localeItem, localeItem)),
|
|
963
|
+
h(
|
|
964
|
+
"span",
|
|
965
|
+
{ dir: getHTMLTextDir(localeItem), lang: localeItem },
|
|
966
|
+
getLocaleName(localeItem, locale)
|
|
967
|
+
),
|
|
968
|
+
h(
|
|
969
|
+
"span",
|
|
970
|
+
{ dir: "ltr", lang: Locales.ENGLISH },
|
|
971
|
+
getLocaleName(localeItem, Locales.ENGLISH)
|
|
972
|
+
)
|
|
973
|
+
)
|
|
974
|
+
)
|
|
975
|
+
)
|
|
1304
976
|
);
|
|
1305
977
|
};
|
|
1306
978
|
|
|
@@ -1309,22 +981,9 @@ module.exports = LocaleSwitcher;
|
|
|
1309
981
|
|
|
1310
982
|
> Referências da documentação:
|
|
1311
983
|
>
|
|
1312
|
-
> > - [`useLocale`
|
|
1313
|
-
>
|
|
1314
|
-
> - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/intlayer/getLocaleName.md)
|
|
1315
|
-
> - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/intlayer/getLocalizedUrl.md)
|
|
1316
|
-
> - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/intlayer/getHTMLTextDir.md)
|
|
1317
|
-
> - Atributo [`hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
|
|
1318
|
-
> - Atributo [`lang`](https://developer.mozilla.org/pt-BR/docs/Web/HTML/Global_attributes/lang)
|
|
1319
|
-
> - Atributo [`dir`](https://developer.mozilla.org/pt-BR/docs/Web/HTML/Global_attributes/dir)
|
|
1320
|
-
> - Atributo [`aria-current`](https://developer.mozilla.org/pt-BR/docs/Web/Accessibility/ARIA/Attributes/aria-current)
|
|
1321
|
-
> - [API Popover](https://developer.mozilla.org/pt-BR/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)
|
|
984
|
+
> > - [Hook `useLocale`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/react-intlayer/useLocale.md) (API é semelhante para `preact-intlayer`)> - [Hook `getLocaleName`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/intlayer/getLocaleName.md)> - [Hook `getLocalizedUrl`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/intlayer/getLocalizedUrl.md)> - [Hook `getHTMLTextDir`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/packages/intlayer/getHTMLTextDir.md)> - [Atributo `hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)> - [Atributo `lang`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang)> - [Atributo `dir`](https://developer.mozilla.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)
|
|
1322
985
|
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
---
|
|
1326
|
-
|
|
1327
|
-
### (Opcional) Passo 9: Alterar os atributos de idioma e direção do HTML
|
|
986
|
+
### (Opcional) Passo 9: Alternar os atributos de idioma e direção do HTML
|
|
1328
987
|
|
|
1329
988
|
Quando sua aplicação suporta múltiplos idiomas, é crucial atualizar os atributos `lang` e `dir` da tag `<html>` para corresponder ao locale atual. Fazer isso garante:
|
|
1330
989
|
|
|
@@ -1469,213 +1128,192 @@ const App = () => (
|
|
|
1469
1128
|
module.exports = App;
|
|
1470
1129
|
```
|
|
1471
1130
|
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
- Garantir que o atributo **language** (`lang`) reflita corretamente a localidade atual, o que é importante para SEO e comportamento do navegador.
|
|
1475
|
-
- Ajustar a **direção do texto** (`dir`) de acordo com a localidade, melhorando a legibilidade e usabilidade para idiomas com ordens de leitura diferentes.
|
|
1476
|
-
- Proporcionar uma experiência mais **acessível**, pois as tecnologias assistivas dependem desses atributos para funcionar de forma otimizada.
|
|
1477
|
-
|
|
1478
|
-
### (Opcional) Passo 10: Criando um Componente de Link Localizado
|
|
1131
|
+
### (Opcional) Passo 10: Criando um componente de link localizado
|
|
1479
1132
|
|
|
1480
|
-
Para garantir que a navegação da sua aplicação respeite o
|
|
1133
|
+
Para garantir que a navegação da sua aplicação respeite o locale atual, você pode criar um componente `Link` personalizado. Este componente prefixa automaticamente as URLs internas com o idioma atual.
|
|
1481
1134
|
|
|
1482
|
-
|
|
1135
|
+
Este comportamento é útil por vários motivos:
|
|
1483
1136
|
|
|
1484
|
-
- **SEO e Experiência do Usuário**: URLs localizadas ajudam os motores de busca a indexar corretamente páginas específicas por idioma e fornecem aos usuários conteúdo no idioma
|
|
1485
|
-
- **Consistência**: Ao usar um link localizado em toda a sua aplicação, você garante que a navegação permaneça dentro do
|
|
1486
|
-
- **
|
|
1137
|
+
- **SEO e Experiência do Usuário**: URLs localizadas ajudam os motores de busca a indexar corretamente as páginas específicas por idioma e fornecem aos usuários conteúdo no idioma de sua preferência.
|
|
1138
|
+
- **Consistência**: Ao usar um link localizado em toda a sua aplicação, você garante que a navegação permaneça dentro do locale atual, evitando mudanças inesperadas de idioma.
|
|
1139
|
+
- **Manutenibilidade**: Centralizar a lógica de localização em um único componente simplifica a gestão das URLs.
|
|
1487
1140
|
|
|
1488
|
-
|
|
1141
|
+
Abaixo está a implementação de um componente `Link` localizado em Preact:
|
|
1489
1142
|
|
|
1490
|
-
```tsx fileName="src/components/
|
|
1143
|
+
```tsx fileName="src/components/Link.tsx" codeFormat="typescript"
|
|
1491
1144
|
import { getLocalizedUrl } from "intlayer";
|
|
1492
|
-
import { useLocale
|
|
1493
|
-
|
|
1494
|
-
import type { JSX } from "preact";
|
|
1495
|
-
import { forwardRef } from "preact/compat"; // Para encaminhar refs
|
|
1145
|
+
import { useLocale } from "preact-intlayer";
|
|
1146
|
+
import { forwardRef } from "preact/compat";
|
|
1147
|
+
import type { JSX } from "preact";
|
|
1496
1148
|
|
|
1497
|
-
export interface
|
|
1149
|
+
export interface LinkProps extends JSX.HTMLAttributes<HTMLAnchorElement> {
|
|
1498
1150
|
href: string;
|
|
1499
|
-
replace?: boolean; // Opcional: para substituir o estado do histórico
|
|
1500
1151
|
}
|
|
1501
1152
|
|
|
1502
1153
|
/**
|
|
1503
|
-
* Função utilitária para verificar se uma URL é externa.
|
|
1504
|
-
* Se a URL começar com http:// ou https://, é considerada externa.
|
|
1154
|
+
* Função utilitária para verificar se uma URL dada é externa.
|
|
1155
|
+
* Se a URL começar com http:// ou https://, ela é considerada externa.
|
|
1505
1156
|
*/
|
|
1506
1157
|
export const checkIsExternalLink = (href?: string): boolean =>
|
|
1507
1158
|
/^https?:\/\//.test(href ?? "");
|
|
1508
1159
|
|
|
1509
1160
|
/**
|
|
1510
1161
|
* Um componente Link personalizado que adapta o atributo href com base no locale atual.
|
|
1511
|
-
* Para links internos, ele usa `getLocalizedUrl` para prefixar a URL com
|
|
1512
|
-
* Isso garante que a navegação permaneça dentro do mesmo contexto de
|
|
1513
|
-
* Ele usa uma tag <a> padrão, mas pode disparar a navegação no lado do cliente usando o `route` do preact-iso.
|
|
1162
|
+
* Para links internos, ele usa `getLocalizedUrl` para prefixar a URL com o locale (ex: /fr/about).
|
|
1163
|
+
* Isso garante que a navegação permaneça dentro do mesmo contexto de locale.
|
|
1514
1164
|
*/
|
|
1515
|
-
export const
|
|
1516
|
-
({ href, children,
|
|
1165
|
+
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
1166
|
+
({ href, children, ...props }, ref) => {
|
|
1517
1167
|
const { locale } = useLocale();
|
|
1518
|
-
const location = useLocation(); // do preact-iso
|
|
1519
1168
|
const isExternalLink = checkIsExternalLink(href);
|
|
1520
1169
|
|
|
1170
|
+
// Se o link for interno e um href válido for fornecido, obtenha a URL localizada.
|
|
1521
1171
|
const hrefI18n =
|
|
1522
1172
|
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1523
1173
|
|
|
1524
|
-
const handleClick = (event: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {
|
|
1525
|
-
if (onClick) {
|
|
1526
|
-
onClick(event);
|
|
1527
|
-
}
|
|
1528
|
-
if (
|
|
1529
|
-
!isExternalLink &&
|
|
1530
|
-
href && // Garantir que href está definido
|
|
1531
|
-
event.button === 0 && // Clique esquerdo
|
|
1532
|
-
!event.metaKey &&
|
|
1533
|
-
!event.ctrlKey &&
|
|
1534
|
-
!event.shiftKey &&
|
|
1535
|
-
!event.altKey && // Verificação padrão de modificadores
|
|
1536
|
-
!props.target // Não direcionando para uma nova aba/janela
|
|
1537
|
-
) {
|
|
1538
|
-
event.preventDefault();
|
|
1539
|
-
if (location.url !== hrefI18n) {
|
|
1540
|
-
// Navegar apenas se a URL for diferente
|
|
1541
|
-
route(hrefI18n, replace); // Usar a rota do preact-iso
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
};
|
|
1545
|
-
|
|
1546
1174
|
return (
|
|
1547
|
-
<a href={hrefI18n} ref={ref}
|
|
1175
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1548
1176
|
{children}
|
|
1549
1177
|
</a>
|
|
1550
1178
|
);
|
|
1551
1179
|
}
|
|
1552
1180
|
);
|
|
1181
|
+
|
|
1182
|
+
Link.displayName = "Link";
|
|
1553
1183
|
```
|
|
1554
1184
|
|
|
1555
|
-
```jsx fileName="src/components/
|
|
1185
|
+
```jsx fileName="src/components/Link.jsx" codeFormat="esm"
|
|
1556
1186
|
import { getLocalizedUrl } from "intlayer";
|
|
1557
1187
|
import { useLocale } from "preact-intlayer";
|
|
1558
|
-
import { useLocation, route } from "preact-iso"; // Importar de preact-iso
|
|
1559
1188
|
import { forwardRef } from "preact/compat";
|
|
1560
|
-
import { h } from "preact"; // Para JSX
|
|
1561
1189
|
|
|
1190
|
+
/**
|
|
1191
|
+
* Função utilitária para verificar se uma URL dada é externa.
|
|
1192
|
+
* Se a URL começar com http:// ou https://, ela é considerada externa.
|
|
1193
|
+
*/
|
|
1562
1194
|
export const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
|
|
1563
1195
|
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1196
|
+
/**
|
|
1197
|
+
* Um componente Link personalizado que adapta o atributo href com base no locale atual.
|
|
1198
|
+
* Para links internos, ele usa `getLocalizedUrl` para prefixar a URL com o locale (ex: /fr/about).
|
|
1199
|
+
* Isso garante que a navegação permaneça dentro do mesmo contexto de locale.
|
|
1200
|
+
*/
|
|
1201
|
+
export const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1202
|
+
const { locale } = useLocale();
|
|
1203
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1569
1204
|
|
|
1570
|
-
|
|
1571
|
-
|
|
1205
|
+
// Se o link for interno e um href válido for fornecido, obtenha a URL localizada.
|
|
1206
|
+
const hrefI18n =
|
|
1207
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1572
1208
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
href &&
|
|
1580
|
-
event.button === 0 &&
|
|
1581
|
-
!event.metaKey &&
|
|
1582
|
-
!event.ctrlKey &&
|
|
1583
|
-
!event.shiftKey &&
|
|
1584
|
-
!event.altKey &&
|
|
1585
|
-
!props.target
|
|
1586
|
-
) {
|
|
1587
|
-
event.preventDefault();
|
|
1588
|
-
if (location.url !== hrefI18n) {
|
|
1589
|
-
route(hrefI18n, replace);
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
};
|
|
1209
|
+
return (
|
|
1210
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1211
|
+
{children}
|
|
1212
|
+
</a>
|
|
1213
|
+
);
|
|
1214
|
+
});
|
|
1593
1215
|
|
|
1594
|
-
|
|
1595
|
-
<a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
|
|
1596
|
-
{children}
|
|
1597
|
-
</a>
|
|
1598
|
-
);
|
|
1599
|
-
}
|
|
1600
|
-
);
|
|
1216
|
+
Link.displayName = "Link";
|
|
1601
1217
|
```
|
|
1602
1218
|
|
|
1603
|
-
```jsx fileName="src/components/
|
|
1219
|
+
```jsx fileName="src/components/Link.cjsx" codeFormat="commonjs"
|
|
1604
1220
|
const { getLocalizedUrl } = require("intlayer");
|
|
1605
1221
|
const { useLocale } = require("preact-intlayer");
|
|
1606
|
-
const { useLocation, route } = require("preact-iso"); // Importado de preact-iso
|
|
1607
1222
|
const { forwardRef } = require("preact/compat");
|
|
1608
|
-
const { h } = require("preact"); // Para JSX
|
|
1609
1223
|
|
|
1224
|
+
/**
|
|
1225
|
+
* Função utilitária para verificar se uma URL dada é externa.
|
|
1226
|
+
* Se a URL começar com http:// ou https://, ela é considerada externa.
|
|
1227
|
+
*/
|
|
1610
1228
|
const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
|
|
1611
1229
|
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
event.preventDefault();
|
|
1636
|
-
if (location.url !== hrefI18n) {
|
|
1637
|
-
route(hrefI18n, replace);
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
};
|
|
1230
|
+
/**
|
|
1231
|
+
* Um componente Link personalizado que adapta o atributo href com base no locale atual.
|
|
1232
|
+
* Para links internos, ele usa `getLocalizedUrl` para prefixar a URL com o locale (ex: /fr/about).
|
|
1233
|
+
* Isso garante que a navegação permaneça dentro do mesmo contexto de locale.
|
|
1234
|
+
*/
|
|
1235
|
+
const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1236
|
+
const { locale } = useLocale();
|
|
1237
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1238
|
+
|
|
1239
|
+
// Se o link for interno e um href válido for fornecido, obtenha a URL localizada.
|
|
1240
|
+
const hrefI18n =
|
|
1241
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1242
|
+
|
|
1243
|
+
return h(
|
|
1244
|
+
"a",
|
|
1245
|
+
{
|
|
1246
|
+
href: hrefI18n,
|
|
1247
|
+
ref: ref,
|
|
1248
|
+
...props,
|
|
1249
|
+
},
|
|
1250
|
+
children
|
|
1251
|
+
);
|
|
1252
|
+
});
|
|
1641
1253
|
|
|
1642
|
-
|
|
1643
|
-
<a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
|
|
1644
|
-
{children}
|
|
1645
|
-
</a>
|
|
1646
|
-
);
|
|
1647
|
-
}
|
|
1648
|
-
);
|
|
1254
|
+
Link.displayName = "Link";
|
|
1649
1255
|
|
|
1650
|
-
module.exports = {
|
|
1256
|
+
module.exports = { Link, checkIsExternalLink };
|
|
1651
1257
|
```
|
|
1652
1258
|
|
|
1653
1259
|
#### Como Funciona
|
|
1654
1260
|
|
|
1655
|
-
- **
|
|
1656
|
-
A função auxiliar `checkIsExternalLink` determina se uma URL é externa. Links externos permanecem inalterados.
|
|
1657
|
-
- **Recuperando
|
|
1658
|
-
O hook `useLocale` fornece
|
|
1261
|
+
- **Detectando Links Externos**:
|
|
1262
|
+
A função auxiliar `checkIsExternalLink` determina se uma URL é externa. Links externos permanecem inalterados porque não precisam de localização.
|
|
1263
|
+
- **Recuperando o Locale Atual**:
|
|
1264
|
+
O hook `useLocale` fornece o locale atual (ex: `fr` para francês).
|
|
1659
1265
|
- **Localizando a URL**:
|
|
1660
|
-
Para links internos, `getLocalizedUrl`
|
|
1661
|
-
- **Navegação no Lado do Cliente**:
|
|
1662
|
-
A função `handleClick` verifica se o link é interno e se a navegação padrão deve ser evitada. Se for o caso, ela usa a função `route` do `preact-iso` (obtida via `useLocation` ou importada diretamente) para realizar a navegação no lado do cliente. Isso proporciona um comportamento semelhante a SPA sem recarregamentos completos da página.
|
|
1266
|
+
Para links internos (ou seja, não externos), o `getLocalizedUrl` é usado para prefixar automaticamente a URL com o locale atual. Isso significa que, se o seu usuário estiver em francês, passar `/about` como o `href` o transformará em `/fr/about`.
|
|
1663
1267
|
- **Retornando o Link**:
|
|
1664
|
-
O componente retorna um elemento `<a>` com a URL localizada
|
|
1268
|
+
O componente retorna um elemento `<a>` com a URL localizada, garantindo que a navegação seja consistente com o locale.
|
|
1269
|
+
|
|
1270
|
+
### (Opcional) Passo 11: Renderizar Markdown e HTML
|
|
1271
|
+
|
|
1272
|
+
O Intlayer suporta a renderização de conteúdo Markdown e HTML no Preact.
|
|
1273
|
+
|
|
1274
|
+
Você pode personalizar a renderização de conteúdo Markdown e HTML usando o método `.use()`. Este método permite que você substitua a renderização padrão de tags específicas.
|
|
1275
|
+
|
|
1276
|
+
```tsx
|
|
1277
|
+
import { useIntlayer } from "preact-intlayer";
|
|
1278
|
+
|
|
1279
|
+
const { myMarkdownContent, myHtmlContent } = useIntlayer("my-component");
|
|
1280
|
+
|
|
1281
|
+
// ...
|
|
1282
|
+
|
|
1283
|
+
return (
|
|
1284
|
+
<div>
|
|
1285
|
+
{/* Renderização básica */}
|
|
1286
|
+
{myMarkdownContent}
|
|
1287
|
+
|
|
1288
|
+
{/* Renderização personalizada para Markdown */}
|
|
1289
|
+
{myMarkdownContent.use({
|
|
1290
|
+
h1: (props) => <h1 style={{ color: "red" }} {...props} />,
|
|
1291
|
+
})}
|
|
1292
|
+
|
|
1293
|
+
{/* Renderização básica para HTML */}
|
|
1294
|
+
{myHtmlContent}
|
|
1295
|
+
|
|
1296
|
+
{/* Renderização personalizada para HTML */}
|
|
1297
|
+
{myHtmlContent.use({
|
|
1298
|
+
b: (props) => <strong style={{ color: "blue" }} {...props} />,
|
|
1299
|
+
})}
|
|
1300
|
+
</div>
|
|
1301
|
+
);
|
|
1302
|
+
```
|
|
1665
1303
|
|
|
1666
1304
|
### Configurar TypeScript
|
|
1667
1305
|
|
|
1668
|
-
O Intlayer usa
|
|
1306
|
+
O Intlayer usa aumento de módulo para obter benefícios do TypeScript e tornar sua base de código mais forte.
|
|
1669
1307
|
|
|
1670
1308
|

|
|
1671
1309
|
|
|
1672
1310
|

|
|
1673
1311
|
|
|
1674
|
-
|
|
1312
|
+
Certifique-se de que sua configuração do TypeScript inclua os tipos autogerados.
|
|
1675
1313
|
|
|
1676
1314
|
```json5 fileName="tsconfig.json"
|
|
1677
1315
|
{
|
|
1678
|
-
// ... Suas configurações
|
|
1316
|
+
// ... Suas configurações de TypeScript existentes
|
|
1679
1317
|
"compilerOptions": {
|
|
1680
1318
|
// ...
|
|
1681
1319
|
"jsx": "react-jsx",
|
|
@@ -1683,34 +1321,34 @@ Garanta que sua configuração do TypeScript inclua os tipos gerados automaticam
|
|
|
1683
1321
|
// ...
|
|
1684
1322
|
},
|
|
1685
1323
|
"include": [
|
|
1686
|
-
// ... Suas configurações
|
|
1687
|
-
".intlayer/**/*.ts", // Inclua os tipos
|
|
1324
|
+
// ... Suas configurações de TypeScript existentes
|
|
1325
|
+
".intlayer/**/*.ts", // Inclua os tipos autogerados
|
|
1688
1326
|
],
|
|
1689
1327
|
}
|
|
1690
1328
|
```
|
|
1691
1329
|
|
|
1692
|
-
> Certifique-se de que seu `tsconfig.json` esteja configurado para Preact, especialmente `jsx` e `jsxImportSource` ou `jsxFactory`/`jsxFragmentFactory` para versões antigas do Preact,
|
|
1330
|
+
> Certifique-se de que seu `tsconfig.json` esteja configurado para o Preact, especialmente `jsx` e `jsxImportSource` ou `jsxFactory`/`jsxFragmentFactory` para versões antigas do Preact, se não estiver usando os padrões do `preset-vite`.
|
|
1693
1331
|
|
|
1694
1332
|
### Configuração do Git
|
|
1695
1333
|
|
|
1696
|
-
|
|
1334
|
+
Recomenda-se ignorar os arquivos gerados pelo Intlayer. Isso permite que você evite comitá-los em seu repositório Git.
|
|
1697
1335
|
|
|
1698
|
-
Para isso, você pode adicionar as seguintes instruções ao seu arquivo `.gitignore`:
|
|
1336
|
+
Para fazer isso, você pode adicionar as seguintes instruções ao seu arquivo `.gitignore`:
|
|
1699
1337
|
|
|
1700
1338
|
```plaintext
|
|
1701
|
-
#
|
|
1339
|
+
# Ignore the files generated by Intlayer
|
|
1702
1340
|
.intlayer
|
|
1703
1341
|
```
|
|
1704
1342
|
|
|
1705
|
-
### Extensão VS Code
|
|
1343
|
+
### Extensão do VS Code
|
|
1706
1344
|
|
|
1707
1345
|
Para melhorar sua experiência de desenvolvimento com o Intlayer, você pode instalar a extensão oficial **Intlayer VS Code Extension**.
|
|
1708
1346
|
|
|
1709
|
-
[Instalar
|
|
1347
|
+
[Instalar a partir do VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
|
|
1710
1348
|
|
|
1711
|
-
Esta extensão
|
|
1349
|
+
Esta extensão fornece:
|
|
1712
1350
|
|
|
1713
|
-
- **
|
|
1351
|
+
- **Autocomplemento** para chaves de tradução.
|
|
1714
1352
|
- **Detecção de erros em tempo real** para traduções ausentes.
|
|
1715
1353
|
- **Visualizações inline** do conteúdo traduzido.
|
|
1716
1354
|
- **Ações rápidas** para criar e atualizar traduções facilmente.
|