@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,730 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-11-20
|
|
3
|
+
updatedAt: 2025-11-20
|
|
4
|
+
title: Как перевести ваше приложение SvelteKit – руководство по i18n 2025
|
|
5
|
+
description: Узнайте, как сделать ваш сайт на SvelteKit многоязычным. Следуйте документации по интернационализации (i18n) и переводу с использованием серверного рендеринга (SSR).
|
|
6
|
+
keywords:
|
|
7
|
+
- Интернационализация
|
|
8
|
+
- Документация
|
|
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: Инициализация истории
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Перевод вашего сайта на SvelteKit с помощью Intlayer | Интернационализация (i18n)
|
|
25
|
+
|
|
26
|
+
## Содержание
|
|
27
|
+
|
|
28
|
+
<TOC/>
|
|
29
|
+
|
|
30
|
+
## Что такое Intlayer?
|
|
31
|
+
|
|
32
|
+
**Intlayer** — это инновационная, с открытым исходным кодом библиотека интернационализации (i18n), разработанная для упрощения поддержки многоязычности в современных веб-приложениях. Она отлично интегрируется с возможностями серверного рендеринга (SSR) в **SvelteKit**.
|
|
33
|
+
|
|
34
|
+
С помощью Intlayer вы можете:
|
|
35
|
+
|
|
36
|
+
- **Легко управлять переводами** с использованием декларативных словарей на уровне компонентов.
|
|
37
|
+
- **Динамически локализовать метаданные**, маршруты и контент.
|
|
38
|
+
- **Обеспечить поддержку TypeScript** с помощью автогенерируемых типов.
|
|
39
|
+
- **Использовать SSR SvelteKit** для SEO-оптимизированной интернационализации.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Пошаговое руководство по настройке Intlayer в приложении SvelteKit
|
|
44
|
+
|
|
45
|
+
Для начала создайте новый проект SvelteKit. Вот итоговая структура, которую мы создадим:
|
|
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
|
+
### Шаг 1: Установка зависимостей
|
|
88
|
+
|
|
89
|
+
Установите необходимые пакеты с помощью 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**: Основной пакет для i18n.
|
|
112
|
+
- **svelte-intlayer**: Предоставляет провайдеры контекста и сторы для Svelte/SvelteKit.
|
|
113
|
+
- **vite-intlayer**: Плагин Vite для интеграции деклараций контента в процесс сборки.
|
|
114
|
+
|
|
115
|
+
### Шаг 2: Конфигурация вашего проекта
|
|
116
|
+
|
|
117
|
+
Создайте файл конфигурации в корне вашего проекта:
|
|
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
|
+
### Шаг 3: Интеграция Intlayer в конфигурацию Vite
|
|
133
|
+
|
|
134
|
+
Обновите ваш файл `vite.config.ts`, чтобы включить плагин Intlayer. Этот плагин отвечает за транспиляцию ваших файлов с контентом.
|
|
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()], // порядок важен, Intlayer должен быть размещён перед SvelteKit
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Шаг 4: Объявите ваш контент
|
|
147
|
+
|
|
148
|
+
Создайте файлы объявления контента в любом месте внутри папки `src` (например, `src/lib/content` или рядом с вашими компонентами). Эти файлы определяют переводимый контент для вашего приложения с использованием функции `t()` для каждой локали.
|
|
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
|
+
### Шаг 5: Используйте Intlayer в ваших компонентах
|
|
168
|
+
|
|
169
|
+
Теперь вы можете использовать функцию `useIntlayer` в любом Svelte-компоненте. Она возвращает реактивный store, который автоматически обновляется при изменении локали. Функция автоматически учитывает текущую локаль (как во время SSR, так и при навигации на клиенте).
|
|
170
|
+
|
|
171
|
+
> **Примечание:** `useIntlayer` возвращает Svelte store, поэтому для доступа к его реактивному значению нужно использовать префикс `---
|
|
172
|
+
> createdAt: 2025-11-20
|
|
173
|
+
> updatedAt: 2025-11-20
|
|
174
|
+
> title: Как перевести ваше приложение SvelteKit – руководство по i18n 2025
|
|
175
|
+
> description: Узнайте, как сделать ваш сайт на SvelteKit многоязычным. Следуйте документации по интернационализации (i18n) и переводу с использованием серверного рендеринга (SSR).
|
|
176
|
+
> keywords:
|
|
177
|
+
|
|
178
|
+
- Интернационализация
|
|
179
|
+
- Документация
|
|
180
|
+
- Intlayer
|
|
181
|
+
- SvelteKit
|
|
182
|
+
- JavaScript
|
|
183
|
+
- SSR
|
|
184
|
+
slugs:
|
|
185
|
+
- doc
|
|
186
|
+
- environment
|
|
187
|
+
- sveltekit
|
|
188
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-sveltekit-template
|
|
189
|
+
history:
|
|
190
|
+
- version: 7.1.10
|
|
191
|
+
date: 2025-11-20
|
|
192
|
+
changes: Инициализация истории
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
# Перевод вашего сайта на SvelteKit с помощью Intlayer | Интернационализация (i18n)
|
|
197
|
+
|
|
198
|
+
## Содержание
|
|
199
|
+
|
|
200
|
+
<TOC/>
|
|
201
|
+
|
|
202
|
+
## Что такое Intlayer?
|
|
203
|
+
|
|
204
|
+
**Intlayer** — это инновационная, с открытым исходным кодом библиотека интернационализации (i18n), разработанная для упрощения поддержки многоязычности в современных веб-приложениях. Она отлично интегрируется с возможностями серверного рендеринга (SSR) в **SvelteKit**.
|
|
205
|
+
|
|
206
|
+
С помощью Intlayer вы можете:
|
|
207
|
+
|
|
208
|
+
- **Легко управлять переводами** с использованием декларативных словарей на уровне компонентов.
|
|
209
|
+
- **Динамически локализовать метаданные**, маршруты и контент.
|
|
210
|
+
- **Обеспечить поддержку TypeScript** с помощью автогенерируемых типов.
|
|
211
|
+
- **Использовать SSR SvelteKit** для SEO-оптимизированной интернационализации.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Пошаговое руководство по настройке Intlayer в приложении SvelteKit
|
|
216
|
+
|
|
217
|
+
Для начала создайте новый проект SvelteKit. Вот итоговая структура, которую мы создадим:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
.
|
|
221
|
+
├── intlayer.config.ts
|
|
222
|
+
├── package.json
|
|
223
|
+
├── src
|
|
224
|
+
│ ├── app.d.ts
|
|
225
|
+
│ ├── app.html
|
|
226
|
+
│ ├── hooks.server.ts
|
|
227
|
+
│ ├── lib
|
|
228
|
+
│ │ ├── getLocale.ts
|
|
229
|
+
│ │ ├── LocaleSwitcher.svelte
|
|
230
|
+
│ │ └── LocalizedLink.svelte
|
|
231
|
+
│ ├── params
|
|
232
|
+
│ │ └── locale.ts
|
|
233
|
+
│ └── routes
|
|
234
|
+
│ ├── [[locale=locale]]
|
|
235
|
+
│ │ ├── +layout.svelte
|
|
236
|
+
│ │ ├── +layout.ts
|
|
237
|
+
│ │ ├── +page.svelte
|
|
238
|
+
│ │ ├── +page.ts
|
|
239
|
+
│ │ ├── about
|
|
240
|
+
│ │ │ ├── +page.svelte
|
|
241
|
+
│ │ │ ├── +page.ts
|
|
242
|
+
│ │ │ └── page.content.ts
|
|
243
|
+
│ │ ├── Counter.content.ts
|
|
244
|
+
│ │ ├── Counter.svelte
|
|
245
|
+
│ │ ├── Header.content.ts
|
|
246
|
+
│ │ ├── Header.svelte
|
|
247
|
+
│ │ ├── home.content.ts
|
|
248
|
+
│ │ └── layout.content.ts
|
|
249
|
+
│ ├── +layout.svelte
|
|
250
|
+
│ └── layout.css
|
|
251
|
+
├── static
|
|
252
|
+
│ ├── favicon.svg
|
|
253
|
+
│ └── robots.txt
|
|
254
|
+
├── svelte.config.js
|
|
255
|
+
├── tsconfig.json
|
|
256
|
+
└── vite.config.ts
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Шаг 1: Установка зависимостей
|
|
260
|
+
|
|
261
|
+
Установите необходимые пакеты с помощью npm:
|
|
262
|
+
|
|
263
|
+
```bash packageManager="npm"
|
|
264
|
+
npm install intlayer svelte-intlayer
|
|
265
|
+
npm install vite-intlayer --save-dev
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```bash packageManager="pnpm"
|
|
269
|
+
pnpm add intlayer svelte-intlayer
|
|
270
|
+
pnpm add vite-intlayer --save-dev
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
```bash packageManager="yarn"
|
|
274
|
+
yarn add intlayer svelte-intlayer
|
|
275
|
+
yarn add vite-intlayer --save-dev
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
```bash packageManager="bun"
|
|
279
|
+
bun add intlayer svelte-intlayer
|
|
280
|
+
bun add vite-intlayer --save-dev
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
- **intlayer**: Основной пакет для i18n.
|
|
284
|
+
- **svelte-intlayer**: Предоставляет провайдеры контекста и сторы для Svelte/SvelteKit.
|
|
285
|
+
- **vite-intlayer**: Плагин Vite для интеграции деклараций контента в процесс сборки.
|
|
286
|
+
|
|
287
|
+
### Шаг 2: Конфигурация вашего проекта
|
|
288
|
+
|
|
289
|
+
Создайте файл конфигурации в корне вашего проекта:
|
|
290
|
+
|
|
291
|
+
```typescript fileName="intlayer.config.ts"
|
|
292
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
293
|
+
|
|
294
|
+
const config: IntlayerConfig = {
|
|
295
|
+
internationalization: {
|
|
296
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], // локали, поддерживаемые в проекте
|
|
297
|
+
defaultLocale: Locales.ENGLISH, // локаль по умолчанию
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
export default config;
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Шаг 3: Интеграция Intlayer в конфигурацию Vite
|
|
305
|
+
|
|
306
|
+
Обновите ваш файл `vite.config.ts`, чтобы включить плагин Intlayer. Этот плагин отвечает за транспиляцию ваших файлов с контентом.
|
|
307
|
+
|
|
308
|
+
```typescript fileName="vite.config.ts"
|
|
309
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
310
|
+
import { defineConfig } from "vite";
|
|
311
|
+
import { intlayer } from "vite-intlayer";
|
|
312
|
+
|
|
313
|
+
export default defineConfig({
|
|
314
|
+
plugins: [intlayer(), sveltekit()], // порядок важен, Intlayer должен быть размещён перед SvelteKit
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Шаг 4: Объявите ваш контент
|
|
319
|
+
|
|
320
|
+
Создайте файлы объявления контента в любом месте внутри папки `src` (например, `src/lib/content` или рядом с вашими компонентами). Эти файлы определяют переводимый контент для вашего приложения с использованием функции `t()` для каждой локали.
|
|
321
|
+
|
|
322
|
+
```ts fileName="src/features/hero/hero.content.ts" contentDeclarationFormat="typescript"
|
|
323
|
+
import { t, type Dictionary } from "intlayer";
|
|
324
|
+
|
|
325
|
+
const heroContent = {
|
|
326
|
+
key: "hero-section",
|
|
327
|
+
content: {
|
|
328
|
+
title: t({
|
|
329
|
+
en: "Welcome to SvelteKit", // приветствие на английском
|
|
330
|
+
fr: "Bienvenue sur SvelteKit", // приветствие на французском
|
|
331
|
+
es: "Bienvenido a SvelteKit", // приветствие на испанском
|
|
332
|
+
}),
|
|
333
|
+
},
|
|
334
|
+
} satisfies Dictionary;
|
|
335
|
+
|
|
336
|
+
export default heroContent;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Шаг 5: Используйте Intlayer в ваших компонентах
|
|
340
|
+
|
|
341
|
+
(например, `$content.title`).
|
|
342
|
+
|
|
343
|
+
```svelte fileName="src/lib/components/Component.svelte"
|
|
344
|
+
<script lang="ts">
|
|
345
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
346
|
+
|
|
347
|
+
// "hero-section" соответствует ключу, определённому на Шаге 4
|
|
348
|
+
const content = useIntlayer("hero-section");
|
|
349
|
+
</script>
|
|
350
|
+
|
|
351
|
+
<!-- Отобразить контент как простой текст -->
|
|
352
|
+
<h1>{$content.title}</h1>
|
|
353
|
+
<!-- Чтобы отобразить контент с возможностью редактирования через редактор -->
|
|
354
|
+
<h1><svelte:component this={$content.title} /></h1>
|
|
355
|
+
<!-- Для отображения содержимого в виде строки -->
|
|
356
|
+
<div aria-label={$content.title.value}></div>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### (Необязательно) Шаг 6: Настройка маршрутизации
|
|
360
|
+
|
|
361
|
+
Следующие шаги показывают, как настроить маршрутизацию на основе локали в SvelteKit. Это позволяет вашим URL включать префикс локали (например, `/en/about`, `/fr/about`) для улучшения SEO и удобства пользователей.
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
.
|
|
365
|
+
└─── src
|
|
366
|
+
├── app.d.ts # Определение типа локали
|
|
367
|
+
├── hooks.server.ts # Управление маршрутизацией локали
|
|
368
|
+
├── lib
|
|
369
|
+
│ └── getLocale.ts # Проверка локали из заголовка, cookies
|
|
370
|
+
├── params
|
|
371
|
+
│ └── locale.ts # Определение параметра локали
|
|
372
|
+
└── routes
|
|
373
|
+
├── [[locale=locale]] # Обертка в группу маршрутов для установки локали
|
|
374
|
+
│ ├── +layout.svelte # Локальный layout для маршрута
|
|
375
|
+
│ ├── +layout.ts
|
|
376
|
+
│ ├── +page.svelte
|
|
377
|
+
│ ├── +page.ts
|
|
378
|
+
│ └── about
|
|
379
|
+
│ ├── +page.svelte
|
|
380
|
+
│ └── +page.ts
|
|
381
|
+
└── +layout.svelte # Корневой layout для шрифтов и глобальных стилей
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Шаг 7: Обработка определения локали на стороне сервера (Hooks)
|
|
385
|
+
|
|
386
|
+
В SvelteKit сервер должен знать локаль пользователя, чтобы отобразить правильный контент во время SSR. Мы используем `hooks.server.ts` для определения локали из URL или cookies.
|
|
387
|
+
|
|
388
|
+
Создайте или измените файл `src/hooks.server.ts`:
|
|
389
|
+
|
|
390
|
+
```typescript fileName="src/hooks.server.ts"
|
|
391
|
+
import type { Handle } from "@sveltejs/kit";
|
|
392
|
+
import { getLocalizedUrl } from "intlayer";
|
|
393
|
+
import { getLocale } from "$lib/getLocale";
|
|
394
|
+
|
|
395
|
+
export const handle: Handle = async ({ event, resolve }) => {
|
|
396
|
+
const detectedLocale = getLocale(event);
|
|
397
|
+
|
|
398
|
+
// Проверяем, начинается ли текущий путь с локали (например, /fr, /en)
|
|
399
|
+
const pathname = event.url.pathname;
|
|
400
|
+
const targetPathname = getLocalizedUrl(pathname, detectedLocale);
|
|
401
|
+
|
|
402
|
+
// Если локаль отсутствует в URL (например, пользователь заходит на "/"), перенаправляем его
|
|
403
|
+
if (targetPathname !== pathname) {
|
|
404
|
+
return new Response(undefined, {
|
|
405
|
+
headers: { Location: targetPathname },
|
|
406
|
+
status: 307, // Временное перенаправление
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return resolve(event, {
|
|
411
|
+
transformPageChunk: ({ html }) => html.replace("%lang%", detectedLocale),
|
|
412
|
+
});
|
|
413
|
+
};
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Затем создайте помощник для получения локали пользователя из события запроса:
|
|
417
|
+
|
|
418
|
+
```typescript fileName="src/lib/getLocale.ts"
|
|
419
|
+
import {
|
|
420
|
+
configuration,
|
|
421
|
+
getLocaleFromStorage,
|
|
422
|
+
localeDetector,
|
|
423
|
+
type Locale,
|
|
424
|
+
} from "intlayer";
|
|
425
|
+
import type { RequestEvent } from "@sveltejs/kit";
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Получить локаль пользователя из события запроса.
|
|
429
|
+
* Эта функция используется в хуке `handle` в `src/hooks.server.ts`.
|
|
430
|
+
*
|
|
431
|
+
* Сначала пытается получить локаль из хранилища Intlayer (cookies или пользовательские заголовки).
|
|
432
|
+
* Если локаль не найдена, используется fallback на браузерное определение через "Accept-Language".
|
|
433
|
+
*
|
|
434
|
+
* @param event - Событие запроса из SvelteKit
|
|
435
|
+
* @returns Локаль пользователя
|
|
436
|
+
*/
|
|
437
|
+
export const getLocale = (event: RequestEvent): Locale => {
|
|
438
|
+
const defaultLocale = configuration?.internationalization?.defaultLocale;
|
|
439
|
+
|
|
440
|
+
// Попытка получить локаль из хранилища Intlayer (Cookies или заголовки)
|
|
441
|
+
const storedLocale = getLocaleFromStorage({
|
|
442
|
+
// Доступ к cookies в SvelteKit
|
|
443
|
+
getCookie: (name: string) => event.cookies.get(name) ?? null,
|
|
444
|
+
// Доступ к заголовкам в SvelteKit
|
|
445
|
+
getHeader: (name: string) => event.request.headers.get(name) ?? null,
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
if (storedLocale) {
|
|
449
|
+
return storedLocale;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Запасной вариант: определение локали через браузерный заголовок "Accept-Language"
|
|
453
|
+
const negotiatorHeaders: Record<string, string> = {};
|
|
454
|
+
|
|
455
|
+
// Преобразование объекта Headers из SvelteKit в простой Record<string, string>
|
|
456
|
+
event.request.headers.forEach((value, key) => {
|
|
457
|
+
negotiatorHeaders[key] = value;
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// Проверка локали из заголовка `Accept-Language`
|
|
461
|
+
const userFallbackLocale = localeDetector(negotiatorHeaders);
|
|
462
|
+
|
|
463
|
+
if (userFallbackLocale) {
|
|
464
|
+
return userFallbackLocale;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Возврат локали по умолчанию, если совпадений не найдено
|
|
468
|
+
return defaultLocale;
|
|
469
|
+
};
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
> `getLocaleFromStorage` будет проверять локаль из заголовка или cookie в зависимости от вашей конфигурации. Подробнее смотрите в разделе [Configuration](https://intlayer.org/doc/configuration).
|
|
473
|
+
|
|
474
|
+
> Функция `localeDetector` обрабатывает заголовок `Accept-Language` и возвращает наилучшее совпадение.
|
|
475
|
+
|
|
476
|
+
Если локаль не настроена, мы хотим возвращать ошибку 404. Чтобы упростить это, можно создать функцию `match` для проверки валидности локали:
|
|
477
|
+
|
|
478
|
+
```ts fileName="/src/params/locale.ts"
|
|
479
|
+
import { configuration, type Locale } from "intlayer";
|
|
480
|
+
|
|
481
|
+
export const match = (
|
|
482
|
+
param: Locale = configuration.internationalization.defaultLocale
|
|
483
|
+
): boolean => {
|
|
484
|
+
return configuration.internationalization.locales.includes(param);
|
|
485
|
+
};
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
> **Примечание:** Убедитесь, что в вашем файле `src/app.d.ts` определена локаль:
|
|
489
|
+
>
|
|
490
|
+
> ```typescript
|
|
491
|
+
> declare global {
|
|
492
|
+
> namespace App {
|
|
493
|
+
> interface Locals {
|
|
494
|
+
> locale: import("intlayer").Locale;
|
|
495
|
+
> }
|
|
496
|
+
> }
|
|
497
|
+
> }
|
|
498
|
+
> ```
|
|
499
|
+
|
|
500
|
+
Для файла `+layout.svelte` мы можем удалить всё, чтобы оставить только статический контент, не связанный с i18n:
|
|
501
|
+
|
|
502
|
+
```svelte fileName="src/+layout.svelte"
|
|
503
|
+
<script lang="ts">
|
|
504
|
+
import './layout.css';
|
|
505
|
+
|
|
506
|
+
let { children } = $props();
|
|
507
|
+
</script>
|
|
508
|
+
|
|
509
|
+
<div class="app">
|
|
510
|
+
{@render children()}
|
|
511
|
+
</div>
|
|
512
|
+
|
|
513
|
+
<style>
|
|
514
|
+
.app {
|
|
515
|
+
/* */
|
|
516
|
+
}
|
|
517
|
+
</style>
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Затем создайте новую страницу и layout в группе `[[locale=locale]]`:
|
|
521
|
+
|
|
522
|
+
```ts fileName="src/routes/[[locale=locale]]/+layout.ts"
|
|
523
|
+
import type { Load } from "@sveltejs/kit";
|
|
524
|
+
import { configuration, type Locale } from "intlayer";
|
|
525
|
+
|
|
526
|
+
export const prerender = true;
|
|
527
|
+
|
|
528
|
+
// Используем универсальный тип Load
|
|
529
|
+
export const load: Load = ({ params }) => {
|
|
530
|
+
const locale: Locale =
|
|
531
|
+
(params.locale as Locale) ??
|
|
532
|
+
configuration.internationalization.defaultLocale;
|
|
533
|
+
|
|
534
|
+
return {
|
|
535
|
+
locale,
|
|
536
|
+
};
|
|
537
|
+
};
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
```svelte fileName="src/routes/[[locale=locale]]/+layout.svelte"
|
|
541
|
+
<script lang="ts">
|
|
542
|
+
import type { Snippet } from 'svelte';
|
|
543
|
+
import { useIntlayer, setupIntlayer } from 'svelte-intlayer';
|
|
544
|
+
import Header from './Header.svelte';
|
|
545
|
+
import type { LayoutData } from './$types';
|
|
546
|
+
|
|
547
|
+
let { children, data }: { children: Snippet, data: LayoutData } = $props();
|
|
548
|
+
|
|
549
|
+
// Инициализация Intlayer с локалью из маршрута
|
|
550
|
+
setupIntlayer(data.locale);
|
|
551
|
+
|
|
552
|
+
// Использование словаря контента для layout
|
|
553
|
+
const layoutContent = useIntlayer('layout');
|
|
554
|
+
</script>
|
|
555
|
+
|
|
556
|
+
<Header />
|
|
557
|
+
|
|
558
|
+
<main>
|
|
559
|
+
{@render children()}
|
|
560
|
+
</main>
|
|
561
|
+
|
|
562
|
+
<footer>
|
|
563
|
+
<p>
|
|
564
|
+
{$layoutContent.footer.prefix.value}{' '}
|
|
565
|
+
<a href="https://svelte.dev/docs/kit">{$layoutContent.footer.linkLabel.value}</a>{' '}
|
|
566
|
+
{$layoutContent.footer.suffix.value}
|
|
567
|
+
</p>
|
|
568
|
+
</footer>
|
|
569
|
+
|
|
570
|
+
<style>
|
|
571
|
+
/* */
|
|
572
|
+
</style>
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
```ts fileName="src/routes/[[locale=locale]]/+page.ts"
|
|
576
|
+
export const prerender = true;
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
```svelte fileName="src/routes/[[locale=locale]]/+page.svelte"
|
|
580
|
+
<script lang="ts">
|
|
581
|
+
import { useIntlayer } from 'svelte-intlayer';
|
|
582
|
+
|
|
583
|
+
// Использование словаря контента для домашней страницы
|
|
584
|
+
const homeContent = useIntlayer('home');
|
|
585
|
+
</script>
|
|
586
|
+
|
|
587
|
+
<svelte:head>
|
|
588
|
+
<title>{$homeContent.title.value}</title>
|
|
589
|
+
</svelte:head>
|
|
590
|
+
|
|
591
|
+
<section>
|
|
592
|
+
<h1>
|
|
593
|
+
{$homeContent.title}
|
|
594
|
+
</h1>
|
|
595
|
+
</section>
|
|
596
|
+
|
|
597
|
+
<style>
|
|
598
|
+
/* */
|
|
599
|
+
</style>
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### (Необязательно) Шаг 8: Интернационализированные ссылки
|
|
603
|
+
|
|
604
|
+
Для SEO рекомендуется добавлять префикс локали к вашим маршрутам (например, `/en/about`, `/fr/about`). Этот компонент автоматически добавляет префикс текущей локали ко всем ссылкам.
|
|
605
|
+
|
|
606
|
+
```svelte fileName="src/lib/components/LocalizedLink.svelte"
|
|
607
|
+
<script lang="ts">
|
|
608
|
+
import { getLocalizedUrl } from "intlayer";
|
|
609
|
+
import { useLocale } from 'svelte-intlayer';
|
|
610
|
+
|
|
611
|
+
let { href = "" } = $props();
|
|
612
|
+
const { locale } = useLocale();
|
|
613
|
+
|
|
614
|
+
// Помощник для добавления префикса локали к URL
|
|
615
|
+
$: localizedHref = getLocalizedUrl(href, $locale);
|
|
616
|
+
</script>
|
|
617
|
+
|
|
618
|
+
<a href={localizedHref}>
|
|
619
|
+
<slot />
|
|
620
|
+
</a>
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
Если вы используете `goto` из SvelteKit, вы можете применить ту же логику с `getLocalizedUrl` для перехода по локализованному URL:
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
import { goto } from "$app/navigation";
|
|
627
|
+
import { getLocalizedUrl } from "intlayer";
|
|
628
|
+
import { useLocale } from "svelte-intlayer";
|
|
629
|
+
|
|
630
|
+
const { locale } = useLocale();
|
|
631
|
+
const localizedPath = getLocalizedUrl("/about", $locale);
|
|
632
|
+
goto(localizedPath); // Переходит на /en/about или /fr/about в зависимости от локали
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### (Необязательно) Шаг 9: Переключатель языка
|
|
636
|
+
|
|
637
|
+
Чтобы позволить пользователям переключать языки, обновляйте URL.
|
|
638
|
+
|
|
639
|
+
```svelte fileName="src/lib/components/LanguageSwitcher.svelte"
|
|
640
|
+
<script lang="ts">
|
|
641
|
+
import { getLocalizedUrl, getLocaleName } from 'intlayer';
|
|
642
|
+
import { useLocale } from 'svelte-intlayer';
|
|
643
|
+
import { page } from '$app/stores';
|
|
644
|
+
import { goto } from '$app/navigation';
|
|
645
|
+
|
|
646
|
+
const { locale, setLocale, availableLocales } = useLocale({
|
|
647
|
+
onLocaleChange: (newLocale) => {
|
|
648
|
+
const localizedPath = getLocalizedUrl($page.url.pathname, newLocale);
|
|
649
|
+
goto(localizedPath);
|
|
650
|
+
},
|
|
651
|
+
});
|
|
652
|
+
</script>
|
|
653
|
+
|
|
654
|
+
<ul class="locale-list">
|
|
655
|
+
{#each availableLocales as localeEl}
|
|
656
|
+
<li>
|
|
657
|
+
<a
|
|
658
|
+
href={getLocalizedUrl($page.url.pathname, localeEl)}
|
|
659
|
+
onclick={(e) => {
|
|
660
|
+
e.preventDefault();
|
|
661
|
+
setLocale(localeEl); // Установит локаль в хранилище и вызовет onLocaleChange
|
|
662
|
+
}}
|
|
663
|
+
class:active={$locale === localeEl}
|
|
664
|
+
>
|
|
665
|
+
{getLocaleName(localeEl)}
|
|
666
|
+
</a>
|
|
667
|
+
</li>
|
|
668
|
+
{/each}
|
|
669
|
+
</ul>
|
|
670
|
+
|
|
671
|
+
<style>
|
|
672
|
+
/* */
|
|
673
|
+
</style>
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### (Необязательно) Шаг 10: Добавить backend proxy
|
|
677
|
+
|
|
678
|
+
Чтобы добавить backend proxy в ваше приложение SvelteKit, вы можете использовать функцию `intlayerProxy`, предоставляемую плагином `vite-intlayer`. Этот плагин автоматически определит лучшую локаль для пользователя на основе URL, cookies и предпочтений языка браузера.
|
|
679
|
+
|
|
680
|
+
```ts fileName="vite.config.ts"
|
|
681
|
+
import { defineConfig } from "vite";
|
|
682
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
683
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
684
|
+
|
|
685
|
+
// https://vitejs.dev/config/
|
|
686
|
+
export default defineConfig({
|
|
687
|
+
plugins: [intlayer(), intlayerProxy(), sveltekit()],
|
|
688
|
+
});
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### (Необязательно) Шаг 11: Настройка редактора / CMS intlayer
|
|
692
|
+
|
|
693
|
+
Для настройки редактора intlayer необходимо следовать [документации редактора intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/intlayer_visual_editor.md).
|
|
694
|
+
|
|
695
|
+
Для настройки CMS intlayer необходимо следовать [документации CMS intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/intlayer_CMS.md).
|
|
696
|
+
|
|
697
|
+
Чтобы иметь возможность визуализировать селектор редактора intlayer, вам нужно использовать синтаксис компонента в вашем контенте intlayer.
|
|
698
|
+
|
|
699
|
+
```svelte fileName="Component.svelte"
|
|
700
|
+
<script lang="ts">
|
|
701
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
702
|
+
|
|
703
|
+
const content = useIntlayer("component");
|
|
704
|
+
</script>
|
|
705
|
+
|
|
706
|
+
<div>
|
|
707
|
+
|
|
708
|
+
<!-- Отобразить контент как простой контент -->
|
|
709
|
+
<h1>{$content.title}</h1>
|
|
710
|
+
|
|
711
|
+
<!-- Отобразить контент как компонент (требуется редактором) -->
|
|
712
|
+
<svelte:component this={$content.component} />
|
|
713
|
+
</div>
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### Конфигурация Git
|
|
717
|
+
|
|
718
|
+
Рекомендуется игнорировать файлы, сгенерированные Intlayer.
|
|
719
|
+
|
|
720
|
+
```plaintext fileName=".gitignore"
|
|
721
|
+
# Игнорировать файлы, сгенерированные Intlayer
|
|
722
|
+
.intlayer
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
### Дальнейшие шаги
|
|
728
|
+
|
|
729
|
+
- **Визуальный редактор**: Интегрируйте [Визуальный редактор Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/intlayer_visual_editor.md), чтобы редактировать переводы напрямую из пользовательского интерфейса.
|
|
730
|
+
- **CMS**: Вынесите управление контентом с помощью [CMS Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/intlayer_CMS.md).
|