@intlayer/docs 7.3.14 → 7.3.15
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/blog/ar/intlayer_with_i18next.md +3 -0
- package/blog/ar/intlayer_with_next-i18next.md +3 -0
- package/blog/ar/intlayer_with_next-intl.md +3 -0
- package/blog/ar/intlayer_with_react-i18next.md +3 -0
- package/blog/ar/intlayer_with_react-intl.md +3 -0
- package/blog/ar/intlayer_with_vue-i18n.md +3 -0
- package/blog/de/intlayer_with_i18next.md +3 -0
- package/blog/de/intlayer_with_next-i18next.md +3 -0
- package/blog/de/intlayer_with_next-intl.md +3 -0
- package/blog/de/intlayer_with_react-i18next.md +3 -0
- package/blog/de/intlayer_with_react-intl.md +3 -0
- package/blog/de/intlayer_with_vue-i18n.md +3 -0
- package/blog/en/intlayer_with_i18next.md +7 -0
- package/blog/en/intlayer_with_next-i18next.md +3 -0
- package/blog/en/intlayer_with_next-intl.md +7 -0
- package/blog/en/intlayer_with_react-i18next.md +3 -0
- package/blog/en/intlayer_with_react-intl.md +3 -0
- package/blog/en/intlayer_with_vue-i18n.md +3 -0
- package/blog/en-GB/intlayer_with_i18next.md +3 -0
- package/blog/en-GB/intlayer_with_next-i18next.md +3 -0
- package/blog/en-GB/intlayer_with_next-intl.md +3 -0
- package/blog/en-GB/intlayer_with_react-i18next.md +3 -0
- package/blog/en-GB/intlayer_with_react-intl.md +3 -0
- package/blog/en-GB/intlayer_with_vue-i18n.md +3 -0
- package/blog/es/intlayer_with_i18next.md +3 -0
- package/blog/es/intlayer_with_next-i18next.md +3 -0
- package/blog/es/intlayer_with_next-intl.md +3 -0
- package/blog/es/intlayer_with_react-i18next.md +3 -0
- package/blog/es/intlayer_with_react-intl.md +3 -0
- package/blog/es/intlayer_with_vue-i18n.md +3 -0
- package/blog/fr/intlayer_with_i18next.md +3 -0
- package/blog/fr/intlayer_with_next-i18next.md +3 -0
- package/blog/fr/intlayer_with_next-intl.md +3 -0
- package/blog/fr/intlayer_with_react-i18next.md +3 -0
- package/blog/fr/intlayer_with_react-intl.md +3 -0
- package/blog/fr/intlayer_with_vue-i18n.md +3 -0
- package/blog/hi/intlayer_with_i18next.md +3 -0
- package/blog/hi/intlayer_with_next-i18next.md +3 -0
- package/blog/hi/intlayer_with_next-intl.md +3 -0
- package/blog/hi/intlayer_with_react-i18next.md +3 -0
- package/blog/hi/intlayer_with_react-intl.md +3 -0
- package/blog/hi/intlayer_with_vue-i18n.md +3 -0
- package/blog/id/intlayer_with_i18next.md +3 -0
- package/blog/id/intlayer_with_next-i18next.md +3 -0
- package/blog/id/intlayer_with_next-intl.md +3 -0
- package/blog/id/intlayer_with_react-i18next.md +3 -0
- package/blog/id/intlayer_with_react-intl.md +3 -0
- package/blog/id/intlayer_with_vue-i18n.md +3 -0
- package/blog/it/intlayer_with_i18next.md +3 -0
- package/blog/it/intlayer_with_next-i18next.md +3 -0
- package/blog/it/intlayer_with_next-intl.md +3 -0
- package/blog/it/intlayer_with_react-i18next.md +3 -0
- package/blog/it/intlayer_with_react-intl.md +3 -0
- package/blog/it/intlayer_with_vue-i18n.md +3 -0
- package/blog/ja/intlayer_with_i18next.md +3 -0
- package/blog/ja/intlayer_with_next-i18next.md +3 -0
- package/blog/ja/intlayer_with_next-intl.md +3 -0
- package/blog/ja/intlayer_with_react-i18next.md +3 -0
- package/blog/ja/intlayer_with_react-intl.md +3 -0
- package/blog/ja/intlayer_with_vue-i18n.md +3 -0
- package/blog/ko/intlayer_with_i18next.md +3 -0
- package/blog/ko/intlayer_with_next-i18next.md +3 -0
- package/blog/ko/intlayer_with_next-intl.md +3 -0
- package/blog/ko/intlayer_with_react-i18next.md +3 -0
- package/blog/ko/intlayer_with_react-intl.md +3 -0
- package/blog/ko/intlayer_with_vue-i18n.md +3 -0
- package/blog/pl/intlayer_with_i18next.md +3 -0
- package/blog/pl/intlayer_with_next-i18next.md +3 -0
- package/blog/pl/intlayer_with_next-intl.md +3 -0
- package/blog/pl/intlayer_with_react-i18next.md +3 -0
- package/blog/pl/intlayer_with_react-intl.md +3 -0
- package/blog/pl/intlayer_with_vue-i18n.md +3 -0
- package/blog/pt/intlayer_with_i18next.md +3 -0
- package/blog/pt/intlayer_with_next-i18next.md +3 -0
- package/blog/pt/intlayer_with_next-intl.md +3 -0
- package/blog/pt/intlayer_with_react-i18next.md +3 -0
- package/blog/pt/intlayer_with_react-intl.md +3 -0
- package/blog/pt/intlayer_with_vue-i18n.md +3 -0
- package/blog/ru/intlayer_with_i18next.md +3 -0
- package/blog/ru/intlayer_with_next-i18next.md +3 -0
- package/blog/ru/intlayer_with_next-intl.md +3 -0
- package/blog/ru/intlayer_with_react-i18next.md +3 -0
- package/blog/ru/intlayer_with_react-intl.md +3 -0
- package/blog/ru/intlayer_with_vue-i18n.md +3 -0
- package/blog/tr/intlayer_with_i18next.md +3 -0
- package/blog/tr/intlayer_with_next-i18next.md +3 -0
- package/blog/tr/intlayer_with_next-intl.md +3 -0
- package/blog/tr/intlayer_with_react-i18next.md +3 -0
- package/blog/tr/intlayer_with_vue-i18n.md +3 -0
- package/blog/vi/intlayer_with_i18next.md +3 -0
- package/blog/vi/intlayer_with_next-i18next.md +3 -0
- package/blog/vi/intlayer_with_next-intl.md +3 -0
- package/blog/vi/intlayer_with_react-i18next.md +3 -0
- package/blog/vi/intlayer_with_react-intl.md +3 -0
- package/blog/vi/intlayer_with_vue-i18n.md +3 -0
- package/blog/zh/intlayer_with_i18next.md +3 -0
- package/blog/zh/intlayer_with_next-i18next.md +3 -0
- package/blog/zh/intlayer_with_next-intl.md +3 -0
- package/blog/zh/intlayer_with_react-i18next.md +3 -0
- package/blog/zh/intlayer_with_react-intl.md +3 -0
- package/blog/zh/intlayer_with_vue-i18n.md +3 -0
- package/docs/ar/intlayer_with_lynx+react.md +1 -1
- package/docs/ar/intlayer_with_vite+react.md +99 -331
- package/docs/ar/plugins/sync-json.md +3 -0
- package/docs/de/intlayer_with_lynx+react.md +1 -1
- package/docs/de/intlayer_with_vite+react.md +116 -380
- package/docs/de/plugins/sync-json.md +3 -0
- package/docs/en/intlayer_with_vite+react.md +6 -10
- package/docs/en/plugins/sync-json.md +3 -0
- package/docs/en-GB/intlayer_with_vite+react.md +62 -74
- package/docs/en-GB/plugins/sync-json.md +3 -0
- package/docs/es/intlayer_with_vite+react.md +101 -333
- package/docs/es/plugins/sync-json.md +3 -0
- package/docs/fr/intlayer_with_vite+react.md +101 -357
- package/docs/fr/plugins/sync-json.md +3 -0
- package/docs/hi/intlayer_with_vite+react.md +120 -333
- package/docs/hi/plugins/sync-json.md +3 -0
- package/docs/id/intlayer_with_vite+react.md +7 -13
- package/docs/id/plugins/sync-json.md +3 -0
- package/docs/it/intlayer_with_lynx+react.md +1 -1
- package/docs/it/intlayer_with_vite+react.md +121 -393
- package/docs/it/plugins/sync-json.md +3 -0
- package/docs/ja/intlayer_with_vite+react.md +106 -378
- package/docs/ja/plugins/sync-json.md +3 -0
- package/docs/ko/intlayer_with_lynx+react.md +1 -1
- package/docs/ko/intlayer_with_vite+react.md +90 -322
- package/docs/ko/plugins/sync-json.md +3 -0
- package/docs/pl/intlayer_with_vite+react.md +25 -21
- package/docs/pl/plugins/sync-json.md +3 -0
- package/docs/pt/intlayer_with_vite+react.md +96 -328
- package/docs/pt/plugins/sync-json.md +3 -0
- package/docs/ru/intlayer_with_lynx+react.md +1 -1
- package/docs/ru/intlayer_with_vite+react.md +109 -362
- package/docs/ru/plugins/sync-json.md +3 -0
- package/docs/tr/intlayer_with_vite+react.md +132 -366
- package/docs/tr/plugins/sync-json.md +3 -0
- package/docs/vi/intlayer_with_vite+react.md +16 -19
- package/docs/vi/plugins/sync-json.md +3 -0
- package/docs/zh/intlayer_with_tanstack.md +1 -1
- package/docs/zh/intlayer_with_vite+react.md +91 -374
- package/docs/zh/plugins/sync-json.md +3 -0
- package/frequent_questions/ar/customized_locale_list.md +1 -1
- package/frequent_questions/de/customized_locale_list.md +1 -1
- package/frequent_questions/en/customized_locale_list.md +1 -1
- package/frequent_questions/en-GB/customized_locale_list.md +1 -1
- package/frequent_questions/es/customized_locale_list.md +1 -1
- package/frequent_questions/fr/customized_locale_list.md +1 -1
- package/frequent_questions/hi/customized_locale_list.md +1 -1
- package/frequent_questions/id/customized_locale_list.md +1 -1
- package/frequent_questions/it/customized_locale_list.md +1 -1
- package/frequent_questions/ja/customized_locale_list.md +1 -1
- package/frequent_questions/ko/customized_locale_list.md +1 -1
- package/frequent_questions/pl/customized_locale_list.md +1 -1
- package/frequent_questions/pt/customized_locale_list.md +1 -1
- package/frequent_questions/ru/customized_locale_list.md +1 -1
- package/frequent_questions/tr/customized_locale_list.md +1 -1
- package/frequent_questions/vi/customized_locale_list.md +1 -1
- package/frequent_questions/zh/customized_locale_list.md +1 -1
- package/package.json +6 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2024-03-07
|
|
3
|
-
updatedAt:
|
|
4
|
-
title: Как перевести ваше Vite
|
|
3
|
+
updatedAt: 2025-12-10
|
|
4
|
+
title: Как перевести ваше приложение на Vite и React – руководство по i18n 2025
|
|
5
5
|
description: Узнайте, как добавить интернационализацию (i18n) в ваше приложение на Vite и React с помощью Intlayer. Следуйте этому руководству, чтобы сделать ваше приложение многоязычным.
|
|
6
6
|
keywords:
|
|
7
7
|
- Интернационализация
|
|
@@ -16,23 +16,19 @@ slugs:
|
|
|
16
16
|
- environment
|
|
17
17
|
- vite-and-react
|
|
18
18
|
applicationTemplate: https://github.com/aymericzip/intlayer-vite-react-template
|
|
19
|
-
youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
|
|
19
|
+
youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
|
|
20
20
|
history:
|
|
21
21
|
- version: 5.5.10
|
|
22
22
|
date: 2025-06-29
|
|
23
23
|
changes: Инициализация истории
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
-
#
|
|
26
|
+
# Перевод вашего сайта на Vite и React с помощью Intlayer | Интернационализация (i18n)
|
|
27
27
|
|
|
28
28
|
## Содержание
|
|
29
29
|
|
|
30
30
|
<TOC/>
|
|
31
31
|
|
|
32
|
-
<iframe title="The best i18n solution for Vite and React? Discover Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/dS9L7uJeak4?si=VaKmrYMmXjo3xpk2"/>
|
|
33
|
-
|
|
34
|
-
Смотрите [шаблон приложения](https://github.com/aymericzip/intlayer-vite-react-template) на GitHub.
|
|
35
|
-
|
|
36
32
|
## Что такое Intlayer?
|
|
37
33
|
|
|
38
34
|
**Intlayer** - это инновационная, открытая библиотека интернационализации (i18n), созданная для упрощения поддержки многоязычности в современных веб-приложениях.
|
|
@@ -48,6 +44,27 @@ history:
|
|
|
48
44
|
|
|
49
45
|
## Пошаговое руководство по настройке Intlayer в приложении на Vite и React
|
|
50
46
|
|
|
47
|
+
<Tab defaultTab="video">
|
|
48
|
+
<TabItem label="Видео" value="video">
|
|
49
|
+
|
|
50
|
+
<iframe title="Лучшee решение для i18n в Vite и React? Откройте для себя Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/dS9L7uJeak4?si=VaKmrYMmXjo3xpk2"/>
|
|
51
|
+
|
|
52
|
+
</TabItem>
|
|
53
|
+
<TabItem label="Код" value="code">
|
|
54
|
+
|
|
55
|
+
<iframe
|
|
56
|
+
src="https://stackblitz.com/github/aymericzip/intlayer-vite-react-template?embed=1&ctl=1&file=intlayer.config.ts"
|
|
57
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
58
|
+
title="Демонстрация CodeSandbox — Как интернационализировать ваше приложение с помощью Intlayer"
|
|
59
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
60
|
+
loading="lazy"
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
</TabItem>
|
|
64
|
+
</Tab>
|
|
65
|
+
|
|
66
|
+
Смотрите [Application Template](https://github.com/aymericzip/intlayer-vite-react-template) на GitHub.
|
|
67
|
+
|
|
51
68
|
### Шаг 1: Установка зависимостей
|
|
52
69
|
|
|
53
70
|
Установите необходимые пакеты с помощью npm:
|
|
@@ -68,14 +85,13 @@ yarn add vite-intlayer --save-dev
|
|
|
68
85
|
```
|
|
69
86
|
|
|
70
87
|
- **intlayer**
|
|
71
|
-
|
|
72
|
-
Основной пакет, предоставляющий инструменты интернационализации для управления конфигурацией, перевода, [объявления контента](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dictionary/get_started.md), транспиляции и [CLI-команд](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/intlayer_cli.md).
|
|
88
|
+
Основной пакет, предоставляющий инструменты интернационализации для управления конфигурацией, перевода, [объявления контента](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dictionary/content_file.md), транспиляции и [CLI-команд](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/cli/index.md).
|
|
73
89
|
|
|
74
90
|
- **react-intlayer**
|
|
75
91
|
Пакет, который интегрирует Intlayer с приложением на React. Он предоставляет провайдеры контекста и хуки для интернационализации в React.
|
|
76
92
|
|
|
77
93
|
- **vite-intlayer**
|
|
78
|
-
Включает плагин Vite для интеграции Intlayer с [сборщиком Vite](https://vite.dev/guide/why.html#why-bundle-for-production), а также
|
|
94
|
+
Включает плагин Vite для интеграции Intlayer с [сборщиком Vite](https://vite.dev/guide/why.html#why-bundle-for-production), а также middleware для определения предпочтительной локали пользователя, управления куки и обработки перенаправления URL.
|
|
79
95
|
|
|
80
96
|
### Шаг 2: Конфигурация вашего проекта
|
|
81
97
|
|
|
@@ -137,7 +153,7 @@ const config = {
|
|
|
137
153
|
module.exports = config;
|
|
138
154
|
```
|
|
139
155
|
|
|
140
|
-
> Через этот файл конфигурации вы можете настроить локализованные URL-адреса, перенаправление в
|
|
156
|
+
> Через этот файл конфигурации вы можете настроить локализованные URL-адреса, перенаправление в middleware, имена cookie, расположение и расширение ваших деклараций контента, отключить логи Intlayer в консоли и многое другое. Для полного списка доступных параметров обратитесь к [документации по конфигурации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md).
|
|
141
157
|
|
|
142
158
|
### Шаг 3: Интеграция Intlayer в вашу конфигурацию Vite
|
|
143
159
|
|
|
@@ -245,12 +261,14 @@ const appContent = {
|
|
|
245
261
|
key: "app",
|
|
246
262
|
content: {
|
|
247
263
|
viteLogo: t({
|
|
248
|
-
|
|
264
|
+
ru: "Логотип Vite",
|
|
265
|
+
en: "Vite logo",
|
|
249
266
|
fr: "Logo Vite",
|
|
250
267
|
es: "Logo Vite",
|
|
251
268
|
}),
|
|
252
269
|
reactLogo: t({
|
|
253
|
-
|
|
270
|
+
ru: "Логотип React",
|
|
271
|
+
en: "React logo",
|
|
254
272
|
fr: "Logo React",
|
|
255
273
|
es: "Logo React",
|
|
256
274
|
}),
|
|
@@ -258,7 +276,8 @@ const appContent = {
|
|
|
258
276
|
title: "Vite + React",
|
|
259
277
|
|
|
260
278
|
count: t({
|
|
261
|
-
|
|
279
|
+
ru: "счет: ",
|
|
280
|
+
en: "count is ",
|
|
262
281
|
fr: "le compte est ",
|
|
263
282
|
es: "el recuento es ",
|
|
264
283
|
}),
|
|
@@ -268,9 +287,15 @@ const appContent = {
|
|
|
268
287
|
ReactNode >
|
|
269
288
|
{
|
|
270
289
|
// Не забудьте импортировать React, если используете React-узел в вашем контенте
|
|
290
|
+
ru: (
|
|
291
|
+
<>
|
|
292
|
+
Редактируйте <code>src/App.tsx</code> и сохраните, чтобы проверить
|
|
293
|
+
HMR
|
|
294
|
+
</>
|
|
295
|
+
),
|
|
271
296
|
en: (
|
|
272
297
|
<>
|
|
273
|
-
Edit <code>src/App.tsx</code>
|
|
298
|
+
Edit <code>src/App.tsx</code> and save to test HMR
|
|
274
299
|
</>
|
|
275
300
|
),
|
|
276
301
|
fr: (
|
|
@@ -286,7 +311,8 @@ const appContent = {
|
|
|
286
311
|
},
|
|
287
312
|
|
|
288
313
|
readTheDocs: t({
|
|
289
|
-
|
|
314
|
+
ru: "Нажмите на логотипы Vite и React, чтобы узнать больше",
|
|
315
|
+
en: "Click on the Vite and React logos to learn more",
|
|
290
316
|
fr: "Cliquez sur les logos Vite et React pour en savoir plus",
|
|
291
317
|
es: "Haga clic en los logotipos de Vite y React para obtener más información",
|
|
292
318
|
}),
|
|
@@ -418,7 +444,7 @@ module.exports = appContent;
|
|
|
418
444
|
|
|
419
445
|
> Ваши объявления контента могут быть определены в любом месте вашего приложения, как только они включены в каталог `contentDir` (по умолчанию, `./src`). И соответствуют расширению файла объявления контента (по умолчанию, `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
|
|
420
446
|
|
|
421
|
-
> Для получения дополнительной информации обратитесь к [документации по
|
|
447
|
+
> Для получения дополнительной информации обратитесь к [документации по объявлению контента](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dictionary/content_file.md).
|
|
422
448
|
|
|
423
449
|
> Если ваш файл контента включает код TSX, рекомендуется импортировать `import React from "react";` в вашем файле контента.
|
|
424
450
|
|
|
@@ -574,7 +600,7 @@ module.exports = App;
|
|
|
574
600
|
> <img src={content.image.src.value} alt={content.image.value} />
|
|
575
601
|
> ```
|
|
576
602
|
|
|
577
|
-
|
|
603
|
+
Чтобы узнать больше о хуке `useIntlayer`, обратитесь к [документации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useIntlayer.md).
|
|
578
604
|
|
|
579
605
|
### (Необязательно) Шаг 6: Изменение языка вашего контента
|
|
580
606
|
|
|
@@ -630,7 +656,7 @@ const LocaleSwitcher = () => {
|
|
|
630
656
|
|
|
631
657
|
### (Необязательно) Шаг 7: Добавьте локализованную маршрутизацию в ваше приложение
|
|
632
658
|
|
|
633
|
-
Цель этого шага
|
|
659
|
+
Цель этого шага — создать уникальные маршруты для каждого языка. Это полезно для SEO и SEO-дружественных URL.
|
|
634
660
|
Пример:
|
|
635
661
|
|
|
636
662
|
```plaintext
|
|
@@ -644,82 +670,10 @@ const LocaleSwitcher = () => {
|
|
|
644
670
|
Чтобы добавить локализованную маршрутизацию в ваше приложение, вы можете создать компонент `LocaleRouter`, который оборачивает маршруты вашего приложения и обрабатывает маршрутизацию на основе локали. Вот пример с использованием [React Router](https://reactrouter.com/home):
|
|
645
671
|
|
|
646
672
|
```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
|
|
647
|
-
|
|
648
|
-
import { type Locales, configuration, getPathWithoutLocale } from "intlayer"; // Утилиты и типы из 'intlayer'
|
|
673
|
+
import { localeMap } from "intlayer"; // Утилиты и типы из 'intlayer'
|
|
649
674
|
import type { FC, PropsWithChildren } from "react"; // Типы React для функциональных компонентов и пропсов
|
|
650
675
|
import { IntlayerProvider } from "react-intlayer"; // Провайдер для контекста интернационализации
|
|
651
|
-
import {
|
|
652
|
-
BrowserRouter,
|
|
653
|
-
Routes,
|
|
654
|
-
Route,
|
|
655
|
-
Navigate,
|
|
656
|
-
useLocation,
|
|
657
|
-
} from "react-router-dom"; // Компоненты роутера для управления навигацией
|
|
658
|
-
|
|
659
|
-
// Деструктуризация конфигурации из Intlayer
|
|
660
|
-
const { internationalization, middleware } = configuration;
|
|
661
|
-
const { locales, defaultLocale } = internationalization;
|
|
662
|
-
|
|
663
|
-
/**
|
|
664
|
-
* Компонент, который обрабатывает локализацию и оборачивает дочерние элементы в соответствующий контекст локали.
|
|
665
|
-
* Управляет определением и проверкой локали на основе URL.
|
|
666
|
-
*/
|
|
667
|
-
const AppLocalized: FC<PropsWithChildren<{ locale: Locales }>> = ({
|
|
668
|
-
children,
|
|
669
|
-
locale,
|
|
670
|
-
}) => {
|
|
671
|
-
const { pathname, search } = useLocation(); // Получить текущий путь URL
|
|
672
|
-
|
|
673
|
-
// Определить текущую локаль, используя локаль по умолчанию, если не указана
|
|
674
|
-
const currentLocale = locale ?? defaultLocale;
|
|
675
|
-
|
|
676
|
-
// Удалить префикс локали из пути для формирования базового пути
|
|
677
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
678
|
-
pathname // Текущий путь URL
|
|
679
|
-
);
|
|
680
|
-
|
|
681
|
-
/**
|
|
682
|
-
* Если middleware.prefixDefault равно true, префикс локали по умолчанию должен всегда присутствовать.
|
|
683
|
-
*/
|
|
684
|
-
if (middleware.prefixDefault) {
|
|
685
|
-
// Проверить валидность локали
|
|
686
|
-
if (!locale || !locales.includes(locale)) {
|
|
687
|
-
// Перенаправить на локаль по умолчанию с обновлённым путем
|
|
688
|
-
return (
|
|
689
|
-
<Navigate
|
|
690
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
691
|
-
replace // Заменить текущую запись истории новой
|
|
692
|
-
/>
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
// Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
|
|
697
|
-
return (
|
|
698
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
699
|
-
);
|
|
700
|
-
} else {
|
|
701
|
-
/**
|
|
702
|
-
* Когда middleware.prefixDefault равно false, локаль по умолчанию не префиксируется.
|
|
703
|
-
* Убедиться, что текущая локаль действительна и не является локалью по умолчанию.
|
|
704
|
-
*/
|
|
705
|
-
if (
|
|
706
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
707
|
-
!locales
|
|
708
|
-
.filter(
|
|
709
|
-
(locale) => locale.toString() !== defaultLocale.toString() // Исключить локаль по умолчанию
|
|
710
|
-
)
|
|
711
|
-
.includes(currentLocale) // Проверить, находится ли текущая локаль в списке допустимых локалей
|
|
712
|
-
) {
|
|
713
|
-
// Перенаправить на путь без префикса локали
|
|
714
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
// Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
|
|
718
|
-
return (
|
|
719
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
720
|
-
);
|
|
721
|
-
}
|
|
722
|
-
};
|
|
676
|
+
import { BrowserRouter, Route, Routes } from "react-router-dom"; // Компоненты роутера для управления навигацией
|
|
723
677
|
|
|
724
678
|
/**
|
|
725
679
|
* Компонент маршрутизатора, который настраивает маршруты для конкретных локалей.
|
|
@@ -728,256 +682,81 @@ const AppLocalized: FC<PropsWithChildren<{ locale: Locales }>> = ({
|
|
|
728
682
|
export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
|
|
729
683
|
<BrowserRouter>
|
|
730
684
|
<Routes>
|
|
731
|
-
{
|
|
732
|
-
|
|
733
|
-
(
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
/>
|
|
742
|
-
))}
|
|
743
|
-
|
|
744
|
-
{
|
|
745
|
-
// Если префикс для локали по умолчанию отключен, рендерить дочерние элементы напрямую по корневому пути
|
|
746
|
-
!middleware.prefixDefault && (
|
|
747
|
-
<Route
|
|
748
|
-
path="*"
|
|
749
|
-
element={
|
|
750
|
-
<AppLocalized locale={defaultLocale}>{children}</AppLocalized>
|
|
751
|
-
} // Оборачивает дочерние элементы с управлением локалью
|
|
752
|
-
/>
|
|
753
|
-
)
|
|
754
|
-
}
|
|
685
|
+
{localeMap(({ locale, urlPrefix }) => (
|
|
686
|
+
<Route
|
|
687
|
+
// Шаблон маршрута для захвата локали (например, /en/, /fr/) и соответствия всем последующим путям
|
|
688
|
+
path={`${urlPrefix}/*`}
|
|
689
|
+
key={locale}
|
|
690
|
+
element={
|
|
691
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
692
|
+
} // Оборачивает дочерние элементы с управлением локалью
|
|
693
|
+
/>
|
|
694
|
+
))}
|
|
755
695
|
</Routes>
|
|
756
696
|
</BrowserRouter>
|
|
757
697
|
);
|
|
758
698
|
```
|
|
759
699
|
|
|
760
700
|
```jsx fileName="src/components/LocaleRouter.mjx" codeFormat="esm"
|
|
761
|
-
|
|
762
|
-
import {
|
|
763
|
-
|
|
764
|
-
import {
|
|
765
|
-
import {
|
|
766
|
-
BrowserRouter,
|
|
767
|
-
Routes,
|
|
768
|
-
Route,
|
|
769
|
-
Navigate,
|
|
770
|
-
useLocation,
|
|
771
|
-
} from "react-router-dom"; // Компоненты роутера для управления навигацией
|
|
772
|
-
|
|
773
|
-
// Деструктуризация конфигурации из Intlayer
|
|
774
|
-
const { internationalization, middleware } = configuration;
|
|
775
|
-
const { locales, defaultLocale } = internationalization;
|
|
776
|
-
|
|
777
|
-
/**
|
|
778
|
-
* Компонент, который обрабатывает локализацию и оборачивает дочерние элементы в соответствующий контекст локали.
|
|
779
|
-
* Он управляет определением и проверкой локали на основе URL.
|
|
780
|
-
*/
|
|
781
|
-
const AppLocalized = ({ children, locale }) => {
|
|
782
|
-
const { pathname, search } = useLocation(); // Получить текущий путь URL
|
|
783
|
-
|
|
784
|
-
// Определить текущую локаль, используя локаль по умолчанию, если не указана
|
|
785
|
-
const currentLocale = locale ?? defaultLocale;
|
|
786
|
-
|
|
787
|
-
// Удалить префикс локали из пути для построения базового пути
|
|
788
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
789
|
-
pathname // Текущий путь URL
|
|
790
|
-
);
|
|
791
|
-
|
|
792
|
-
/**
|
|
793
|
-
* Если middleware.prefixDefault равно true, префикс локали по умолчанию должен всегда присутствовать.
|
|
794
|
-
*/
|
|
795
|
-
if (middleware.prefixDefault) {
|
|
796
|
-
// Проверить локаль
|
|
797
|
-
if (!locale || !locales.includes(locale)) {
|
|
798
|
-
// Перенаправить на локаль по умолчанию с обновлённым путем
|
|
799
|
-
return (
|
|
800
|
-
<Navigate
|
|
801
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
802
|
-
replace // Заменить текущую запись в истории на новую
|
|
803
|
-
/>
|
|
804
|
-
);
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
// Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
|
|
808
|
-
return (
|
|
809
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
810
|
-
);
|
|
811
|
-
} else {
|
|
812
|
-
/**
|
|
813
|
-
* Когда middleware.prefixDefault равно false, префикс для локали по умолчанию не используется.
|
|
814
|
-
* Убедиться, что текущая локаль действительна и не является локалью по умолчанию.
|
|
815
|
-
*/
|
|
816
|
-
if (
|
|
817
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
818
|
-
!locales
|
|
819
|
-
.filter(
|
|
820
|
-
(locale) => locale.toString() !== defaultLocale.toString() // Исключить локаль по умолчанию
|
|
821
|
-
)
|
|
822
|
-
.includes(currentLocale) // Проверить, находится ли текущая локаль в списке допустимых локалей
|
|
823
|
-
) {
|
|
824
|
-
// Перенаправить на путь без префикса локали
|
|
825
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
// Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
|
|
829
|
-
return (
|
|
830
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
831
|
-
);
|
|
832
|
-
}
|
|
833
|
-
};
|
|
701
|
+
import { localeMap } from 'intlayer'; // Утилиты и типы из 'intlayer'
|
|
702
|
+
import type { FC, PropsWithChildren } from 'react'; // Типы React для функциональных компонентов и пропсов
|
|
703
|
+
import { IntlayerProvider } from 'react-intlayer'; // Провайдер для контекста интернационализации
|
|
704
|
+
import { BrowserRouter, Route, Routes } from 'react-router-dom'; // Компоненты роутера для управления навигацией
|
|
834
705
|
|
|
835
706
|
/**
|
|
836
707
|
* Компонент маршрутизатора, который настраивает маршруты для конкретных локалей.
|
|
837
708
|
* Использует React Router для управления навигацией и рендеринга локализованных компонентов.
|
|
838
709
|
*/
|
|
839
|
-
export const LocaleRouter = ({ children }) => (
|
|
710
|
+
export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
|
|
840
711
|
<BrowserRouter>
|
|
841
712
|
<Routes>
|
|
842
|
-
{
|
|
843
|
-
|
|
844
|
-
(
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
/>
|
|
853
|
-
))}
|
|
854
|
-
|
|
855
|
-
{
|
|
856
|
-
// Если префикс для локали по умолчанию отключен, рендерить дочерние элементы напрямую по корневому пути
|
|
857
|
-
!middleware.prefixDefault && (
|
|
858
|
-
<Route
|
|
859
|
-
path="*"
|
|
860
|
-
element={
|
|
861
|
-
<AppLocalized locale={defaultLocale}>{children}</AppLocalized>
|
|
862
|
-
} // Оборачивает дочерние элементы с управлением локалью
|
|
863
|
-
/>
|
|
864
|
-
)
|
|
865
|
-
}
|
|
713
|
+
{localeMap(({ locale, urlPrefix }) => (
|
|
714
|
+
<Route
|
|
715
|
+
// Шаблон маршрута для захвата локали (например, /en/, /fr/) и сопоставления всех последующих путей
|
|
716
|
+
path={`${urlPrefix}/*`}
|
|
717
|
+
key={locale}
|
|
718
|
+
element={
|
|
719
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
720
|
+
} // Оборачивает дочерние элементы с управлением локалью
|
|
721
|
+
/>
|
|
722
|
+
))}
|
|
866
723
|
</Routes>
|
|
867
724
|
</BrowserRouter>
|
|
868
725
|
);
|
|
869
726
|
```
|
|
870
727
|
|
|
871
728
|
```jsx fileName="src/components/LocaleRouter.cjx" codeFormat="commonjs"
|
|
872
|
-
|
|
873
|
-
const
|
|
874
|
-
const { IntlayerProvider
|
|
875
|
-
const {
|
|
876
|
-
BrowserRouter,
|
|
877
|
-
Routes,
|
|
878
|
-
Route,
|
|
879
|
-
Navigate,
|
|
880
|
-
useLocation,
|
|
881
|
-
} = require("react-router-dom"); // Компоненты роутера для управления навигацией
|
|
882
|
-
|
|
883
|
-
// Деструктуризация конфигурации из Intlayer
|
|
884
|
-
const { internationalization, middleware } = configuration;
|
|
885
|
-
const { locales, defaultLocale } = internationalization;
|
|
886
|
-
|
|
887
|
-
/**
|
|
888
|
-
* Компонент, который обрабатывает локализацию и оборачивает дочерние элементы в соответствующий контекст локали.
|
|
889
|
-
* Управляет определением и проверкой локали на основе URL.
|
|
890
|
-
*/
|
|
891
|
-
const AppLocalized = ({ children, locale }) => {
|
|
892
|
-
const { pathname, search } = useLocation(); // Получить текущий путь URL
|
|
893
|
-
|
|
894
|
-
// Определить текущую локаль, используя локаль по умолчанию, если не указана
|
|
895
|
-
const currentLocale = locale ?? defaultLocale;
|
|
896
|
-
|
|
897
|
-
// Удалить префикс локали из пути для построения базового пути
|
|
898
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
899
|
-
pathname // Текущий путь URL
|
|
900
|
-
);
|
|
901
|
-
|
|
902
|
-
/**
|
|
903
|
-
* Если middleware.prefixDefault равно true, локаль по умолчанию всегда должна иметь префикс.
|
|
904
|
-
*/
|
|
905
|
-
if (middleware.prefixDefault) {
|
|
906
|
-
// Проверить валидность локали
|
|
907
|
-
if (!locale || !locales.includes(locale)) {
|
|
908
|
-
// Перенаправить на локаль по умолчанию с обновлённым путём
|
|
909
|
-
return (
|
|
910
|
-
<Navigate
|
|
911
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
912
|
-
replace // Заменить текущую запись истории на новую
|
|
913
|
-
/>
|
|
914
|
-
);
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
// Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
|
|
918
|
-
return (
|
|
919
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
920
|
-
);
|
|
921
|
-
} else {
|
|
922
|
-
/**
|
|
923
|
-
* Когда middleware.prefixDefault равно false, префикс для локали по умолчанию не добавляется.
|
|
924
|
-
* Убедиться, что текущая локаль валидна и не является локалью по умолчанию.
|
|
925
|
-
*/
|
|
926
|
-
if (
|
|
927
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
928
|
-
!locales
|
|
929
|
-
.filter(
|
|
930
|
-
(locale) => locale.toString() !== defaultLocale.toString() // Исключить локаль по умолчанию
|
|
931
|
-
)
|
|
932
|
-
.includes(currentLocale) // Проверить, что текущая локаль есть в списке валидных локалей
|
|
933
|
-
) {
|
|
934
|
-
// Перенаправить на путь без префикса локали
|
|
935
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
// Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
|
|
939
|
-
return (
|
|
940
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
941
|
-
);
|
|
942
|
-
}
|
|
943
|
-
};
|
|
729
|
+
const { localeMap } = require("intlayer"); // Утилиты и типы из 'intlayer'
|
|
730
|
+
const React = require("react"); // Импорт React
|
|
731
|
+
const { IntlayerProvider } = require("react-intlayer"); // Провайдер для контекста интернационализации
|
|
732
|
+
const { BrowserRouter, Route, Routes } = require("react-router-dom"); // Компоненты роутера для управления навигацией
|
|
944
733
|
|
|
945
734
|
/**
|
|
946
735
|
* Компонент роутера, который настраивает маршруты для конкретных локалей.
|
|
947
736
|
* Использует React Router для управления навигацией и отображения локализованных компонентов.
|
|
948
737
|
*/
|
|
949
|
-
const LocaleRouter = ({ children }) =>
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
738
|
+
const LocaleRouter = ({ children }) =>
|
|
739
|
+
React.createElement(
|
|
740
|
+
BrowserRouter,
|
|
741
|
+
{},
|
|
742
|
+
React.createElement(
|
|
743
|
+
Routes,
|
|
744
|
+
{},
|
|
745
|
+
localeMap(({ locale, urlPrefix }) =>
|
|
746
|
+
React.createElement(Route, {
|
|
747
|
+
path: `${urlPrefix}/*`,
|
|
748
|
+
key: locale,
|
|
749
|
+
element: React.createElement(IntlayerProvider, { locale }, children),
|
|
750
|
+
})
|
|
751
|
+
)
|
|
752
|
+
)
|
|
753
|
+
);
|
|
964
754
|
|
|
965
|
-
|
|
966
|
-
// Если префикс для локали по умолчанию отключен, рендерить дочерние элементы напрямую по корневому пути
|
|
967
|
-
!middleware.prefixDefault && (
|
|
968
|
-
<Route
|
|
969
|
-
path="*"
|
|
970
|
-
element={
|
|
971
|
-
<AppLocalized locale={defaultLocale}>{children}</AppLocalized>
|
|
972
|
-
} // Оборачивает дочерние элементы с управлением локалью
|
|
973
|
-
/>
|
|
974
|
-
)
|
|
975
|
-
}
|
|
976
|
-
</Routes>
|
|
977
|
-
</BrowserRouter>
|
|
978
|
-
);
|
|
755
|
+
exports.LocaleRouter = LocaleRouter;
|
|
979
756
|
```
|
|
980
757
|
|
|
758
|
+
> Примечание: если вы используете `routing.mode: 'no-prefix' | 'search-params'`, скорее всего, вам не нужно использовать функцию `localeMap`.
|
|
759
|
+
|
|
981
760
|
Затем вы можете использовать компонент `LocaleRouter` в вашем приложении:
|
|
982
761
|
|
|
983
762
|
```tsx fileName="src/App.tsx" codeFormat="typescript"
|
|
@@ -1019,6 +798,8 @@ const App = () => (
|
|
|
1019
798
|
|
|
1020
799
|
Параллельно вы также можете использовать `intlayerProxy` для добавления маршрутизации на стороне сервера в ваше приложение. Этот плагин автоматически определит текущую локаль на основе URL и установит соответствующее cookie с локалью. Если локаль не указана, плагин определит наиболее подходящую локаль на основе языковых предпочтений браузера пользователя. Если локаль не будет обнаружена, произойдет перенаправление на локаль по умолчанию.
|
|
1021
800
|
|
|
801
|
+
Обратите внимание, что для использования `intlayerProxy` в продакшене необходимо переместить пакет `vite-intlayer` из `devDependencies` в `dependencies`.
|
|
802
|
+
|
|
1022
803
|
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
1023
804
|
import { defineConfig } from "vite";
|
|
1024
805
|
import react from "@vitejs/plugin-react-swc";
|
|
@@ -1254,11 +1035,11 @@ const LocaleSwitcher = () => {
|
|
|
1254
1035
|
> - [`useLocale` хук](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useLocale.md)
|
|
1255
1036
|
> - [`getLocaleName` хук](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocaleName.md)
|
|
1256
1037
|
> - [`getLocalizedUrl` хук](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocalizedUrl.md)
|
|
1257
|
-
> - [`getHTMLTextDir`
|
|
1258
|
-
> - [`hrefLang`
|
|
1259
|
-
> - [`lang`
|
|
1260
|
-
> - [`dir`
|
|
1261
|
-
> - [`aria-current`
|
|
1038
|
+
> - [`getHTMLTextDir` хук](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getHTMLTextDir.md)
|
|
1039
|
+
> - [`hrefLang` атрибут](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
|
|
1040
|
+
> - [`lang` атрибут](https://developer.mozilla.org/ru/docs/Web/HTML/Global_attributes/lang)
|
|
1041
|
+
> - [`dir` атрибут](https://developer.mozilla.org/ru/docs/Web/HTML/Global_attributes/dir)
|
|
1042
|
+
> - [`aria-current` атрибут](https://developer.mozilla.org/ru/docs/Web/Accessibility/ARIA/Attributes/aria-current)
|
|
1262
1043
|
|
|
1263
1044
|
Ниже приведён обновлённый **Шаг 9** с дополнительными объяснениями и уточнёнными примерами кода:
|
|
1264
1045
|
|
|
@@ -1427,36 +1208,6 @@ module.exports = App;
|
|
|
1427
1208
|
Применяя эти изменения, ваше приложение будет:
|
|
1428
1209
|
|
|
1429
1210
|
- Обеспечивать корректное отражение текущей локали в атрибуте **language** (`lang`), что важно для SEO и поведения браузера.
|
|
1430
|
-
- Регулировать **направление текста** (`dir`) в соответствии с локалью, улучшая читаемость и удобство для языков с разным порядком чтения.
|
|
1431
|
-
- Обеспечивать более **доступный** опыт, так как вспомогательные технологии зависят от этих атрибутов для оптимальной работы.
|
|
1432
|
-
|
|
1433
|
-
### (Необязательно) Шаг 10: Создание локализованного компонента ссылки
|
|
1434
|
-
|
|
1435
|
-
```tsx fileName="src/App.tsx" codeFormat="typescript"
|
|
1436
|
-
import type { FC } from "react";
|
|
1437
|
-
import { IntlayerProvider, useIntlayer } from "react-intlayer";
|
|
1438
|
-
import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
|
|
1439
|
-
import "./App.css";
|
|
1440
|
-
|
|
1441
|
-
const AppContent: FC = () => {
|
|
1442
|
-
// Примените хук для обновления атрибутов lang и dir тега <html> в зависимости от локали.
|
|
1443
|
-
useI18nHTMLAttributes();
|
|
1444
|
-
|
|
1445
|
-
// ... Остальная часть вашего компонента
|
|
1446
|
-
};
|
|
1447
|
-
|
|
1448
|
-
const App = () => (
|
|
1449
|
-
<IntlayerProvider>
|
|
1450
|
-
<AppContent />
|
|
1451
|
-
</IntlayerProvider>
|
|
1452
|
-
);
|
|
1453
|
-
|
|
1454
|
-
module.exports = App;
|
|
1455
|
-
```
|
|
1456
|
-
|
|
1457
|
-
Применяя эти изменения, ваше приложение будет:
|
|
1458
|
-
|
|
1459
|
-
- Обеспечивать корректное отражение текущей локали в атрибуте **языка** (`lang`), что важно для SEO и поведения браузера.
|
|
1460
1211
|
- Настраивать **направление текста** (`dir`) в соответствии с локалью, улучшая читаемость и удобство использования для языков с разным порядком чтения.
|
|
1461
1212
|
- Обеспечивать более **доступный** опыт, так как вспомогательные технологии зависят от этих атрибутов для оптимальной работы.
|
|
1462
1213
|
|
|
@@ -1466,7 +1217,7 @@ module.exports = App;
|
|
|
1466
1217
|
|
|
1467
1218
|
Такое поведение полезно по нескольким причинам:
|
|
1468
1219
|
|
|
1469
|
-
- **SEO и удобство для пользователя**: Локализованные URL помогают поисковым системам правильно индексировать страницы на
|
|
1220
|
+
- **SEO и удобство для пользователя**: Локализованные URL помогают поисковым системам правильно индексировать страницы на конкретном языке и предоставлять пользователям контент на предпочитаемом языке.
|
|
1470
1221
|
- **Последовательность**: Используя локализованную ссылку по всему приложению, вы гарантируете, что навигация остаётся в рамках текущей локали, предотвращая неожиданные переключения языка.
|
|
1471
1222
|
- **Поддерживаемость**: Централизация логики локализации в одном компоненте упрощает управление URL-адресами, делая ваш код более удобным для поддержки и расширения по мере роста приложения.
|
|
1472
1223
|
|
|
@@ -1481,11 +1232,10 @@ import {
|
|
|
1481
1232
|
} from "react";
|
|
1482
1233
|
import { useLocale } from "react-intlayer";
|
|
1483
1234
|
|
|
1484
|
-
export interface LinkProps
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
> {}
|
|
1235
|
+
export interface LinkProps extends DetailedHTMLProps<
|
|
1236
|
+
AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
1237
|
+
HTMLAnchorElement
|
|
1238
|
+
> {}
|
|
1489
1239
|
|
|
1490
1240
|
/**
|
|
1491
1241
|
* Вспомогательная функция для проверки, является ли данный URL внешним.
|
|
@@ -1634,8 +1384,7 @@ Intlayer использует расширение модулей (module augmen
|
|
|
1634
1384
|
|
|
1635
1385
|
Для этого вы можете добавить следующие инструкции в ваш файл `.gitignore`:
|
|
1636
1386
|
|
|
1637
|
-
|
|
1638
|
-
# Переведите ваш Vite and React с Intlayer | Интернационализация (i18n)
|
|
1387
|
+
```# Игнорировать файлы, сгенерированные Intlayer
|
|
1639
1388
|
.intlayer
|
|
1640
1389
|
```
|
|
1641
1390
|
|
|
@@ -1659,5 +1408,3 @@ Intlayer использует расширение модулей (module augmen
|
|
|
1659
1408
|
### Продвинутые возможности
|
|
1660
1409
|
|
|
1661
1410
|
Для расширения возможностей вы можете реализовать [визуальный редактор](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/intlayer_visual_editor.md) или вынести ваш контент во внешний [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/intlayer_CMS.md).
|
|
1662
|
-
|
|
1663
|
-
---
|