@intlayer/docs 7.1.9 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cjs/generated/docs.entry.cjs +19 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +19 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_svelte_kit.md +730 -0
- package/docs/ar/intlayer_with_vite+svelte.md +288 -104
- package/docs/de/intlayer_with_svelte_kit.md +730 -0
- package/docs/de/intlayer_with_vite+svelte.md +302 -101
- package/docs/en/intlayer_with_svelte_kit.md +560 -0
- package/docs/en/intlayer_with_vite+svelte.md +22 -6
- package/docs/en/introduction.md +2 -0
- package/docs/en-GB/intlayer_with_svelte_kit.md +730 -0
- package/docs/en-GB/intlayer_with_vite+svelte.md +262 -84
- package/docs/es/intlayer_with_svelte_kit.md +730 -0
- package/docs/es/intlayer_with_vite+svelte.md +300 -107
- package/docs/fr/intlayer_with_svelte_kit.md +762 -0
- package/docs/fr/intlayer_with_vite+svelte.md +297 -101
- package/docs/hi/intlayer_with_svelte_kit.md +730 -0
- package/docs/hi/intlayer_with_vite+svelte.md +298 -108
- package/docs/id/intlayer_with_svelte_kit.md +730 -0
- package/docs/id/intlayer_with_vite+svelte.md +277 -99
- package/docs/it/intlayer_with_svelte_kit.md +762 -0
- package/docs/it/intlayer_with_vite+svelte.md +275 -99
- package/docs/ja/intlayer_with_svelte_kit.md +730 -0
- package/docs/ja/intlayer_with_vite+svelte.md +295 -110
- package/docs/ko/intlayer_with_svelte_kit.md +730 -0
- package/docs/ko/intlayer_with_vite+svelte.md +286 -199
- package/docs/pl/intlayer_with_svelte_kit.md +732 -0
- package/docs/pl/intlayer_with_vite+svelte.md +273 -101
- package/docs/pt/intlayer_with_svelte_kit.md +764 -0
- package/docs/pt/intlayer_with_vite+svelte.md +290 -96
- package/docs/ru/intlayer_with_svelte_kit.md +730 -0
- package/docs/ru/intlayer_with_vite+svelte.md +275 -99
- package/docs/tr/intlayer_with_svelte_kit.md +730 -0
- package/docs/tr/intlayer_with_vite+svelte.md +297 -119
- package/docs/vi/intlayer_with_svelte_kit.md +730 -0
- package/docs/vi/intlayer_with_vite+svelte.md +275 -102
- package/docs/zh/intlayer_with_svelte_kit.md +730 -0
- package/docs/zh/intlayer_with_vite+svelte.md +309 -107
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +19 -0
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-11-20
|
|
3
|
+
updatedAt: 2025-11-20
|
|
4
|
+
title: Como traduzir sua aplicação SvelteKit – guia i18n 2025
|
|
5
|
+
description: Descubra como tornar seu site SvelteKit multilíngue. Siga a documentação para internacionalizar (i18n) e traduzir usando Server-Side Rendering (SSR).
|
|
6
|
+
keywords:
|
|
7
|
+
- Internacionalização
|
|
8
|
+
- Documentação
|
|
9
|
+
- Intlayer
|
|
10
|
+
- SvelteKit
|
|
11
|
+
- JavaScript
|
|
12
|
+
- SSR
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- environment
|
|
16
|
+
- sveltekit
|
|
17
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-sveltekit-template
|
|
18
|
+
history:
|
|
19
|
+
- version: 7.1.10
|
|
20
|
+
date: 2025-11-20
|
|
21
|
+
changes: Histórico inicial
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Traduza seu site SvelteKit usando Intlayer | Internacionalização (i18n)
|
|
25
|
+
|
|
26
|
+
## Índice
|
|
27
|
+
|
|
28
|
+
<TOC/>
|
|
29
|
+
|
|
30
|
+
## O que é o Intlayer?
|
|
31
|
+
|
|
32
|
+
**Intlayer** é uma biblioteca inovadora e open-source de internacionalização (i18n) projetada para simplificar o suporte multilíngue em aplicações web modernas. Ela funciona perfeitamente com as capacidades de Server-Side Rendering (SSR) do **SvelteKit**.
|
|
33
|
+
|
|
34
|
+
Com o Intlayer, você pode:
|
|
35
|
+
|
|
36
|
+
- **Gerenciar traduções facilmente** usando dicionários declarativos no nível do componente.
|
|
37
|
+
- **Localizar dinamicamente metadados**, rotas e conteúdo.
|
|
38
|
+
- **Garantir suporte ao TypeScript** com tipos gerados automaticamente.
|
|
39
|
+
- **Aproveitar o SSR do SvelteKit** para uma internacionalização amigável ao SEO.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Guia Passo a Passo para Configurar o Intlayer em uma Aplicação SvelteKit
|
|
44
|
+
|
|
45
|
+
Para começar, crie um novo projeto SvelteKit. Aqui está a estrutura final que iremos criar:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
.
|
|
49
|
+
├── intlayer.config.ts
|
|
50
|
+
├── package.json
|
|
51
|
+
├── src
|
|
52
|
+
│ ├── app.d.ts
|
|
53
|
+
│ ├── app.html
|
|
54
|
+
│ ├── hooks.server.ts
|
|
55
|
+
│ ├── lib
|
|
56
|
+
│ │ ├── getLocale.ts
|
|
57
|
+
│ │ ├── LocaleSwitcher.svelte
|
|
58
|
+
│ │ └── LocalizedLink.svelte
|
|
59
|
+
│ ├── params
|
|
60
|
+
│ │ └── locale.ts
|
|
61
|
+
│ └── routes
|
|
62
|
+
│ ├── [[locale=locale]]
|
|
63
|
+
│ │ ├── +layout.svelte
|
|
64
|
+
│ │ ├── +layout.ts
|
|
65
|
+
│ │ ├── +page.svelte
|
|
66
|
+
│ │ ├── +page.ts
|
|
67
|
+
│ │ ├── about
|
|
68
|
+
│ │ │ ├── +page.svelte
|
|
69
|
+
│ │ │ ├── +page.ts
|
|
70
|
+
│ │ │ └── page.content.ts
|
|
71
|
+
│ │ ├── Counter.content.ts
|
|
72
|
+
│ │ ├── Counter.svelte
|
|
73
|
+
│ │ ├── Header.content.ts
|
|
74
|
+
│ │ ├── Header.svelte
|
|
75
|
+
│ │ ├── home.content.ts
|
|
76
|
+
│ │ └── layout.content.ts
|
|
77
|
+
│ ├── +layout.svelte
|
|
78
|
+
│ └── layout.css
|
|
79
|
+
├── static
|
|
80
|
+
│ ├── favicon.svg
|
|
81
|
+
│ └── robots.txt
|
|
82
|
+
├── svelte.config.js
|
|
83
|
+
├── tsconfig.json
|
|
84
|
+
└── vite.config.ts
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Passo 1: Instalar Dependências
|
|
88
|
+
|
|
89
|
+
Instale os pacotes necessários usando npm:
|
|
90
|
+
|
|
91
|
+
```bash packageManager="npm"
|
|
92
|
+
npm install intlayer svelte-intlayer
|
|
93
|
+
npm install vite-intlayer --save-dev
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```bash packageManager="pnpm"
|
|
97
|
+
pnpm add intlayer svelte-intlayer
|
|
98
|
+
pnpm add vite-intlayer --save-dev
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```bash packageManager="yarn"
|
|
102
|
+
yarn add intlayer svelte-intlayer
|
|
103
|
+
yarn add vite-intlayer --save-dev
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```bash packageManager="bun"
|
|
107
|
+
bun add intlayer svelte-intlayer
|
|
108
|
+
bun add vite-intlayer --save-dev
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- **intlayer**: O pacote principal de i18n.
|
|
112
|
+
- **svelte-intlayer**: Fornece context providers e stores para Svelte/SvelteKit.
|
|
113
|
+
- **vite-intlayer**: O plugin do Vite para integrar as declarações de conteúdo com o processo de build.
|
|
114
|
+
|
|
115
|
+
### Passo 2: Configuração do seu projeto
|
|
116
|
+
|
|
117
|
+
Crie um arquivo de configuração na raiz do seu projeto:
|
|
118
|
+
|
|
119
|
+
```typescript fileName="intlayer.config.ts"
|
|
120
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
121
|
+
|
|
122
|
+
const config: IntlayerConfig = {
|
|
123
|
+
internationalization: {
|
|
124
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
125
|
+
defaultLocale: Locales.ENGLISH,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export default config;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Passo 3: Integre o Intlayer na sua Configuração do Vite
|
|
133
|
+
|
|
134
|
+
Atualize seu `vite.config.ts` para incluir o plugin Intlayer. Este plugin gerencia a transpiração dos seus arquivos de conteúdo.
|
|
135
|
+
|
|
136
|
+
```typescript fileName="vite.config.ts"
|
|
137
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
138
|
+
import { defineConfig } from "vite";
|
|
139
|
+
import { intlayer } from "vite-intlayer";
|
|
140
|
+
|
|
141
|
+
export default defineConfig({
|
|
142
|
+
plugins: [intlayer(), sveltekit()], // a ordem importa, Intlayer deve ser colocado antes do SvelteKit
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Passo 4: Declare Seu Conteúdo
|
|
147
|
+
|
|
148
|
+
Crie seus arquivos de declaração de conteúdo em qualquer lugar dentro da sua pasta `src` (por exemplo, `src/lib/content` ou junto aos seus componentes). Esses arquivos definem o conteúdo traduzível para sua aplicação usando a função `t()` para cada locale.
|
|
149
|
+
|
|
150
|
+
```ts fileName="src/features/hero/hero.content.ts" contentDeclarationFormat="typescript"
|
|
151
|
+
import { t, type Dictionary } from "intlayer";
|
|
152
|
+
|
|
153
|
+
const heroContent = {
|
|
154
|
+
key: "hero-section",
|
|
155
|
+
content: {
|
|
156
|
+
title: t({
|
|
157
|
+
en: "Welcome to SvelteKit",
|
|
158
|
+
fr: "Bienvenue sur SvelteKit",
|
|
159
|
+
es: "Bienvenido a SvelteKit",
|
|
160
|
+
}),
|
|
161
|
+
},
|
|
162
|
+
} satisfies Dictionary;
|
|
163
|
+
|
|
164
|
+
export default heroContent;
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Passo 5: Utilize o Intlayer em Seus Componentes
|
|
168
|
+
|
|
169
|
+
### Passo 5: Utilize o Intlayer em Seus Componentes
|
|
170
|
+
|
|
171
|
+
Agora você pode usar a função `useIntlayer` em qualquer componente Svelte. Ela retorna uma store reativa que atualiza automaticamente quando o locale muda. A função respeitará automaticamente o locale atual (tanto durante SSR quanto na navegação do lado do cliente).
|
|
172
|
+
|
|
173
|
+
> **Nota:** `useIntlayer` retorna uma store do Svelte, então você precisa usar o prefixo `---
|
|
174
|
+
> createdAt: 2025-11-20
|
|
175
|
+
> updatedAt: 2025-11-20
|
|
176
|
+
> title: Como traduzir sua aplicação SvelteKit – guia i18n 2025
|
|
177
|
+
> description: Descubra como tornar seu site SvelteKit multilíngue. Siga a documentação para internacionalizar (i18n) e traduzir usando Server-Side Rendering (SSR).
|
|
178
|
+
> keywords:
|
|
179
|
+
|
|
180
|
+
- Internacionalização
|
|
181
|
+
- Documentação
|
|
182
|
+
- Intlayer
|
|
183
|
+
- SvelteKit
|
|
184
|
+
- JavaScript
|
|
185
|
+
- SSR
|
|
186
|
+
slugs:
|
|
187
|
+
- doc
|
|
188
|
+
- environment
|
|
189
|
+
- sveltekit
|
|
190
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-sveltekit-template
|
|
191
|
+
history:
|
|
192
|
+
- version: 7.1.10
|
|
193
|
+
date: 2025-11-20
|
|
194
|
+
changes: Histórico inicial
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
# Traduza seu site SvelteKit usando Intlayer | Internacionalização (i18n)
|
|
199
|
+
|
|
200
|
+
## Índice
|
|
201
|
+
|
|
202
|
+
<TOC/>
|
|
203
|
+
|
|
204
|
+
## O que é o Intlayer?
|
|
205
|
+
|
|
206
|
+
**Intlayer** é uma biblioteca inovadora e open-source de internacionalização (i18n) projetada para simplificar o suporte multilíngue em aplicações web modernas. Ela funciona perfeitamente com as capacidades de Server-Side Rendering (SSR) do **SvelteKit**.
|
|
207
|
+
|
|
208
|
+
Com o Intlayer, você pode:
|
|
209
|
+
|
|
210
|
+
- **Gerenciar traduções facilmente** usando dicionários declarativos no nível do componente.
|
|
211
|
+
- **Localizar dinamicamente metadados**, rotas e conteúdo.
|
|
212
|
+
- **Garantir suporte ao TypeScript** com tipos gerados automaticamente.
|
|
213
|
+
- **Aproveitar o SSR do SvelteKit** para uma internacionalização amigável ao SEO.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Guia Passo a Passo para Configurar o Intlayer em uma Aplicação SvelteKit
|
|
218
|
+
|
|
219
|
+
Para começar, crie um novo projeto SvelteKit. Aqui está a estrutura final que iremos criar:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
.
|
|
223
|
+
├── intlayer.config.ts
|
|
224
|
+
├── package.json
|
|
225
|
+
├── src
|
|
226
|
+
│ ├── app.d.ts
|
|
227
|
+
│ ├── app.html
|
|
228
|
+
│ ├── hooks.server.ts
|
|
229
|
+
│ ├── lib
|
|
230
|
+
│ │ ├── getLocale.ts
|
|
231
|
+
│ │ ├── LocaleSwitcher.svelte
|
|
232
|
+
│ │ └── LocalizedLink.svelte
|
|
233
|
+
│ ├── params
|
|
234
|
+
│ │ └── locale.ts
|
|
235
|
+
│ └── routes
|
|
236
|
+
│ ├── [[locale=locale]]
|
|
237
|
+
│ │ ├── +layout.svelte
|
|
238
|
+
│ │ ├── +layout.ts
|
|
239
|
+
│ │ ├── +page.svelte
|
|
240
|
+
│ │ ├── +page.ts
|
|
241
|
+
│ │ ├── about
|
|
242
|
+
│ │ │ ├── +page.svelte
|
|
243
|
+
│ │ │ ├── +page.ts
|
|
244
|
+
│ │ │ └── page.content.ts
|
|
245
|
+
│ │ ├── Counter.content.ts
|
|
246
|
+
│ │ ├── Counter.svelte
|
|
247
|
+
│ │ ├── Header.content.ts
|
|
248
|
+
│ │ ├── Header.svelte
|
|
249
|
+
│ │ ├── home.content.ts
|
|
250
|
+
│ │ └── layout.content.ts
|
|
251
|
+
│ ├── +layout.svelte
|
|
252
|
+
│ └── layout.css
|
|
253
|
+
├── static
|
|
254
|
+
│ ├── favicon.svg
|
|
255
|
+
│ └── robots.txt
|
|
256
|
+
├── svelte.config.js
|
|
257
|
+
├── tsconfig.json
|
|
258
|
+
└── vite.config.ts
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Passo 1: Instalar Dependências
|
|
262
|
+
|
|
263
|
+
Instale os pacotes necessários usando npm:
|
|
264
|
+
|
|
265
|
+
```bash packageManager="npm"
|
|
266
|
+
npm install intlayer svelte-intlayer
|
|
267
|
+
npm install vite-intlayer --save-dev
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```bash packageManager="pnpm"
|
|
271
|
+
pnpm add intlayer svelte-intlayer
|
|
272
|
+
pnpm add vite-intlayer --save-dev
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
```bash packageManager="yarn"
|
|
276
|
+
yarn add intlayer svelte-intlayer
|
|
277
|
+
yarn add vite-intlayer --save-dev
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
```bash packageManager="bun"
|
|
281
|
+
bun add intlayer svelte-intlayer
|
|
282
|
+
bun add vite-intlayer --save-dev
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
- **intlayer**: O pacote principal de i18n.
|
|
286
|
+
- **svelte-intlayer**: Fornece context providers e stores para Svelte/SvelteKit.
|
|
287
|
+
- **vite-intlayer**: O plugin do Vite para integrar as declarações de conteúdo com o processo de build.
|
|
288
|
+
|
|
289
|
+
### Passo 2: Configuração do seu projeto
|
|
290
|
+
|
|
291
|
+
Crie um arquivo de configuração na raiz do seu projeto:
|
|
292
|
+
|
|
293
|
+
```typescript fileName="intlayer.config.ts"
|
|
294
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
295
|
+
|
|
296
|
+
const config: IntlayerConfig = {
|
|
297
|
+
internationalization: {
|
|
298
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
299
|
+
defaultLocale: Locales.ENGLISH,
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
export default config;
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Passo 3: Integre o Intlayer na sua Configuração do Vite
|
|
307
|
+
|
|
308
|
+
Atualize seu `vite.config.ts` para incluir o plugin Intlayer. Este plugin gerencia a transpiração dos seus arquivos de conteúdo.
|
|
309
|
+
|
|
310
|
+
```typescript fileName="vite.config.ts"
|
|
311
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
312
|
+
import { defineConfig } from "vite";
|
|
313
|
+
import { intlayer } from "vite-intlayer";
|
|
314
|
+
|
|
315
|
+
export default defineConfig({
|
|
316
|
+
plugins: [intlayer(), sveltekit()], // a ordem importa, Intlayer deve ser colocado antes do SvelteKit
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Passo 4: Declare Seu Conteúdo
|
|
321
|
+
|
|
322
|
+
Crie seus arquivos de declaração de conteúdo em qualquer lugar dentro da sua pasta `src` (por exemplo, `src/lib/content` ou junto aos seus componentes). Esses arquivos definem o conteúdo traduzível para sua aplicação usando a função `t()` para cada locale.
|
|
323
|
+
|
|
324
|
+
```ts fileName="src/features/hero/hero.content.ts" contentDeclarationFormat="typescript"
|
|
325
|
+
import { t, type Dictionary } from "intlayer";
|
|
326
|
+
|
|
327
|
+
const heroContent = {
|
|
328
|
+
key: "hero-section",
|
|
329
|
+
content: {
|
|
330
|
+
title: t({
|
|
331
|
+
en: "Welcome to SvelteKit",
|
|
332
|
+
fr: "Bienvenue sur SvelteKit",
|
|
333
|
+
es: "Bienvenido a SvelteKit",
|
|
334
|
+
}),
|
|
335
|
+
},
|
|
336
|
+
} satisfies Dictionary;
|
|
337
|
+
|
|
338
|
+
export default heroContent;
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Passo 5: Utilize o Intlayer em Seus Componentes
|
|
342
|
+
|
|
343
|
+
para acessar seu valor reativo (por exemplo, `$content.title`).
|
|
344
|
+
|
|
345
|
+
```svelte fileName="src/lib/components/Component.svelte"
|
|
346
|
+
<script lang="ts">
|
|
347
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
348
|
+
|
|
349
|
+
// "hero-section" corresponde à chave definida no Passo 4
|
|
350
|
+
const content = useIntlayer("hero-section");
|
|
351
|
+
</script>
|
|
352
|
+
|
|
353
|
+
<!-- Renderizar conteúdo como conteúdo simples -->
|
|
354
|
+
<h1>{$content.title}</h1>
|
|
355
|
+
<!-- Para renderizar o conteúdo editável usando o editor -->
|
|
356
|
+
<h1><svelte:component this={$content.title} /></h1>
|
|
357
|
+
<!-- Para renderizar o conteúdo como uma string -->
|
|
358
|
+
<div aria-label={$content.title.value}></div>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### (Opcional) Passo 6: Configurar o roteamento
|
|
362
|
+
|
|
363
|
+
Os passos a seguir mostram como configurar o roteamento baseado em locale no SvelteKit. Isso permite que suas URLs incluam o prefixo do locale (ex.: `/en/about`, `/fr/about`) para melhor SEO e experiência do usuário.
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
.
|
|
367
|
+
└─── src
|
|
368
|
+
├── app.d.ts # Definir o tipo de locale
|
|
369
|
+
├── hooks.server.ts # Gerenciar o roteamento do locale
|
|
370
|
+
├── lib
|
|
371
|
+
│ └── getLocale.ts # Verificar o locale a partir do header, cookies
|
|
372
|
+
├── params
|
|
373
|
+
│ └── locale.ts # Definir o parâmetro do locale
|
|
374
|
+
└── routes
|
|
375
|
+
├── [[locale=locale]] # Envolver em um grupo de rotas para definir o locale
|
|
376
|
+
│ ├── +layout.svelte # Layout local para a rota
|
|
377
|
+
│ ├── +layout.ts
|
|
378
|
+
│ ├── +page.svelte
|
|
379
|
+
│ ├── +page.ts
|
|
380
|
+
│ └── about
|
|
381
|
+
│ ├── +page.svelte
|
|
382
|
+
│ └── +page.ts
|
|
383
|
+
└── +layout.svelte # Layout raiz para fontes e estilos globais
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Passo 7: Gerenciar a Detecção de Locale no Lado do Servidor (Hooks)
|
|
387
|
+
|
|
388
|
+
No SvelteKit, o servidor precisa saber o locale do usuário para renderizar o conteúdo correto durante o SSR. Usamos `hooks.server.ts` para detectar o locale a partir da URL ou dos cookies.
|
|
389
|
+
|
|
390
|
+
Crie ou modifique `src/hooks.server.ts`:
|
|
391
|
+
|
|
392
|
+
```typescript fileName="src/hooks.server.ts"
|
|
393
|
+
import type { Handle } from "@sveltejs/kit";
|
|
394
|
+
import { getLocalizedUrl } from "intlayer";
|
|
395
|
+
import { getLocale } from "$lib/getLocale";
|
|
396
|
+
|
|
397
|
+
export const handle: Handle = async ({ event, resolve }) => {
|
|
398
|
+
const detectedLocale = getLocale(event);
|
|
399
|
+
|
|
400
|
+
// Verifica se o caminho atual já começa com uma localidade (ex: /fr, /en)
|
|
401
|
+
const pathname = event.url.pathname;
|
|
402
|
+
const targetPathname = getLocalizedUrl(pathname, detectedLocale);
|
|
403
|
+
|
|
404
|
+
// Se NÃO houver localidade presente na URL (ex: usuário visita "/"), redireciona
|
|
405
|
+
if (targetPathname !== pathname) {
|
|
406
|
+
return new Response(undefined, {
|
|
407
|
+
headers: { Location: targetPathname },
|
|
408
|
+
status: 307, // Redirecionamento temporário
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return resolve(event, {
|
|
413
|
+
transformPageChunk: ({ html }) => html.replace("%lang%", detectedLocale),
|
|
414
|
+
});
|
|
415
|
+
};
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Em seguida, crie um helper para obter a localidade do usuário a partir do evento da requisição:
|
|
419
|
+
|
|
420
|
+
```typescript fileName="src/lib/getLocale.ts"
|
|
421
|
+
import {
|
|
422
|
+
configuration,
|
|
423
|
+
getLocaleFromStorage,
|
|
424
|
+
localeDetector,
|
|
425
|
+
type Locale,
|
|
426
|
+
} from "intlayer";
|
|
427
|
+
import type { RequestEvent } from "@sveltejs/kit";
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Obtém a localidade do usuário a partir do evento de requisição.
|
|
431
|
+
* Esta função é usada no hook `handle` em `src/hooks.server.ts`.
|
|
432
|
+
*
|
|
433
|
+
* Primeiro, tenta obter a localidade do armazenamento do Intlayer (cookies ou cabeçalhos personalizados).
|
|
434
|
+
* Se a localidade não for encontrada, recorre à negociação "Accept-Language" do navegador.
|
|
435
|
+
*
|
|
436
|
+
* @param event - O evento de requisição do SvelteKit
|
|
437
|
+
* @returns A localidade do usuário
|
|
438
|
+
*/
|
|
439
|
+
export const getLocale = (event: RequestEvent): Locale => {
|
|
440
|
+
const defaultLocale = configuration?.internationalization?.defaultLocale;
|
|
441
|
+
|
|
442
|
+
// Tenta obter a localidade do armazenamento do Intlayer (Cookies ou cabeçalhos)
|
|
443
|
+
const storedLocale = getLocaleFromStorage({
|
|
444
|
+
// Acesso aos cookies do SvelteKit
|
|
445
|
+
getCookie: (name: string) => event.cookies.get(name) ?? null,
|
|
446
|
+
// Acesso aos headers do SvelteKit
|
|
447
|
+
getHeader: (name: string) => event.request.headers.get(name) ?? null,
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
if (storedLocale) {
|
|
451
|
+
return storedLocale;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Recurso de fallback para a negociação "Accept-Language" do navegador
|
|
455
|
+
const negotiatorHeaders: Record<string, string> = {};
|
|
456
|
+
|
|
457
|
+
// Converte o objeto Headers do SvelteKit para um Record<string, string> simples
|
|
458
|
+
event.request.headers.forEach((value, key) => {
|
|
459
|
+
negotiatorHeaders[key] = value;
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
// Verifica a localidade a partir do header `Accept-Language`
|
|
463
|
+
const userFallbackLocale = localeDetector(negotiatorHeaders);
|
|
464
|
+
|
|
465
|
+
if (userFallbackLocale) {
|
|
466
|
+
return userFallbackLocale;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Retorna a localidade padrão se nenhuma correspondência for encontrada
|
|
470
|
+
return defaultLocale;
|
|
471
|
+
};
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
> `getLocaleFromStorage` verificará o locale a partir do header ou cookie dependendo da sua configuração. Veja [Configuração](https://intlayer.org/doc/configuration) para mais detalhes.
|
|
475
|
+
|
|
476
|
+
> A função `localeDetector` tratará o header `Accept-Language` e retornará a melhor correspondência.
|
|
477
|
+
|
|
478
|
+
Se o locale não estiver configurado, queremos retornar um erro 404. Para facilitar, podemos criar uma função `match` para verificar se o locale é válido:
|
|
479
|
+
|
|
480
|
+
```ts fileName="/src/params/locale.ts"
|
|
481
|
+
import { configuration, type Locale } from "intlayer";
|
|
482
|
+
|
|
483
|
+
export const match = (
|
|
484
|
+
param: Locale = configuration.internationalization.defaultLocale
|
|
485
|
+
): boolean => {
|
|
486
|
+
return configuration.internationalization.locales.includes(param);
|
|
487
|
+
};
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
> **Nota:** Certifique-se de que seu arquivo `src/app.d.ts` inclua a definição do locale:
|
|
491
|
+
>
|
|
492
|
+
> ```typescript
|
|
493
|
+
> declare global {
|
|
494
|
+
> namespace App {
|
|
495
|
+
> interface Locals {
|
|
496
|
+
> locale: import("intlayer").Locale;
|
|
497
|
+
> }
|
|
498
|
+
> }
|
|
499
|
+
> }
|
|
500
|
+
> ```
|
|
501
|
+
|
|
502
|
+
Para o arquivo `+layout.svelte`, podemos remover tudo, para manter apenas conteúdo estático, não relacionado à i18n:
|
|
503
|
+
|
|
504
|
+
```svelte fileName="src/+layout.svelte"
|
|
505
|
+
<script lang="ts">
|
|
506
|
+
import './layout.css';
|
|
507
|
+
|
|
508
|
+
let { children } = $props();
|
|
509
|
+
</script>
|
|
510
|
+
|
|
511
|
+
<div class="app">
|
|
512
|
+
{@render children()}
|
|
513
|
+
</div>
|
|
514
|
+
|
|
515
|
+
<style>
|
|
516
|
+
.app {
|
|
517
|
+
/* */
|
|
518
|
+
}
|
|
519
|
+
</style>
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Em seguida, crie uma nova página e layout dentro do grupo `[[locale=locale]]`:
|
|
523
|
+
|
|
524
|
+
```ts fileName="src/routes/[[locale=locale]]/+layout.ts"
|
|
525
|
+
import type { Load } from "@sveltejs/kit";
|
|
526
|
+
import { configuration, type Locale } from "intlayer";
|
|
527
|
+
|
|
528
|
+
export const prerender = true;
|
|
529
|
+
|
|
530
|
+
// Use o tipo genérico Load
|
|
531
|
+
export const load: Load = ({ params }) => {
|
|
532
|
+
const locale: Locale =
|
|
533
|
+
(params.locale as Locale) ??
|
|
534
|
+
configuration.internationalization.defaultLocale;
|
|
535
|
+
|
|
536
|
+
return {
|
|
537
|
+
locale,
|
|
538
|
+
};
|
|
539
|
+
};
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
```svelte fileName="src/routes/[[locale=locale]]/+layout.svelte"
|
|
543
|
+
<script lang="ts">
|
|
544
|
+
import type { Snippet } from 'svelte';
|
|
545
|
+
import { useIntlayer, setupIntlayer } from 'svelte-intlayer';
|
|
546
|
+
import Header from './Header.svelte';
|
|
547
|
+
import type { LayoutData } from './$types';
|
|
548
|
+
|
|
549
|
+
let { children, data }: { children: Snippet, data: LayoutData } = $props();
|
|
550
|
+
|
|
551
|
+
// Inicializar o Intlayer com a locale da rota
|
|
552
|
+
setupIntlayer(data.locale);
|
|
553
|
+
|
|
554
|
+
// Usar o dicionário de conteúdo do layout
|
|
555
|
+
const layoutContent = useIntlayer('layout');
|
|
556
|
+
</script>
|
|
557
|
+
|
|
558
|
+
<Header />
|
|
559
|
+
|
|
560
|
+
<main>
|
|
561
|
+
{@render children()}
|
|
562
|
+
</main>
|
|
563
|
+
|
|
564
|
+
<footer>
|
|
565
|
+
<p>
|
|
566
|
+
{$layoutContent.footer.prefix.value}{' '}
|
|
567
|
+
<a href="https://svelte.dev/docs/kit">{$layoutContent.footer.linkLabel.value}</a>{' '}
|
|
568
|
+
{$layoutContent.footer.suffix.value}
|
|
569
|
+
</p>
|
|
570
|
+
</footer>
|
|
571
|
+
|
|
572
|
+
<style>
|
|
573
|
+
/* */
|
|
574
|
+
</style>
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
```ts fileName="src/routes/[[locale=locale]]/+page.ts"
|
|
578
|
+
export const prerender = true;
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
```svelte fileName="src/routes/[[locale=locale]]/+page.svelte"
|
|
582
|
+
<script lang="ts">
|
|
583
|
+
import { useIntlayer } from 'svelte-intlayer';
|
|
584
|
+
|
|
585
|
+
// Usar o dicionário de conteúdo da home
|
|
586
|
+
const homeContent = useIntlayer('home');
|
|
587
|
+
</script>
|
|
588
|
+
|
|
589
|
+
<svelte:head>
|
|
590
|
+
<title>{$homeContent.title.value}</title>
|
|
591
|
+
</svelte:head>
|
|
592
|
+
|
|
593
|
+
<section>
|
|
594
|
+
<h1>
|
|
595
|
+
{$homeContent.title}
|
|
596
|
+
</h1>
|
|
597
|
+
</section>
|
|
598
|
+
|
|
599
|
+
<style>
|
|
600
|
+
/* */
|
|
601
|
+
</style>
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
### (Opcional) Passo 8: Links Internacionalizados
|
|
605
|
+
|
|
606
|
+
Para SEO, é recomendado prefixar suas rotas com a localidade (ex: `/en/about`, `/fr/about`). Este componente automaticamente prefixa qualquer link com a localidade atual.
|
|
607
|
+
|
|
608
|
+
```svelte fileName="src/lib/components/LocalizedLink.svelte"
|
|
609
|
+
<script lang="ts">
|
|
610
|
+
import { getLocalizedUrl } from "intlayer";
|
|
611
|
+
import { useLocale } from 'svelte-intlayer';
|
|
612
|
+
|
|
613
|
+
let { href = "" } = $props();
|
|
614
|
+
const { locale } = useLocale();
|
|
615
|
+
|
|
616
|
+
// Auxiliar para prefixar URL com a localidade atual
|
|
617
|
+
$: localizedHref = getLocalizedUrl(href, $locale);
|
|
618
|
+
</script>
|
|
619
|
+
|
|
620
|
+
<a href={localizedHref}>
|
|
621
|
+
<slot />
|
|
622
|
+
</a>
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
Se você usar `goto` do SvelteKit, pode usar a mesma lógica com `getLocalizedUrl` para navegar para a URL localizada:
|
|
626
|
+
|
|
627
|
+
```typescript
|
|
628
|
+
import { goto } from "$app/navigation";
|
|
629
|
+
import { getLocalizedUrl } from "intlayer";
|
|
630
|
+
import { useLocale } from "svelte-intlayer";
|
|
631
|
+
|
|
632
|
+
const { locale } = useLocale();
|
|
633
|
+
const localizedPath = getLocalizedUrl("/about", $locale);
|
|
634
|
+
goto(localizedPath); // Navega para /en/about ou /fr/about dependendo da localidade
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### (Opcional) Passo 9: Seletor de Idioma
|
|
638
|
+
|
|
639
|
+
Para permitir que os usuários mudem de idioma, atualize a URL.
|
|
640
|
+
|
|
641
|
+
```svelte fileName="src/lib/components/LanguageSwitcher.svelte"
|
|
642
|
+
<script lang="ts">
|
|
643
|
+
import { getLocalizedUrl, getLocaleName } from 'intlayer';
|
|
644
|
+
import { useLocale } from 'svelte-intlayer';
|
|
645
|
+
import { page } from '$app/stores';
|
|
646
|
+
import { goto } from '$app/navigation';
|
|
647
|
+
|
|
648
|
+
const { locale, setLocale, availableLocales } = useLocale({
|
|
649
|
+
onLocaleChange: (newLocale) => {
|
|
650
|
+
const localizedPath = getLocalizedUrl($page.url.pathname, newLocale);
|
|
651
|
+
goto(localizedPath);
|
|
652
|
+
},
|
|
653
|
+
});
|
|
654
|
+
</script>
|
|
655
|
+
|
|
656
|
+
<ul class="locale-list">
|
|
657
|
+
{#each availableLocales as localeEl}
|
|
658
|
+
<li>
|
|
659
|
+
<a
|
|
660
|
+
href={getLocalizedUrl($page.url.pathname, localeEl)}
|
|
661
|
+
onclick={(e) => {
|
|
662
|
+
e.preventDefault();
|
|
663
|
+
setLocale(localeEl); // Vai definir a localidade na store e disparar onLocaleChange
|
|
664
|
+
}}
|
|
665
|
+
class:active={$locale === localeEl}
|
|
666
|
+
>
|
|
667
|
+
{getLocaleName(localeEl)}
|
|
668
|
+
</a>
|
|
669
|
+
</li>
|
|
670
|
+
{/each}
|
|
671
|
+
</ul>
|
|
672
|
+
|
|
673
|
+
<style>
|
|
674
|
+
/* */
|
|
675
|
+
</style>
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### (Opcional) Passo 10: Adicionar proxy backend
|
|
679
|
+
|
|
680
|
+
Para adicionar um proxy backend à sua aplicação SvelteKit, você pode usar a função `intlayerProxy` fornecida pelo plugin `vite-intlayer`. Este plugin detectará automaticamente a melhor localidade para o usuário com base na URL, cookies e preferências de idioma do navegador.
|
|
681
|
+
|
|
682
|
+
```ts fileName="vite.config.ts"
|
|
683
|
+
import { defineConfig } from "vite";
|
|
684
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
685
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
686
|
+
|
|
687
|
+
// https://vitejs.dev/config/
|
|
688
|
+
export default defineConfig({
|
|
689
|
+
plugins: [intlayer(), intlayerProxy(), sveltekit()],
|
|
690
|
+
});
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
### (Opcional) Passo 11: Configurar o editor / CMS do intlayer
|
|
694
|
+
|
|
695
|
+
Para configurar o editor do intlayer, você deve seguir a [documentação do editor intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_visual_editor.md).
|
|
696
|
+
|
|
697
|
+
Para configurar o CMS do intlayer, você deve seguir a [documentação do CMS intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_CMS.md).
|
|
698
|
+
|
|
699
|
+
Para poder visualizar o seletor do editor intlayer, você deverá usar a sintaxe de componente no seu conteúdo intlayer.
|
|
700
|
+
|
|
701
|
+
```svelte fileName="Component.svelte"
|
|
702
|
+
<script lang="ts">
|
|
703
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
704
|
+
|
|
705
|
+
const content = useIntlayer("component");
|
|
706
|
+
</script>
|
|
707
|
+
|
|
708
|
+
<div>
|
|
709
|
+
|
|
710
|
+
<!-- Renderizar conteúdo como conteúdo simples -->
|
|
711
|
+
<h1>{$content.title}</h1>
|
|
712
|
+
|
|
713
|
+
<!-- Renderizar conteúdo como um componente (requerido pelo editor) -->
|
|
714
|
+
<svelte:component this={$content.component} />
|
|
715
|
+
</div>
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### Configuração do Git
|
|
719
|
+
|
|
720
|
+
É recomendado ignorar os arquivos gerados pelo Intlayer.
|
|
721
|
+
|
|
722
|
+
```plaintext fileName=".gitignore"
|
|
723
|
+
# Ignorar os arquivos gerados pelo Intlayer
|
|
724
|
+
.intlayer
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
---
|
|
728
|
+
|
|
729
|
+
### Ir Além
|
|
730
|
+
|
|
731
|
+
Para poder visualizar o seletor do editor intlayer, você terá que usar a sintaxe de componente no seu conteúdo intlayer.
|
|
732
|
+
|
|
733
|
+
```svelte fileName="Component.svelte"
|
|
734
|
+
<script lang="ts">
|
|
735
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
736
|
+
|
|
737
|
+
const content = useIntlayer("component");
|
|
738
|
+
</script>
|
|
739
|
+
|
|
740
|
+
<div>
|
|
741
|
+
|
|
742
|
+
<!-- Renderizar conteúdo como conteúdo simples -->
|
|
743
|
+
<h1>{$content.title}</h1>
|
|
744
|
+
|
|
745
|
+
<!-- Renderizar conteúdo como um componente (requerido pelo editor) -->
|
|
746
|
+
<svelte:component this={$content.component} />
|
|
747
|
+
</div>
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
### Configuração do Git
|
|
751
|
+
|
|
752
|
+
É recomendado ignorar os arquivos gerados pelo Intlayer.
|
|
753
|
+
|
|
754
|
+
```plaintext fileName=".gitignore"
|
|
755
|
+
# Ignorar os arquivos gerados pelo Intlayer
|
|
756
|
+
.intlayer
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
---
|
|
760
|
+
|
|
761
|
+
### Ir Além
|
|
762
|
+
|
|
763
|
+
- **Editor Visual**: Integre o [Editor Visual Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_visual_editor.md) para editar traduções diretamente pela interface.
|
|
764
|
+
- **CMS**: Externalize o gerenciamento do seu conteúdo usando o [CMS Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_CMS.md).
|