@intlayer/docs 8.0.0 → 8.0.1-canary.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.
Files changed (172) hide show
  1. package/dist/cjs/generated/docs.entry.cjs +160 -0
  2. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  3. package/dist/esm/generated/docs.entry.mjs +160 -0
  4. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  5. package/dist/types/generated/docs.entry.d.ts +8 -0
  6. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  7. package/docs/ar/intlayer_with_adonisjs.md +394 -0
  8. package/docs/ar/intlayer_with_hono.md +223 -0
  9. package/docs/ar/intlayer_with_vite+preact.md +317 -675
  10. package/docs/ar/packages/adonis-intlayer/exports.md +50 -0
  11. package/docs/ar/packages/adonis-intlayer/intlayer.md +54 -0
  12. package/docs/ar/packages/adonis-intlayer/t.md +149 -0
  13. package/docs/ar/packages/hono-intlayer/exports.md +59 -0
  14. package/docs/ar/packages/hono-intlayer/intlayer.md +60 -0
  15. package/docs/ar/packages/hono-intlayer/t.md +268 -0
  16. package/docs/de/intlayer_with_adonisjs.md +392 -0
  17. package/docs/de/intlayer_with_hono.md +418 -0
  18. package/docs/de/intlayer_with_vite+preact.md +272 -632
  19. package/docs/de/packages/adonis-intlayer/exports.md +50 -0
  20. package/docs/de/packages/adonis-intlayer/intlayer.md +54 -0
  21. package/docs/de/packages/adonis-intlayer/t.md +149 -0
  22. package/docs/de/packages/hono-intlayer/exports.md +59 -0
  23. package/docs/de/packages/hono-intlayer/intlayer.md +59 -0
  24. package/docs/de/packages/hono-intlayer/t.md +316 -0
  25. package/docs/en/index.md +8 -0
  26. package/docs/en/intlayer_with_adonisjs.md +388 -0
  27. package/docs/en/intlayer_with_hono.md +418 -0
  28. package/docs/en/intlayer_with_vite+preact.md +171 -556
  29. package/docs/en/introduction.md +1 -0
  30. package/docs/en/packages/adonis-intlayer/exports.md +50 -0
  31. package/docs/en/packages/adonis-intlayer/intlayer.md +54 -0
  32. package/docs/en/packages/adonis-intlayer/t.md +149 -0
  33. package/docs/en/packages/hono-intlayer/exports.md +59 -0
  34. package/docs/en/packages/hono-intlayer/intlayer.md +59 -0
  35. package/docs/en/packages/hono-intlayer/t.md +316 -0
  36. package/docs/en-GB/intlayer_with_adonisjs.md +394 -0
  37. package/docs/en-GB/intlayer_with_hono.md +418 -0
  38. package/docs/en-GB/intlayer_with_vite+preact.md +236 -583
  39. package/docs/en-GB/packages/adonis-intlayer/exports.md +50 -0
  40. package/docs/en-GB/packages/adonis-intlayer/intlayer.md +54 -0
  41. package/docs/en-GB/packages/adonis-intlayer/t.md +149 -0
  42. package/docs/en-GB/packages/hono-intlayer/exports.md +59 -0
  43. package/docs/en-GB/packages/hono-intlayer/intlayer.md +59 -0
  44. package/docs/en-GB/packages/hono-intlayer/t.md +316 -0
  45. package/docs/es/intlayer_with_adonisjs.md +388 -0
  46. package/docs/es/intlayer_with_hono.md +418 -0
  47. package/docs/es/intlayer_with_vite+preact.md +286 -650
  48. package/docs/es/packages/adonis-intlayer/exports.md +50 -0
  49. package/docs/es/packages/adonis-intlayer/intlayer.md +54 -0
  50. package/docs/es/packages/adonis-intlayer/t.md +149 -0
  51. package/docs/es/packages/hono-intlayer/exports.md +59 -0
  52. package/docs/es/packages/hono-intlayer/intlayer.md +59 -0
  53. package/docs/es/packages/hono-intlayer/t.md +316 -0
  54. package/docs/fr/intlayer_with_adonisjs.md +388 -0
  55. package/docs/fr/intlayer_with_hono.md +418 -0
  56. package/docs/fr/intlayer_with_vite+preact.md +274 -614
  57. package/docs/fr/packages/adonis-intlayer/exports.md +50 -0
  58. package/docs/fr/packages/adonis-intlayer/intlayer.md +54 -0
  59. package/docs/fr/packages/adonis-intlayer/t.md +149 -0
  60. package/docs/fr/packages/hono-intlayer/exports.md +59 -0
  61. package/docs/fr/packages/hono-intlayer/intlayer.md +59 -0
  62. package/docs/fr/packages/hono-intlayer/t.md +316 -0
  63. package/docs/hi/intlayer_with_adonisjs.md +394 -0
  64. package/docs/hi/intlayer_with_hono.md +227 -0
  65. package/docs/hi/intlayer_with_vite+preact.md +304 -680
  66. package/docs/hi/packages/adonis-intlayer/exports.md +50 -0
  67. package/docs/hi/packages/adonis-intlayer/intlayer.md +54 -0
  68. package/docs/hi/packages/adonis-intlayer/t.md +149 -0
  69. package/docs/hi/packages/hono-intlayer/exports.md +59 -0
  70. package/docs/hi/packages/hono-intlayer/intlayer.md +60 -0
  71. package/docs/hi/packages/hono-intlayer/t.md +268 -0
  72. package/docs/id/intlayer_with_adonisjs.md +394 -0
  73. package/docs/id/intlayer_with_hono.md +227 -0
  74. package/docs/id/intlayer_with_vite+preact.md +297 -697
  75. package/docs/id/packages/adonis-intlayer/exports.md +50 -0
  76. package/docs/id/packages/adonis-intlayer/intlayer.md +54 -0
  77. package/docs/id/packages/adonis-intlayer/t.md +149 -0
  78. package/docs/id/packages/hono-intlayer/exports.md +59 -0
  79. package/docs/id/packages/hono-intlayer/intlayer.md +60 -0
  80. package/docs/id/packages/hono-intlayer/t.md +268 -0
  81. package/docs/it/intlayer_with_adonisjs.md +394 -0
  82. package/docs/it/intlayer_with_hono.md +227 -0
  83. package/docs/it/intlayer_with_vite+preact.md +290 -659
  84. package/docs/it/packages/adonis-intlayer/exports.md +50 -0
  85. package/docs/it/packages/adonis-intlayer/intlayer.md +54 -0
  86. package/docs/it/packages/adonis-intlayer/t.md +149 -0
  87. package/docs/it/packages/hono-intlayer/exports.md +59 -0
  88. package/docs/it/packages/hono-intlayer/intlayer.md +60 -0
  89. package/docs/it/packages/hono-intlayer/t.md +268 -0
  90. package/docs/ja/intlayer_with_adonisjs.md +394 -0
  91. package/docs/ja/intlayer_with_hono.md +227 -0
  92. package/docs/ja/intlayer_with_vite+preact.md +307 -662
  93. package/docs/ja/packages/adonis-intlayer/exports.md +50 -0
  94. package/docs/ja/packages/adonis-intlayer/intlayer.md +54 -0
  95. package/docs/ja/packages/adonis-intlayer/t.md +149 -0
  96. package/docs/ja/packages/hono-intlayer/exports.md +59 -0
  97. package/docs/ja/packages/hono-intlayer/intlayer.md +60 -0
  98. package/docs/ja/packages/hono-intlayer/t.md +268 -0
  99. package/docs/ko/intlayer_with_adonisjs.md +394 -0
  100. package/docs/ko/intlayer_with_hono.md +227 -0
  101. package/docs/ko/intlayer_with_vite+preact.md +303 -703
  102. package/docs/ko/packages/adonis-intlayer/exports.md +50 -0
  103. package/docs/ko/packages/adonis-intlayer/intlayer.md +54 -0
  104. package/docs/ko/packages/adonis-intlayer/t.md +149 -0
  105. package/docs/ko/packages/hono-intlayer/exports.md +59 -0
  106. package/docs/ko/packages/hono-intlayer/intlayer.md +60 -0
  107. package/docs/ko/packages/hono-intlayer/t.md +268 -0
  108. package/docs/pl/intlayer_with_adonisjs.md +394 -0
  109. package/docs/pl/intlayer_with_hono.md +227 -0
  110. package/docs/pl/intlayer_with_vite+preact.md +289 -690
  111. package/docs/pl/packages/adonis-intlayer/exports.md +50 -0
  112. package/docs/pl/packages/adonis-intlayer/intlayer.md +54 -0
  113. package/docs/pl/packages/adonis-intlayer/t.md +149 -0
  114. package/docs/pl/packages/hono-intlayer/exports.md +59 -0
  115. package/docs/pl/packages/hono-intlayer/intlayer.md +60 -0
  116. package/docs/pl/packages/hono-intlayer/t.md +268 -0
  117. package/docs/pt/intlayer_with_adonisjs.md +394 -0
  118. package/docs/pt/intlayer_with_hono.md +227 -0
  119. package/docs/pt/intlayer_with_vite+preact.md +275 -637
  120. package/docs/pt/packages/adonis-intlayer/exports.md +50 -0
  121. package/docs/pt/packages/adonis-intlayer/intlayer.md +54 -0
  122. package/docs/pt/packages/adonis-intlayer/t.md +149 -0
  123. package/docs/pt/packages/hono-intlayer/exports.md +59 -0
  124. package/docs/pt/packages/hono-intlayer/intlayer.md +60 -0
  125. package/docs/pt/packages/hono-intlayer/t.md +268 -0
  126. package/docs/ru/intlayer_with_adonisjs.md +393 -0
  127. package/docs/ru/intlayer_with_hono.md +223 -0
  128. package/docs/ru/intlayer_with_vite+preact.md +319 -683
  129. package/docs/ru/packages/adonis-intlayer/exports.md +50 -0
  130. package/docs/ru/packages/adonis-intlayer/intlayer.md +54 -0
  131. package/docs/ru/packages/adonis-intlayer/t.md +149 -0
  132. package/docs/ru/packages/hono-intlayer/exports.md +59 -0
  133. package/docs/ru/packages/hono-intlayer/intlayer.md +60 -0
  134. package/docs/ru/packages/hono-intlayer/t.md +268 -0
  135. package/docs/tr/intlayer_with_adonisjs.md +394 -0
  136. package/docs/tr/intlayer_with_hono.md +227 -0
  137. package/docs/tr/intlayer_with_vite+preact.md +332 -665
  138. package/docs/tr/packages/adonis-intlayer/exports.md +50 -0
  139. package/docs/tr/packages/adonis-intlayer/intlayer.md +54 -0
  140. package/docs/tr/packages/adonis-intlayer/t.md +149 -0
  141. package/docs/tr/packages/hono-intlayer/exports.md +59 -0
  142. package/docs/tr/packages/hono-intlayer/intlayer.md +60 -0
  143. package/docs/tr/packages/hono-intlayer/t.md +268 -0
  144. package/docs/uk/intlayer_with_adonisjs.md +394 -0
  145. package/docs/uk/intlayer_with_hono.md +227 -0
  146. package/docs/uk/intlayer_with_vite+preact.md +228 -626
  147. package/docs/uk/packages/adonis-intlayer/exports.md +50 -0
  148. package/docs/uk/packages/adonis-intlayer/intlayer.md +54 -0
  149. package/docs/uk/packages/adonis-intlayer/t.md +149 -0
  150. package/docs/uk/packages/hono-intlayer/exports.md +59 -0
  151. package/docs/uk/packages/hono-intlayer/intlayer.md +60 -0
  152. package/docs/uk/packages/hono-intlayer/t.md +268 -0
  153. package/docs/vi/intlayer_with_adonisjs.md +394 -0
  154. package/docs/vi/intlayer_with_hono.md +227 -0
  155. package/docs/vi/intlayer_with_vite+preact.md +294 -679
  156. package/docs/vi/packages/adonis-intlayer/exports.md +50 -0
  157. package/docs/vi/packages/adonis-intlayer/intlayer.md +54 -0
  158. package/docs/vi/packages/adonis-intlayer/t.md +149 -0
  159. package/docs/vi/packages/hono-intlayer/exports.md +59 -0
  160. package/docs/vi/packages/hono-intlayer/intlayer.md +60 -0
  161. package/docs/vi/packages/hono-intlayer/t.md +268 -0
  162. package/docs/zh/intlayer_with_adonisjs.md +393 -0
  163. package/docs/zh/intlayer_with_hono.md +418 -0
  164. package/docs/zh/intlayer_with_vite+preact.md +338 -743
  165. package/docs/zh/packages/adonis-intlayer/exports.md +50 -0
  166. package/docs/zh/packages/adonis-intlayer/intlayer.md +54 -0
  167. package/docs/zh/packages/adonis-intlayer/t.md +149 -0
  168. package/docs/zh/packages/hono-intlayer/exports.md +59 -0
  169. package/docs/zh/packages/hono-intlayer/intlayer.md +60 -0
  170. package/docs/zh/packages/hono-intlayer/t.md +294 -0
  171. package/package.json +6 -6
  172. package/src/generated/docs.entry.ts +160 -0
@@ -24,7 +24,7 @@ history:
24
24
  changes: Инициализация истории
25
25
  ---
26
26
 
27
- # Переведите ваш Vite and Preact с Intlayer | Интернационализация (i18n)
27
+ # Переведите ваш сайт на Vite и Preact с помощью Intlayer | Интернационализация (i18n)
28
28
 
29
29
  <Tabs defaultTab="video">
30
30
  <Tab label="Video" value="video">
@@ -45,25 +45,27 @@ history:
45
45
  </Tab>
46
46
  </Tabs>
47
47
 
48
- > Этот пакет находится в разработке. Подробнее смотрите в [issue](https://github.com/aymericzip/intlayer/issues/118). Покажите свой интерес к Intlayer для Preact, поставив лайк этому issue.
48
+ ## Содержание
49
49
 
50
- Смотрите [шаблон приложения](https://github.com/aymericzip/intlayer-vite-preact-template) на GitHub.
50
+ <TOC/>
51
51
 
52
52
  ## Что такое Intlayer?
53
53
 
54
- **Intlayer** - это инновационная, открытая библиотека интернационализации (i18n), созданная для упрощения поддержки многоязычности в современных веб-приложениях.
54
+ **Intlayer** это инновационная библиотека интернационализации (i18n) с открытым исходным кодом, разработанная для упрощения поддержки многоязычности в современных веб-приложениях.
55
55
 
56
- С помощью Intlayer вы можете:
56
+ С Intlayer вы можете:
57
57
 
58
- - **Легко управлять переводами** с использованием декларативных словарей на уровне компонентов.
58
+ - **Легко управлять переводами** с помощью декларативных словарей на уровне компонентов.
59
59
  - **Динамически локализовать метаданные**, маршруты и контент.
60
- - **Обеспечить поддержку TypeScript** с помощью автогенерируемых типов, улучшая автодополнение и обнаружение ошибок.
61
- - **Воспользуйтесь расширенными возможностями**, такими как динамическое определение и переключение локали.
60
+ - **Обеспечить поддержку TypeScript** с помощью автоматически генерируемых типов, улучшающих автодополнение и обнаружение ошибок.
61
+ - **Пользоваться расширенными функциями**, такими как динамическое определение локали и переключение языков.
62
62
 
63
63
  ---
64
64
 
65
65
  ## Пошаговое руководство по настройке Intlayer в приложении на Vite и Preact
66
66
 
67
+ См. [Шаблон приложения](https://github.com/aymericzip/intlayer-vite-preact-template) на GitHub.
68
+
67
69
  ### Шаг 1: Установка зависимостей
68
70
 
69
71
  Установите необходимые пакеты с помощью npm:
@@ -94,15 +96,15 @@ bunx intlayer init
94
96
 
95
97
  - **intlayer**
96
98
 
97
- - **intlayer**
98
-
99
- Основной пакет, предоставляющий инструменты интернационализации для управления конфигурацией, перевода, [объявления контента](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).
99
+ Основной пакет, предоставляющий инструменты интернационализации для управления конфигурацией, перевода, [объявления контента](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).
100
100
 
101
101
  - **preact-intlayer**
102
+
102
103
  Пакет, который интегрирует Intlayer с приложением на Preact. Он предоставляет провайдеры контекста и хуки для интернационализации Preact.
103
104
 
104
105
  - **vite-intlayer**
105
- Включает плагин Vite для интеграции Intlayer с [сборщиком Vite](https://vite.dev/guide/why.html#why-bundle-for-production), а также middleware для определения предпочтительной локали пользователя, управления cookie и обработки перенаправления URL.
106
+
107
+ Включает плагин Vite для интеграции Intlayer с [сборщиком Vite](https://vite.dev/guide/why.html#why-bundle-for-production), а также промежуточное ПО для определения предпочтительной локали пользователя, управления куки и обработки перенаправления URL.
106
108
 
107
109
  ### Шаг 2: Конфигурация вашего проекта
108
110
 
@@ -121,6 +123,10 @@ const config: IntlayerConfig = {
121
123
  ],
122
124
  defaultLocale: Locales.ENGLISH,
123
125
  },
126
+ routing: {
127
+ mode: "prefix-no-default", // По умолчанию: префикс для всех локалей, кроме основной
128
+ storage: ["cookie", "header"], // По умолчанию: хранение локали в куки и определение из заголовка
129
+ },
124
130
  };
125
131
 
126
132
  export default config;
@@ -140,6 +146,10 @@ const config = {
140
146
  ],
141
147
  defaultLocale: Locales.ENGLISH,
142
148
  },
149
+ routing: {
150
+ mode: "prefix-no-default", // По умолчанию: префикс для всех локалей, кроме основной
151
+ storage: ["cookie", "header"], // По умолчанию: хранение локали в куки и определение из заголовка
152
+ },
143
153
  };
144
154
 
145
155
  export default config;
@@ -149,7 +159,6 @@ export default config;
149
159
  const { Locales } = require("intlayer");
150
160
 
151
161
  /** @type {import('intlayer').IntlayerConfig} */
152
- // Конфигурация интернационализации
153
162
  const config = {
154
163
  internationalization: {
155
164
  locales: [
@@ -160,14 +169,18 @@ const config = {
160
169
  ],
161
170
  defaultLocale: Locales.ENGLISH,
162
171
  },
172
+ routing: {
173
+ mode: "prefix-no-default", // По умолчанию: префикс для всех локалей, кроме основной
174
+ storage: ["cookie", "header"], // По умолчанию: хранение локали в куки и определение из заголовка
175
+ },
163
176
  };
164
177
 
165
178
  module.exports = config;
166
179
  ```
167
180
 
168
- > Через этот конфигурационный файл вы можете настроить локализованные URL, перенаправление в промежуточном ПО, имена cookie, расположение и расширение ваших деклараций контента, отключить логи Intlayer в консоли и многое другое. Для полного списка доступных параметров обратитесь к [документации по конфигурации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md).
181
+ > Через этот конфигурационный файл вы можете настроить локализованные URL, режимы маршрутизации, параметры хранения, имена куки, расположение и расширение ваших объявлений контента, отключить логи Intlayer в консоли и многое другое. Полный список доступных параметров см. в [документации по конфигурации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md).
169
182
 
170
- ### Шаг 3: Интеграция Intlayer в вашу конфигурацию Vite
183
+ ### Шаг 3: Интеграция Intlayer в конфигурацию Vite
171
184
 
172
185
  Добавьте плагин intlayer в вашу конфигурацию.
173
186
 
@@ -204,11 +217,11 @@ module.exports = defineConfig({
204
217
  });
205
218
  ```
206
219
 
207
- > Плагин Vite `intlayer()` используется для интеграции Intlayer с Vite. Он обеспечивает сборку файлов деклараций контента и отслеживает их в режиме разработки. Определяет переменные окружения Intlayer внутри приложения Vite. Кроме того, предоставляет алиасы для оптимизации производительности.
220
+ > Плагин Vite `intlayer()` используется для интеграции Intlayer с Vite. Он обеспечивает сборку файлов объявлений контента и отслеживает их в режиме разработки. Он определяет переменные окружения Intlayer внутри приложения Vite. Кроме того, он предоставляет алиасы для оптимизации производительности.
208
221
 
209
- ### Шаг 4: Объявите Ваш Контент
222
+ ### Шаг 4: Объявление контента
210
223
 
211
- Создайте и управляйте декларациями контента для хранения переводов:
224
+ Создайте и управляйте своими объявлениями контента для хранения переводов:
212
225
 
213
226
  ```tsx fileName="src/app.content.tsx" contentDeclarationFormat="typescript"
214
227
  import { t, type Dictionary } from "intlayer";
@@ -225,7 +238,7 @@ const appContent = {
225
238
  preactLogo: t({
226
239
  en: "Preact logo",
227
240
  fr: "Logo Preact",
228
- es: "Логотип Preact",
241
+ es: "Logo Preact",
229
242
  }),
230
243
 
231
244
  title: "Vite + Preact",
@@ -239,7 +252,7 @@ const appContent = {
239
252
  edit: t<ComponentChildren>({
240
253
  en: (
241
254
  <>
242
- Редактируйте <code>src/app.tsx</code> и сохраните, чтобы проверить HMR
255
+ Edit <code>src/app.tsx</code> and save to test HMR
243
256
  </>
244
257
  ),
245
258
  fr: (
@@ -267,7 +280,7 @@ export default appContent;
267
280
 
268
281
  ```javascript fileName="src/app.content.mjs" contentDeclarationFormat="esm"
269
282
  import { t } from "intlayer";
270
- // import { h } from 'preact'; // Нужно, если вы используете JSX напрямую в .mjs
283
+ // import { h } from 'preact'; // Требуется, если вы используете JSX напрямую в .mjs
271
284
 
272
285
  /** @type {import('intlayer').Dictionary} */
273
286
  const appContent = {
@@ -275,13 +288,13 @@ const appContent = {
275
288
  content: {
276
289
  viteLogo: t({
277
290
  en: "Vite logo",
278
- fr: "Логотип Vite",
279
- es: "Логотип Vite",
291
+ fr: "Logo Vite",
292
+ es: "Logo Vite",
280
293
  }),
281
294
  preactLogo: t({
282
295
  en: "Preact logo",
283
- fr: "Логотип Preact",
284
- es: "Логотип Preact",
296
+ fr: "Logo Preact",
297
+ es: "Logo Preact",
285
298
  }),
286
299
 
287
300
  title: "Vite + Preact",
@@ -299,8 +312,8 @@ const appContent = {
299
312
  }),
300
313
 
301
314
  readTheDocs: t({
302
- en: "Нажмите на логотипы Vite и Preact, чтобы узнать больше",
303
- fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
315
+ en: "Click on the Vite and Preact logos to learn more",
316
+ fr: "Cliqueз sur les logos Vite et Preact pour en savoir plus",
304
317
  es: "Haga clic en los logotipos de Vite y Preact para obtener más información",
305
318
  }),
306
319
  },
@@ -311,19 +324,19 @@ export default appContent;
311
324
 
312
325
  ```javascript fileName="src/app.content.cjs" contentDeclarationFormat="commonjs"
313
326
  const { t } = require("intlayer");
314
- // const { h } = require('preact'); // Нужно, если вы используете JSX напрямую в .cjs
327
+ // const { h } = require('preact'); // Требуется, если вы используете JSX напрямую в .cjs
315
328
 
316
329
  /** @type {import('intlayer').Dictionary} */
317
330
  const appContent = {
318
331
  key: "app",
319
332
  content: {
320
333
  viteLogo: t({
321
- en: "Логотип Vite",
334
+ en: "Vite logo",
322
335
  fr: "Logo Vite",
323
336
  es: "Logo Vite",
324
337
  }),
325
338
  preactLogo: t({
326
- en: "Логотип Preact",
339
+ en: "Preact logo",
327
340
  fr: "Logo Preact",
328
341
  es: "Logo Preact",
329
342
  }),
@@ -334,21 +347,18 @@ const appContent = {
334
347
  en: "count is ",
335
348
  fr: "le compte est ",
336
349
  es: "el recuento es ",
337
- ru: "счётчик равен ",
338
350
  }),
339
351
 
340
352
  edit: t({
341
353
  en: "Edit src/app.tsx and save to test HMR",
342
354
  fr: "Éditez src/app.tsx et enregistrez pour tester HMR",
343
355
  es: "Edita src/app.tsx y guarda para probar HMR",
344
- ru: "Отредактируйте src/app.tsx и сохраните, чтобы проверить HMR",
345
356
  }),
346
357
 
347
358
  readTheDocs: t({
348
359
  en: "Click on the Vite and Preact logos to learn more",
349
360
  fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
350
361
  es: "Haga clic en los logotipos de Vite y Preact para obtener más información",
351
- ru: "Нажмите на логотипы Vite и Preact, чтобы узнать больше",
352
362
  }),
353
363
  },
354
364
  };
@@ -366,8 +376,7 @@ module.exports = appContent;
366
376
  "translation": {
367
377
  "en": "Vite logo",
368
378
  "fr": "Logo Vite",
369
- "es": "Logo Vite",
370
- "ru": "Логотип Vite" // комментарий: перевод для русского языка
379
+ "es": "Logo Vite"
371
380
  }
372
381
  },
373
382
  "preactLogo": {
@@ -375,8 +384,7 @@ module.exports = appContent;
375
384
  "translation": {
376
385
  "en": "Preact logo",
377
386
  "fr": "Logo Preact",
378
- "es": "Logo Preact",
379
- "ru": "Логотип Preact" // комментарий: перевод для русского языка
387
+ "es": "Logo Preact"
380
388
  }
381
389
  },
382
390
  "title": {
@@ -384,8 +392,7 @@ module.exports = appContent;
384
392
  "translation": {
385
393
  "en": "Vite + Preact",
386
394
  "fr": "Vite + Preact",
387
- "es": "Vite + Preact",
388
- "ru": "Vite + Preact" // комментарий: название технологии не переводится
395
+ "es": "Vite + Preact"
389
396
  }
390
397
  },
391
398
  "count": {
@@ -393,8 +400,7 @@ module.exports = appContent;
393
400
  "translation": {
394
401
  "en": "count is ",
395
402
  "fr": "le compte est ",
396
- "es": "el recuento es ",
397
- "ru": "счётчик равен " // комментарий: перевод для русского языка
403
+ "es": "el recuento es "
398
404
  }
399
405
  },
400
406
  "edit": {
@@ -402,8 +408,7 @@ module.exports = appContent;
402
408
  "translation": {
403
409
  "en": "Edit src/app.tsx and save to test HMR",
404
410
  "fr": "Éditez src/app.tsx et enregistrez pour tester HMR",
405
- "es": "Edita src/app.tsx y guarda para probar HMR",
406
- "ru": "Отредактируйте src/app.tsx и сохраните, чтобы проверить HMR"
411
+ "es": "Edita src/app.tsx y guarda para probar HMR"
407
412
  }
408
413
  },
409
414
  "readTheDocs": {
@@ -411,21 +416,20 @@ module.exports = appContent;
411
416
  "translation": {
412
417
  "en": "Click on the Vite and Preact logos to learn more",
413
418
  "fr": "Cliquez sur les logos Vite et Preact pour en savoir plus",
414
- "es": "Haga clic en los logotipos de Vite y Preact para obtener más información",
415
- "ru": "Нажмите на логотипы Vite и Preact, чтобы узнать больше"
419
+ "es": "Haga clic en los logotipos de Vite y Preact para obtener más información"
416
420
  }
417
421
  }
418
422
  }
419
423
  }
420
424
  ```
421
425
 
422
- > Ваши объявления контента могут быть определены в любом месте вашего приложения, как только они будут включены в каталог `contentDir` (по умолчанию, `./src`). И соответствовать расширению файла объявления контента (по умолчанию, `.content.{json,ts,tsx,js,jsx,mjs,cjs}`).
426
+ > Ваши объявления контента могут быть определены в любом месте вашего приложения, при условии, что они включены в каталог `contentDir` (по умолчанию `./src`). И соответствуют расширению файла объявлений контента (по умолчанию `.content.{json,ts,tsx,js,jsx,mjs,cjs}`).
423
427
 
424
- > Для получения дополнительной информации обратитесь к [документации по объявлениям контента](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dictionary/get_started.md).
428
+ > Подробнее см. в [документации по объявлению контента](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dictionary/content_file.md).
425
429
 
426
- > Если ваш файл контента содержит код TSX, возможно, вам потребуется импортировать `import { h } from "preact";` или убедиться, что ваш JSX pragma правильно настроен для Preact.
430
+ > Если ваш файл контента содержит код TSX, вам может потребоваться импортировать `import { h } from "preact";` или убедиться, что ваша JSX прагма правильно настроена для Preact.
427
431
 
428
- ### Шаг 5: Используйте Intlayer в вашем коде
432
+ ### Шаг 5: Использование Intlayer в коде
429
433
 
430
434
  Получайте доступ к вашим словарям контента по всему приложению:
431
435
 
@@ -463,6 +467,12 @@ const AppContent: FunctionalComponent = () => {
463
467
  </button>
464
468
  <p>{content.edit}</p>
465
469
  </div>
470
+ {/* Markdown контент */}
471
+ <div>{content.myMarkdownContent}</div>
472
+
473
+ {/* HTML контент */}
474
+ <div>{content.myHtmlContent}</div>
475
+
466
476
  <p class="read-the-docs">{content.readTheDocs}</p>
467
477
  </>
468
478
  );
@@ -571,7 +581,7 @@ const App = () => (
571
581
  module.exports = App;
572
582
  ```
573
583
 
574
- > Если вы хотите использовать ваш контент в атрибуте типа `string`, таком как `alt`, `title`, `href`, `aria-label` и т.д., вы должны вызвать значение функции, например:
584
+ > Если вы хотите использовать свой контент в строковом атрибуте, таком как `alt`, `title`, `href`, `aria-label` и т. д., вы должны вызвать значение функции, например:
575
585
 
576
586
  > ```jsx
577
587
  > <img src={content.image.src.value} alt={content.image.value} />
@@ -579,11 +589,11 @@ module.exports = App;
579
589
 
580
590
  > Примечание: В Preact `className` обычно пишется как `class`.
581
591
 
582
- > Чтобы узнать больше о хуке `useIntlayer`, обратитесь к [документации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useIntlayer.md) (API аналогично для `preact-intlayer`).
592
+ > Чтобы узнать больше о хуке `useIntlayer`, обратитесь к [документации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useIntlayer.md) (API для `preact-intlayer` аналогично).
583
593
 
584
- ### (Необязательно) Шаг 6: Изменение языка вашего контента
594
+ ### (Необязательно) Шаг 6: Изменение языка контента
585
595
 
586
- Для изменения языка вашего контента вы можете использовать функцию `setLocale`, предоставляемую хуком `useLocale`. Эта функция позволяет установить локаль приложения и обновить контент соответственно.
596
+ Для изменения языка контента вы можете использовать функцию `setLocale`, предоставляемую хуком `useLocale`. Эта функция позволяет установить локаль приложения и обновить контент соответствующим образом.
587
597
 
588
598
  ```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
589
599
  import type { FunctionalComponent } from "preact";
@@ -595,7 +605,7 @@ const LocaleSwitcher: FunctionalComponent = () => {
595
605
 
596
606
  return (
597
607
  <button onClick={() => setLocale(Locales.ENGLISH)}>
598
- Изменить язык на английский
608
+ Change Language to English
599
609
  </button>
600
610
  );
601
611
  };
@@ -612,7 +622,7 @@ const LocaleSwitcher = () => {
612
622
 
613
623
  return (
614
624
  <button onClick={() => setLocale(Locales.ENGLISH)}>
615
- Изменить язык на английский
625
+ Change Language to English
616
626
  </button>
617
627
  );
618
628
  };
@@ -629,7 +639,7 @@ const LocaleSwitcher = () => {
629
639
 
630
640
  return (
631
641
  <button onClick={() => setLocale(Locales.ENGLISH)}>
632
- Изменить язык на английский
642
+ Change Language to English
633
643
  </button>
634
644
  );
635
645
  };
@@ -637,11 +647,11 @@ const LocaleSwitcher = () => {
637
647
  module.exports = LocaleSwitcher;
638
648
  ```
639
649
 
640
- > Чтобы узнать больше о хуке `useLocale`, обратитесь к [документации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useLocale.md) (API аналогично для `preact-intlayer`).
650
+ > Чтобы узнать больше о хуке `useLocale`, обратитесь к [документации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useLocale.md) (API для `preact-intlayer` аналогично).
641
651
 
642
652
  ### (Необязательно) Шаг 7: Добавьте локализованную маршрутизацию в ваше приложение
643
653
 
644
- Цель этого шага - создать уникальные маршруты для каждого языка. Это полезно для SEO и URL, дружественных к SEO.
654
+ Цель этого шага создать уникальные маршруты для каждого языка. Это полезно для SEO и создания дружественных к поисковым системам URL.
645
655
  Пример:
646
656
 
647
657
  ```plaintext
@@ -650,142 +660,15 @@ module.exports = LocaleSwitcher;
650
660
  - https://example.com/fr/about
651
661
  ```
652
662
 
653
- > По умолчанию маршруты не имеют префикса для локали по умолчанию. Если вы хотите добавить префикс для локали по умолчанию, вы можете установить опцию `middleware.prefixDefault` в значение `true` в вашей конфигурации. Подробнее смотрите в [документации по конфигурации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md).
654
-
655
- Чтобы добавить локализованную маршрутизацию в ваше приложение, вы можете создать компонент `LocaleRouter`, который обернет маршруты вашего приложения и будет обрабатывать маршрутизацию на основе локали. Вот пример с использованием [preact-iso](https://github.com/preactjs/preact-iso):
663
+ > По умолчанию маршруты не имеют префикса для основной локали. Если вы хотите добавить префикс для основной локали, вы можете установить опцию `routing.mode` в значение `"prefix-all"` в вашей конфигурации. См. [документацию по конфигурации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md) для получения дополнительной информации.
656
664
 
657
- Сначала установите `preact-iso`:
658
-
659
- ```bash packageManager="npm"
660
- npm install preact-iso
661
- npx intlayer init
662
- ```
663
-
664
- ```bash packageManager="pnpm"
665
- pnpm add preact-iso
666
- pnpm intlayer init
667
- ```
668
-
669
- ```bash packageManager="yarn"
670
- yarn add preact-iso
671
- ```
665
+ Чтобы добавить локализованную маршрутизацию в ваше приложение, вы можете создать компонент `LocaleRouter`, который оборачивает маршруты вашего приложения и обрабатывает маршрутизацию на основе локали. Вот пример использования [preact-iso](https://github.com/preactjs/preact-iso):
672
666
 
673
667
  ```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
674
- import { type Locales, configuration, getPathWithoutLocale } from "intlayer";
675
- import { ComponentChildren, FunctionalComponent } from "preact";
668
+ import { localeMap } from "intlayer";
676
669
  import { IntlayerProvider } from "preact-intlayer";
677
- import { LocationProvider, useLocation } from "preact-iso";
678
- import { useEffect } from "preact/hooks";
679
-
680
- const { internationalization, middleware } = configuration;
681
- const { locales, defaultLocale } = internationalization;
682
-
683
- const Navigate: FunctionalComponent<{ to: string; replace?: boolean }> = ({
684
- to,
685
- replace,
686
- }) => {
687
- const { route } = useLocation();
688
- useEffect(() => {
689
- route(to, replace);
690
- }, [to, replace, route]);
691
- return null;
692
- };
693
-
694
- /**
695
- /**
696
- * Компонент, который обрабатывает локализацию и оборачивает дочерние элементы в соответствующий контекст локали.
697
- * Он управляет определением и проверкой локали на основе URL.
698
- */
699
- const AppLocalized: FunctionalComponent<{
700
- children: ComponentChildren;
701
- locale?: Locales;
702
- }> = ({ children, locale }) => {
703
- const { path: pathname, url } = useLocation();
704
-
705
- if (!url) {
706
- return null;
707
- }
708
-
709
- const search = url.substring(pathname.length);
710
-
711
- // Определяем текущую локаль, используя локаль по умолчанию, если не указана
712
- const currentLocale = locale ?? defaultLocale;
713
-
714
- // Удаляем префикс локали из пути для построения базового пути
715
- const pathWithoutLocale = getPathWithoutLocale(
716
- pathname // Текущий путь URL
717
- );
718
-
719
- /**
720
- * Если middleware.prefixDefault установлено в true, префикс с локалью по умолчанию должен всегда использоваться.
721
- */
722
- if (middleware.prefixDefault) {
723
- // Проверка локали
724
- if (!locale || !locales.includes(locale)) {
725
- // Перенаправление на локаль по умолчанию с обновлённым путём
726
- return (
727
- <Navigate
728
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
729
- replace // Заменить текущую запись в истории на новую
730
- />
731
- );
732
- }
733
-
734
- // Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
735
- return (
736
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
737
- );
738
- } else {
739
- /**
740
- * Когда middleware.prefixDefault равно false, префикс локали по умолчанию не используется.
741
- * Убедитесь, что текущая локаль действительна и не является локалью по умолчанию.
742
- */
743
- if (
744
- currentLocale.toString() !== defaultLocale.toString() &&
745
- !locales
746
- .filter(
747
- (loc) => loc.toString() !== defaultLocale.toString() // Исключить локаль по умолчанию
748
- )
749
- .includes(currentLocale) // Проверить, входит ли текущая локаль в список допустимых локалей
750
- ) {
751
- // Перенаправить на путь без префикса локали
752
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
753
- }
754
-
755
- // Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
756
- return (
757
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
758
- );
759
- }
760
- };
761
-
762
- const RouterContent: FunctionalComponent<{
763
- children: ComponentChildren;
764
- }> = ({ children }) => {
765
- const { path } = useLocation();
766
-
767
- if (!path) {
768
- return null;
769
- }
770
-
771
- const pathLocale = path.split("/")[1] as Locales;
772
-
773
- const isLocaleRoute = locales
774
- .filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
775
- .some((locale) => locale.toString() === pathLocale);
776
-
777
- if (isLocaleRoute) {
778
- return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
779
- }
780
-
781
- return (
782
- <AppLocalized
783
- locale={!middleware.prefixDefault ? defaultLocale : undefined}
784
- >
785
- {children}
786
- </AppLocalized>
787
- );
788
- };
670
+ import { LocationProvider, Router, Route } from "preact-iso";
671
+ import type { ComponentChildren, FunctionalComponent } from "preact";
789
672
 
790
673
  /**
791
674
  * Компонент маршрутизатора, который настраивает маршруты с учетом локали.
@@ -795,120 +678,27 @@ export const LocaleRouter: FunctionalComponent<{
795
678
  children: ComponentChildren;
796
679
  }> = ({ children }) => (
797
680
  <LocationProvider>
798
- <RouterContent>{children}</RouterContent>
681
+ <Router>
682
+ {localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
683
+ .sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
684
+ .map(({ locale, urlPrefix }) => (
685
+ <Route
686
+ key={locale}
687
+ path={`${urlPrefix}/:rest*`}
688
+ component={() => (
689
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
690
+ )}
691
+ />
692
+ ))}
693
+ </Router>
799
694
  </LocationProvider>
800
695
  );
801
696
  ```
802
697
 
803
698
  ```jsx fileName="src/components/LocaleRouter.jsx" codeFormat="esm"
804
- // Импорт необходимых зависимостей и функций
805
- import { configuration, getPathWithoutLocale } from "intlayer";
699
+ import { localeMap } from "intlayer";
806
700
  import { IntlayerProvider } from "preact-intlayer";
807
- import { LocationProvider, useLocation } from "preact-iso";
808
- import { useEffect } from "preact/hooks";
809
- import { h } from "preact"; // Необходимо для JSX
810
-
811
- // Деструктуризация конфигурации из Intlayer
812
- const { internationalization, middleware } = configuration;
813
- const { locales, defaultLocale } = internationalization;
814
-
815
- const Navigate = ({ to, replace }) => {
816
- const { route } = useLocation();
817
- useEffect(() => {
818
- route(to, replace);
819
- }, [to, replace, route]);
820
- return null;
821
- };
822
-
823
- /**
824
- * Компонент, который обрабатывает локализацию и оборачивает дочерние элементы в соответствующий контекст локали.
825
- * Он управляет определением и проверкой локали на основе URL.
826
- */
827
- const AppLocalized = ({ children, locale }) => {
828
- const { path: pathname, url } = useLocation();
829
-
830
- if (!url) {
831
- return null;
832
- }
833
-
834
- const search = url.substring(pathname.length);
835
-
836
- // Определяем текущую локаль, используя локаль по умолчанию, если не указана
837
- const currentLocale = locale ?? defaultLocale;
838
-
839
- // Удаляем префикс локали из пути для построения базового пути
840
- const pathWithoutLocale = getPathWithoutLocale(
841
- pathname // Текущий путь URL
842
- );
843
-
844
- /**
845
- * Если middleware.prefixDefault равно true, префикс локали по умолчанию всегда должен присутствовать.
846
- */
847
- if (middleware.prefixDefault) {
848
- // Проверяем корректность локали
849
- if (!locale || !locales.includes(locale)) {
850
- // Перенаправляем на локаль по умолчанию с обновлённым путём
851
- return (
852
- <Navigate
853
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
854
- replace // Заменяем текущую запись в истории на новую
855
- />
856
- );
857
- }
858
-
859
- // Оборачиваем дочерние элементы в IntlayerProvider и устанавливаем текущую локаль
860
- return (
861
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
862
- );
863
- } else {
864
- /**
865
- * Если middleware.prefixDefault равно false, локаль по умолчанию не префиксируется.
866
- * Убедитесь, что текущая локаль валидна и не является локалью по умолчанию.
867
- */
868
- if (
869
- currentLocale.toString() !== defaultLocale.toString() &&
870
- !locales
871
- .filter(
872
- (loc) => loc.toString() !== defaultLocale.toString() // Исключить локаль по умолчанию
873
- )
874
- .includes(currentLocale) // Проверить, входит ли текущая локаль в список допустимых локалей
875
- ) {
876
- // Перенаправить на путь без префикса локали
877
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
878
- }
879
-
880
- // Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
881
- return (
882
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
883
- );
884
- }
885
- };
886
-
887
- const RouterContent = ({ children }) => {
888
- const { path } = useLocation();
889
-
890
- if (!path) {
891
- return null;
892
- }
893
-
894
- const pathLocale = path.split("/")[1];
895
-
896
- const isLocaleRoute = locales
897
- .filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
898
- .some((locale) => locale.toString() === pathLocale);
899
-
900
- if (isLocaleRoute) {
901
- return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
902
- }
903
-
904
- return (
905
- <AppLocalized
906
- locale={!middleware.prefixDefault ? defaultLocale : undefined}
907
- >
908
- {children}
909
- </AppLocalized>
910
- );
911
- };
701
+ import { LocationProvider, Router, Route } from "preact-iso";
912
702
 
913
703
  /**
914
704
  * Компонент маршрутизатора, который настраивает маршруты с учетом локали.
@@ -916,143 +706,61 @@ const RouterContent = ({ children }) => {
916
706
  */
917
707
  export const LocaleRouter = ({ children }) => (
918
708
  <LocationProvider>
919
- <RouterContent>{children}</RouterContent>
709
+ <Router>
710
+ {localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
711
+ .sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
712
+ .map(({ locale, urlPrefix }) => (
713
+ <Route
714
+ key={locale}
715
+ path={`${urlPrefix}/:rest*`}
716
+ component={() => (
717
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
718
+ )}
719
+ />
720
+ ))}
721
+ </Router>
920
722
  </LocationProvider>
921
723
  );
922
724
  ```
923
725
 
924
726
  ```jsx fileName="src/components/LocaleRouter.cjsx" codeFormat="commonjs"
925
- // Импорт необходимых зависимостей и функций
926
- const { configuration, getPathWithoutLocale } = require("intlayer");
727
+ const { localeMap } = require("intlayer");
927
728
  const { IntlayerProvider } = require("preact-intlayer");
928
- const { LocationProvider, useLocation } = require("preact-iso");
929
- const { useEffect } = require("preact/hooks");
930
- const { h } = require("preact"); // Необходимо для JSX
931
-
932
- // Деструктуризация конфигурации из Intlayer
933
- const { internationalization, middleware } = configuration;
934
- const { locales, defaultLocale } = internationalization;
935
-
936
- const Navigate = ({ to, replace }) => {
937
- const { route } = useLocation();
938
- useEffect(() => {
939
- route(to, replace);
940
- }, [to, replace, route]);
941
- return null;
942
- };
943
-
944
- /**
945
- * Компонент, который обрабатывает локализацию и оборачивает дочерние элементы в соответствующий контекст локали.
946
- * Управляет определением и проверкой локали на основе URL.
947
- */
948
- const AppLocalized = ({ children, locale }) => {
949
- const { path: pathname, url } = useLocation();
950
-
951
- if (!url) {
952
- return null;
953
- }
954
-
955
- const search = url.substring(pathname.length);
956
-
957
- // Определяем текущую локаль, по умолчанию используем локаль по умолчанию, если не указана
958
- const currentLocale = locale ?? defaultLocale;
959
-
960
- // Удаляем префикс локали из пути для построения базового пути
961
- const pathWithoutLocale = getPathWithoutLocale(
962
- pathname // Текущий путь URL
963
- );
964
-
965
- /**
966
- * Если middleware.prefixDefault равно true, префикс локали по умолчанию всегда должен присутствовать.
967
- */
968
- if (middleware.prefixDefault) {
969
- // Проверяем валидность локали
970
- if (!locale || !locales.includes(locale)) {
971
- // Перенаправляем на локаль по умолчанию с обновлённым путём
972
- return (
973
- <Navigate
974
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
975
- replace // Заменить текущую запись истории на новую
976
- />
977
- );
978
- }
979
-
980
- // Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
981
- return (
982
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
983
- );
984
- } else {
985
- /**
986
- * Когда middleware.prefixDefault равно false, префикс для локали по умолчанию не используется.
987
- * Убедиться, что текущая локаль действительна и не является локалью по умолчанию.
988
- */
989
- if (
990
- currentLocale.toString() !== defaultLocale.toString() &&
991
- !locales
992
- .filter(
993
- (loc) => loc.toString() !== defaultLocale.toString() // Исключить локаль по умолчанию
994
- )
995
- .includes(currentLocale) // Проверяем, находится ли текущая локаль в списке допустимых локалей
996
- ) {
997
- // Перенаправляем на путь без префикса локали
998
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
999
- }
1000
-
1001
- // Оборачиваем дочерние элементы в IntlayerProvider и устанавливаем текущую локаль
1002
- return (
1003
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
1004
- );
1005
- }
1006
- };
1007
-
1008
- const RouterContent = ({ children }) => {
1009
- const { path } = useLocation();
1010
-
1011
- if (!path) {
1012
- return null;
1013
- }
1014
-
1015
- const pathLocale = path.split("/")[1];
1016
-
1017
- const isLocaleRoute = locales
1018
- .filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
1019
- .some((locale) => locale.toString() === pathLocale);
1020
-
1021
- if (isLocaleRoute) {
1022
- return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
1023
- }
1024
-
1025
- return (
1026
- <AppLocalized
1027
- locale={!middleware.prefixDefault ? defaultLocale : undefined}
1028
- >
1029
- {children}
1030
- </AppLocalized>
1031
- );
1032
- };
729
+ const { LocationProvider, Router, Route } = require("preact-iso");
1033
730
 
1034
731
  /**
1035
732
  * Компонент маршрутизатора, который настраивает маршруты с учетом локали.
1036
733
  * Использует preact-iso для управления навигацией и рендеринга локализованных компонентов.
1037
734
  */
1038
- const LocaleRouter = ({ children }) => (
1039
- <LocationProvider>
1040
- <RouterContent>{children}</RouterContent>
1041
- </LocationProvider>
1042
- );
735
+ const LocaleRouter = ({ children }) =>
736
+ h(
737
+ LocationProvider,
738
+ {},
739
+ h(
740
+ Router,
741
+ {},
742
+ localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
743
+ .sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
744
+ .map(({ locale, urlPrefix }) =>
745
+ h(Route, {
746
+ key: locale,
747
+ path: `${urlPrefix}/:rest*`,
748
+ component: () => h(IntlayerProvider, { locale }, children),
749
+ })
750
+ )
751
+ )
752
+ );
1043
753
 
1044
754
  module.exports = { LocaleRouter };
1045
755
  ```
1046
756
 
1047
- Затем вы можете использовать компонент `LocaleRouter` в вашем приложении:
757
+ Затем вы можете использовать компонент `LocaleRouter` в своем приложении:
1048
758
 
1049
759
  ```tsx fileName="src/app.tsx" codeFormat="typescript"
1050
760
  import { LocaleRouter } from "./components/LocaleRouter";
1051
761
  import type { FunctionalComponent } from "preact";
1052
- tsx fileName="src/app.tsx" codeFormat="typescript"
1053
- import { LocaleRouter } from "./components/LocaleRouter";
1054
- import type { FunctionalComponent } from "preact";
1055
- // ... Ваш компонент AppContent (определённый на Шаге 5)
762
+
763
+ // ... Ваш компонент AppContent
1056
764
 
1057
765
  const App: FunctionalComponent = () => (
1058
766
  <LocaleRouter>
@@ -1065,7 +773,8 @@ export default App;
1065
773
 
1066
774
  ```jsx fileName="src/app.jsx" codeFormat="esm"
1067
775
  import { LocaleRouter } from "./components/LocaleRouter";
1068
- // ... Ваш компонент AppContent (определённый на Шаге 5)
776
+
777
+ // ... Ваш компонент AppContent
1069
778
 
1070
779
  const App = () => (
1071
780
  <LocaleRouter>
@@ -1078,7 +787,8 @@ export default App;
1078
787
 
1079
788
  ```jsx fileName="src/app.cjsx" codeFormat="commonjs"
1080
789
  const { LocaleRouter } = require("./components/LocaleRouter");
1081
- // ... Ваш компонент AppContent (определённый на Шаге 5)
790
+
791
+ // ... Ваш компонент AppContent
1082
792
 
1083
793
  const App = () => (
1084
794
  <LocaleRouter>
@@ -1089,47 +799,12 @@ const App = () => (
1089
799
  module.exports = App;
1090
800
  ```
1091
801
 
1092
- Параллельно вы также можете использовать `intlayerProxy` для добавления маршрутизации на стороне сервера в ваше приложение. Этот плагин автоматически определит текущую локаль на основе URL и установит соответствующее cookie с локалью. Если локаль не указана, плагин определит наиболее подходящую локаль на основе языковых предпочтений браузера пользователя. Если локаль не будет обнаружена, произойдет перенаправление на локаль по умолчанию.
1093
-
1094
- ```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
1095
- import { defineConfig } from "vite";
1096
- import preact from "@preact/preset-vite";
1097
- import { intlayer, intlayerProxy } from "vite-intlayer";
1098
-
1099
- // https://vitejs.dev/config/
1100
- export default defineConfig({
1101
- plugins: [preact(), intlayer(), intlayerProxy()],
1102
- });
1103
- ```
1104
-
1105
- ```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
1106
- import { defineConfig } from "vite";
1107
- import preact from "@preact/preset-vite";
1108
- import { intlayer, intlayerProxy } from "vite-intlayer";
1109
-
1110
- // https://vitejs.dev/config/
1111
- export default defineConfig({
1112
- plugins: [preact(), intlayer(), intlayerProxy()],
1113
- });
1114
- ```
1115
-
1116
- ```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
1117
- const { defineConfig } = require("vite");
1118
- const preact = require("@preact/preset-vite");
1119
- const { intlayer, intlayerProxy } = require("vite-intlayer");
1120
-
1121
- // https://vitejs.dev/config/
1122
- module.exports = defineConfig({
1123
- plugins: [preact(), intlayer(), intlayerProxy()],
1124
- });
1125
- ```
1126
-
1127
- ### (Необязательно) Шаг 8: Изменение URL при смене локали
802
+ ### (Необязательно) Шаг 8: Изменяйте URL при смене локали
1128
803
 
1129
- Чтобы изменить URL при смене локали, вы можете использовать проп `onLocaleChange`, предоставляемый хуком `useLocale`. Параллельно вы можете использовать `useLocation` и `route` из `preact-iso` для обновления пути URL.
804
+ Чтобы изменить URL при смене локали, вы можете использовать проп `onLocaleChange`, предоставляемый хуком `useLocale`. Параллельно вы можете использовать метод `route` из `useLocation` библиотеки `preact-iso` для обновления пути URL.
1130
805
 
1131
806
  ```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
1132
- import { useLocation, route } from "preact-iso";
807
+ import { useLocation } from "preact-iso";
1133
808
  import {
1134
809
  Locales,
1135
810
  getHTMLTextDir,
@@ -1140,16 +815,15 @@ import { useLocale } from "preact-intlayer";
1140
815
  import type { FunctionalComponent } from "preact";
1141
816
 
1142
817
  const LocaleSwitcher: FunctionalComponent = () => {
1143
- const location = useLocation();
818
+ const { url, route } = useLocation();
1144
819
  const { locale, availableLocales, setLocale } = useLocale({
1145
820
  onLocaleChange: (newLocale) => {
1146
- const currentFullPath = location.url; // preact-iso предоставляет полный URL
1147
- // Формируем URL с обновлённой локалью
821
+ // Создаем URL с обновленной локалью
1148
822
  // Пример: /es/about?foo=bar
1149
- const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
823
+ const pathWithLocale = getLocalizedUrl(url, newLocale);
1150
824
 
1151
825
  // Обновляем путь URL
1152
- route(pathWithLocale, true); // true для замены
826
+ route(pathWithLocale, true); // true для замены (replace)
1153
827
  },
1154
828
  });
1155
829
 
@@ -1159,30 +833,30 @@ const LocaleSwitcher: FunctionalComponent = () => {
1159
833
  <div id="localePopover" popover="auto">
1160
834
  {availableLocales.map((localeItem) => (
1161
835
  <a
1162
- href={getLocalizedUrl(location.url, localeItem)}
836
+ href={getLocalizedUrl(url, localeItem)}
1163
837
  hreflang={localeItem}
1164
838
  aria-current={locale === localeItem ? "page" : undefined}
1165
839
  onClick={(e) => {
1166
840
  e.preventDefault();
1167
841
  setLocale(localeItem);
1168
- // Программная навигация после установки локали будет обработана в onLocaleChange
842
+ // Программная навигация после смены локали будет обработана в onLocaleChange
1169
843
  }}
1170
844
  key={localeItem}
1171
845
  >
1172
846
  <span>
1173
- {/* Локаль - например, FR */}
847
+ {/* Локаль например, FR */}
1174
848
  {localeItem}
1175
849
  </span>
1176
850
  <span>
1177
- {/* Язык на его собственной локали - например, Français */}
851
+ {/* Язык на самой локали например, Français */}
1178
852
  {getLocaleName(localeItem, localeItem)}
1179
853
  </span>
1180
854
  <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1181
- {/* Язык на текущей локали - например, Francés при установленной локали Locales.SPANISH */}
855
+ {/* Язык на текущей локали например, Francés, если текущая локаль Locales.SPANISH */}
1182
856
  {getLocaleName(localeItem, locale)}
1183
857
  </span>
1184
858
  <span dir="ltr" lang={Locales.ENGLISH}>
1185
- {/* Язык на английском - например, French */}
859
+ {/* Язык на английском например, French */}
1186
860
  {getLocaleName(localeItem, Locales.ENGLISH)}
1187
861
  </span>
1188
862
  </a>
@@ -1196,7 +870,7 @@ export default LocaleSwitcher;
1196
870
  ```
1197
871
 
1198
872
  ```jsx fileName="src/components/LocaleSwitcher.jsx" codeFormat="esm"
1199
- import { useLocation, route } from "preact-iso";
873
+ import { useLocation } from "preact-iso";
1200
874
  import {
1201
875
  Locales,
1202
876
  getHTMLTextDir,
@@ -1204,14 +878,12 @@ import {
1204
878
  getLocalizedUrl,
1205
879
  } from "intlayer";
1206
880
  import { useLocale } from "preact-intlayer";
1207
- import { h } from "preact"; // Для JSX
1208
881
 
1209
882
  const LocaleSwitcher = () => {
1210
- const location = useLocation();
883
+ const { url, route } = useLocation();
1211
884
  const { locale, availableLocales, setLocale } = useLocale({
1212
885
  onLocaleChange: (newLocale) => {
1213
- const currentFullPath = location.url;
1214
- const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
886
+ const pathWithLocale = getLocalizedUrl(url, newLocale);
1215
887
  route(pathWithLocale, true);
1216
888
  },
1217
889
  });
@@ -1222,7 +894,7 @@ const LocaleSwitcher = () => {
1222
894
  <div id="localePopover" popover="auto">
1223
895
  {availableLocales.map((localeItem) => (
1224
896
  <a
1225
- href={getLocalizedUrl(location.url, localeItem)}
897
+ href={getLocalizedUrl(url, localeItem)}
1226
898
  hreflang={localeItem}
1227
899
  aria-current={locale === localeItem ? "page" : undefined}
1228
900
  onClick={(e) => {
@@ -1250,7 +922,7 @@ export default LocaleSwitcher;
1250
922
  ```
1251
923
 
1252
924
  ```jsx fileName="src/components/LocaleSwitcher.cjsx" codeFormat="commonjs"
1253
- const { useLocation, route } = require("preact-iso");
925
+ const { useLocation } = require("preact-iso");
1254
926
  const {
1255
927
  Locales,
1256
928
  getHTMLTextDir,
@@ -1258,45 +930,51 @@ const {
1258
930
  getLocalizedUrl,
1259
931
  } = require("intlayer");
1260
932
  const { useLocale } = require("preact-intlayer");
1261
- const { h } = require("preact"); // Для JSX
1262
933
 
1263
934
  const LocaleSwitcher = () => {
1264
- const location = useLocation();
935
+ const { url, route } = useLocation();
1265
936
  const { locale, availableLocales, setLocale } = useLocale({
1266
937
  onLocaleChange: (newLocale) => {
1267
- const currentFullPath = location.url;
1268
- const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
938
+ const pathWithLocale = getLocalizedUrl(url, newLocale);
1269
939
  route(pathWithLocale, true);
1270
940
  },
1271
941
  });
1272
942
 
1273
- return (
1274
- <div>
1275
- <button popovertarget="localePopover">{getLocaleName(locale)}</button>
1276
- <div id="localePopover" popover="auto">
1277
- {availableLocales.map((localeItem) => (
1278
- <a
1279
- href={getLocalizedUrl(location.url, localeItem)}
1280
- hreflang={localeItem}
1281
- aria-current={locale === localeItem ? "page" : undefined}
1282
- onClick={(e) => {
943
+ return h(
944
+ "div",
945
+ {},
946
+ h("button", { popovertarget: "localePopover" }, getLocaleName(locale)),
947
+ h(
948
+ "div",
949
+ { id: "localePopover", popover: "auto" },
950
+ availableLocales.map((localeItem) =>
951
+ h(
952
+ "a",
953
+ {
954
+ href: getLocalizedUrl(url, localeItem),
955
+ hreflang: localeItem,
956
+ "aria-current": locale === localeItem ? "page" : undefined,
957
+ onClick: (e) => {
1283
958
  e.preventDefault();
1284
959
  setLocale(localeItem);
1285
- }}
1286
- key={localeItem}
1287
- >
1288
- <span>{localeItem}</span>
1289
- <span>{getLocaleName(localeItem, localeItem)}</span>
1290
- <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1291
- {getLocaleName(localeItem, locale)}
1292
- </span>
1293
- <span dir="ltr" lang={Locales.ENGLISH}>
1294
- {getLocaleName(localeItem, Locales.ENGLISH)}
1295
- </span>
1296
- </a>
1297
- ))}
1298
- </div>
1299
- </div>
960
+ },
961
+ key: localeItem,
962
+ },
963
+ h("span", {}, localeItem),
964
+ h("span", {}, getLocaleName(localeItem, localeItem)),
965
+ h(
966
+ "span",
967
+ { dir: getHTMLTextDir(localeItem), lang: localeItem },
968
+ getLocaleName(localeItem, locale)
969
+ ),
970
+ h(
971
+ "span",
972
+ { dir: "ltr", lang: Locales.ENGLISH },
973
+ getLocaleName(localeItem, Locales.ENGLISH)
974
+ )
975
+ )
976
+ )
977
+ )
1300
978
  );
1301
979
  };
1302
980
 
@@ -1305,40 +983,21 @@ module.exports = LocaleSwitcher;
1305
983
 
1306
984
  > Ссылки на документацию:
1307
985
  >
1308
- > > - [`useLocale` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useLocale.md) (API аналогично для `preact-intlayer`)
1309
- > > - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocaleName.md)
1310
- > > - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocalizedUrl.md)
1311
- > > - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getHTMLTextDir.md)
1312
- > > - Атрибут [`hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=ru)
1313
- > > - Атрибут [`lang`](https://developer.mozilla.org/ru/docs/Web/HTML/Global_attributes/lang)
1314
- > > - Атрибут [`dir`](https://developer.mozil
1315
- > > - [`useLocale` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useLocale.md) (API аналогично для `preact-intlayer`)
1316
- > > - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocaleName.md)
1317
- > > - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocalizedUrl.md)
1318
- > > - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getHTMLTextDir.md)
1319
- > > - Атрибут [`hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=ru)
1320
- > > - Атрибут [`lang`](https://developer.mozilla.org/ru/docs/Web/HTML/Global_attributes/lang)
1321
- > > - Атрибут [`dir`](https://developer.mozilla.org/ru/docs/Web/HTML/Global_attributes/dir)
1322
- > > - Атрибут [`aria-current`](https://developer.mozilla.org/ru/docs/Web/Accessibility/ARIA/Attributes/aria-current)
1323
- > > - [API Popover](https://developer.mozilla.org/ru/docs/Web/API/Popover_API) la.org/en-US/docs/Web/HTML/Global_attributes/dir)> - [`aria-current` атрибут](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
1324
-
1325
- Ниже приведён обновлённый **Шаг 9** с дополнительными пояснениями и уточнёнными примерами кода:
986
+ > > - [Хук `useLocale`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/react-intlayer/useLocale.md) (API для `preact-intlayer` аналогично)> - [Хук `getLocaleName`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocaleName.md)> - [Хук `getLocalizedUrl`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getLocalizedUrl.md)> - [Хук `getHTMLTextDir`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/packages/intlayer/getHTMLTextDir.md)> - [Атрибут `hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=ru)> - [Атрибут `lang`](https://developer.mozilla.org/ru/docs/Web/HTML/Global_attributes/lang)> - [Атрибут `dir`](https://developer.mozilla.org/ru/docs/Web/HTML/Global_attributes/dir)> - [Атрибут `aria-current`](https://developer.mozilla.org/ru/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [Popover API](https://developer.mozilla.org/ru/docs/Web/API/Popover_API)
1326
987
 
1327
- ---
1328
-
1329
- ### (Необязательно) Шаг 9: Переключение атрибутов языка и направления в HTML
988
+ ### (Необязательно) Шаг 9: Переключайте атрибуты языка и направления HTML
1330
989
 
1331
990
  Когда ваше приложение поддерживает несколько языков, крайне важно обновлять атрибуты `lang` и `dir` тега `<html>`, чтобы они соответствовали текущей локали. Это обеспечивает:
1332
991
 
1333
- - **Доступность**: Экранные читалки и вспомогательные технологии полагаются на правильный атрибут `lang` для корректного произношения и интерпретации контента.
1334
- - **Отображение текста**: Атрибут `dir` (направление) гарантирует, что текст отображается в правильном порядке (например, слева направо для английского, справа налево для арабского или иврита), что важно для удобочитаемости.
1335
- - **SEO**: Поисковые системы используют атрибут `lang` для определения языка вашей страницы, что помогает показывать правильный локализованный контент в результатах поиска.
992
+ - **Доступность**: Экранные дикторы и вспомогательные технологии полагаются на правильный атрибут `lang` для точного произношения и интерпретации контента.
993
+ - **Отображение текста**: Атрибут `dir` (direction) гарантирует, что текст отображается в правильном порядке (например, слева направо для английского, справа налево для арабского или иврита), что важно для удобочитаемости.
994
+ - **SEO**: Поисковые системы используют атрибут `lang` для определения языка вашей страницы, помогая показывать правильный локализованный контент в результатах поиска.
1336
995
 
1337
- Обновляя эти атрибуты динамически при смене локали, вы обеспечиваете последовательный и доступный опыт для пользователей на всех поддерживаемых языках.
996
+ Обновляя эти атрибуты динамически при изменении локали, вы гарантируете согласованный и доступный опыт для пользователей на всех поддерживаемых языках.
1338
997
 
1339
998
  #### Реализация хука
1340
999
 
1341
- Создайте пользовательский хук для управления атрибутами HTML. Хук отслеживает изменения локали и обновляет атрибуты соответствующим образом:
1000
+ Создайте пользовательский хук для управления атрибутами HTML. Хук прослушивает изменения локали и соответствующим образом обновляет атрибуты:
1342
1001
 
1343
1002
  ```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat="typescript"
1344
1003
  import { useEffect } from "preact/hooks";
@@ -1346,11 +1005,11 @@ import { useLocale } from "preact-intlayer";
1346
1005
  import { getHTMLTextDir } from "intlayer";
1347
1006
 
1348
1007
  /**
1349
- * Обновляет атрибуты `lang` и `dir` элемента <html> в зависимости от текущей локали.
1008
+ * Обновляет атрибуты `lang` и `dir` HTML-элемента <html> на основе текущей локали.
1350
1009
  * - `lang`: Информирует браузеры и поисковые системы о языке страницы.
1351
1010
  * - `dir`: Обеспечивает правильный порядок чтения (например, 'ltr' для английского, 'rtl' для арабского).
1352
1011
  *
1353
- * Динамическое обновление необходимо для правильного отображения текста, доступности и SEO.
1012
+ * Это динамическое обновление необходимо для правильного отображения текста, доступности и SEO.
1354
1013
  */
1355
1014
  export const useI18nHTMLAttributes = () => {
1356
1015
  const { locale } = useLocale();
@@ -1359,7 +1018,7 @@ export const useI18nHTMLAttributes = () => {
1359
1018
  // Обновляет атрибут языка на текущую локаль.
1360
1019
  document.documentElement.lang = locale;
1361
1020
 
1362
- // Устанавливает направление текста в зависимости от текущей локали.
1021
+ // Устанавливает направление текста на основе текущей локали.
1363
1022
  document.documentElement.dir = getHTMLTextDir(locale);
1364
1023
  }, [locale]);
1365
1024
  };
@@ -1371,7 +1030,7 @@ import { useLocale } from "preact-intlayer";
1371
1030
  import { getHTMLTextDir } from "intlayer";
1372
1031
 
1373
1032
  /**
1374
- * Обновляет атрибуты `lang` и `dir` элемента HTML <html> в зависимости от текущей локали.
1033
+ * Обновляет атрибуты `lang` и `dir` HTML-элемента <html> на основе текущей локали.
1375
1034
  */
1376
1035
  export const useI18nHTMLAttributes = () => {
1377
1036
  const { locale } = useLocale();
@@ -1389,7 +1048,7 @@ const { useLocale } = require("preact-intlayer");
1389
1048
  const { getHTMLTextDir } = require("intlayer");
1390
1049
 
1391
1050
  /**
1392
- * Обновляет атрибуты `lang` и `dir` элемента HTML <html> в зависимости от текущей локали.
1051
+ * Обновляет атрибуты `lang` и `dir` HTML-элемента <html> на основе текущей локали.
1393
1052
  */
1394
1053
  const useI18nHTMLAttributes = () => {
1395
1054
  const { locale } = useLocale();
@@ -1405,7 +1064,7 @@ module.exports = { useI18nHTMLAttributes };
1405
1064
 
1406
1065
  #### Использование хука в вашем приложении
1407
1066
 
1408
- Интегрируйте хук в ваш главный компонент, чтобы атрибуты HTML обновлялись при каждом изменении локали:
1067
+ Интегрируйте хук в свой основной компонент, чтобы атрибуты HTML обновлялись при каждом изменении локали:
1409
1068
 
1410
1069
  ```tsx fileName="src/app.tsx" codeFormat="typescript"
1411
1070
  import type { FunctionalComponent } from "preact";
@@ -1418,7 +1077,7 @@ const AppWithHooks: FunctionalComponent = () => {
1418
1077
  // Применяем хук для обновления атрибутов lang и dir тега <html> в зависимости от локали.
1419
1078
  useI18nHTMLAttributes();
1420
1079
 
1421
- // Предполагается, что AppContent - это ваш основной компонент отображения контента из Шага 5
1080
+ // Предполагается, что AppContent это ваш основной компонент отображения контента из Шага 5
1422
1081
  return <AppContent />;
1423
1082
  };
1424
1083
 
@@ -1471,34 +1130,26 @@ const App = () => (
1471
1130
  module.exports = App;
1472
1131
  ```
1473
1132
 
1474
- Применяя эти изменения, ваше приложение будет:
1475
-
1476
- - Обеспечивать корректное отражение текущей локали в атрибуте **языка** (`lang`), что важно для SEO и поведения браузера.
1477
- - Настраивать **направление текста** (`dir`) в соответствии с локалью, улучшая читаемость и удобство использования для языков с разным порядком чтения.
1478
- - Обеспечить более **доступный** опыт, так как вспомогательные технологии зависят от этих атрибутов для оптимальной работы.
1133
+ ### (Необязательно) Шаг 10: Создание компонента локализованной ссылки
1479
1134
 
1480
- ### (Необязательно) Шаг 10: Создание локализованного компонента Link
1481
-
1482
- Чтобы гарантировать, что навигация вашего приложения учитывает текущую локаль, вы можете создать пользовательский компонент `Link`. Этот компонент автоматически добавляет префикс текущего языка к внутренним URL.
1135
+ Чтобы навигация в вашем приложении учитывала текущую локаль, вы можете создать пользовательский компонент `Link`. Этот компонент автоматически добавляет префикс текущего языка к внутренним URL.
1483
1136
 
1484
1137
  Это поведение полезно по нескольким причинам:
1485
1138
 
1486
- - **SEO и пользовательский опыт**: Локализованные URL помогают поисковым системам правильно индексировать страницы на разных языках и предоставлять пользователям контент на предпочитаемом языке.
1487
- - **Последовательность**: Используя локализованную ссылку во всем приложении, вы гарантируете, что навигация останется в пределах текущей локали, предотвращая неожиданные переключения языка.
1139
+ - **SEO и пользовательский опыт**: Локализованные URL помогают поисковым системам правильно индексировать страницы на разных языках и предоставляют пользователям контент на их предпочтительном языке.
1140
+ - **Последовательность**: Используя локализованную ссылку во всем приложении, вы гарантируете, что навигация остается в пределах текущей локали, предотвращая неожиданные переключения языка.
1488
1141
  - **Поддерживаемость**: Централизация логики локализации в одном компоненте упрощает управление URL.
1489
1142
 
1490
- Для Preact с `preact-iso` обычно используются стандартные теги `<a>` для навигации, а маршрутизацию обрабатывает `preact-iso`. Если вам нужна программная навигация по клику (например, чтобы выполнить действия перед переходом), вы можете использовать функцию `route` из `useLocation`. Вот как можно создать пользовательский компонент ссылки, который локализует URL:
1143
+ Ниже приведена реализация компонента локализованной ссылки `Link` в Preact:
1491
1144
 
1492
- ```tsx fileName="src/components/LocalizedLink.tsx" codeFormat="typescript"
1145
+ ```tsx fileName="src/components/Link.tsx" codeFormat="typescript"
1493
1146
  import { getLocalizedUrl } from "intlayer";
1494
- import { useLocale, useLocation, route } from "preact-intlayer"; // Предполагается, что useLocation и route могут быть из preact-iso через preact-intlayer, если они реэкспортированы, или импортировать напрямую
1495
- // Если не реэкспортируется, импортируйте напрямую: import { useLocation, route } from "preact-iso";
1496
- import type { JSX } from "preact"; // Для HTMLAttributes
1497
- import { forwardRef } from "preact/compat"; // Для передачи ref
1147
+ import { useLocale } from "preact-intlayer";
1148
+ import { forwardRef } from "preact/compat";
1149
+ import type { JSX } from "preact";
1498
1150
 
1499
- export interface LocalizedLinkProps extends JSX.HTMLAttributes<HTMLAnchorElement> {
1151
+ export interface LinkProps extends JSX.HTMLAttributes<HTMLAnchorElement> {
1500
1152
  href: string;
1501
- replace?: boolean; // Необязательно: для замены состояния истории
1502
1153
  }
1503
1154
 
1504
1155
  /**
@@ -1509,173 +1160,158 @@ export const checkIsExternalLink = (href?: string): boolean =>
1509
1160
  /^https?:\/\//.test(href ?? "");
1510
1161
 
1511
1162
  /**
1512
- * Кастомный компонент Link, который адаптирует атрибут href в зависимости от текущей локали.
1513
- * Для внутренних ссылок используется `getLocalizedUrl` для добавления префикса локали к URL (например, /fr/about).
1514
- * Это гарантирует, что навигация останется в контексте той же локали.
1515
- * Используется стандартный тег <a>, но может инициировать навигацию на стороне клиента с помощью `route` из preact-iso.
1163
+ * Пользовательский компонент Link, который адаптирует атрибут href в зависимости от текущей локали.
1164
+ * Для внутренних ссылок он использует `getLocalizedUrl`, чтобы добавить префикс локали к URL (например, /fr/about).
1165
+ * Это гарантирует, что навигация остается в контексте той же локали.
1516
1166
  */
1517
- export const LocalizedLink = forwardRef<HTMLAnchorElement, LocalizedLinkProps>(
1518
- ({ href, children, onClick, replace = false, ...props }, ref) => {
1167
+ export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
1168
+ ({ href, children, ...props }, ref) => {
1519
1169
  const { locale } = useLocale();
1520
- const location = useLocation(); // из preact-iso
1521
1170
  const isExternalLink = checkIsExternalLink(href);
1522
1171
 
1172
+ // Если ссылка внутренняя и предоставлен валидный href, получаем локализованный URL.
1523
1173
  const hrefI18n =
1524
1174
  href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1525
1175
 
1526
- const handleClick = (event: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {
1527
- if (onClick) {
1528
- onClick(event);
1529
- }
1530
- if (
1531
- !isExternalLink &&
1532
- href && // Убедиться, что href определён
1533
- event.button === 0 && // Левая кнопка мыши
1534
- !event.metaKey &&
1535
- !event.ctrlKey &&
1536
- !event.shiftKey &&
1537
- !event.altKey && // Проверка стандартных модификаторов
1538
- !props.target // Не открывать в новой вкладке/окне
1539
- ) {
1540
- event.preventDefault();
1541
- if (location.url !== hrefI18n) {
1542
- // Переходить только если URL отличается
1543
- route(hrefI18n, replace); // Использовать route из preact-iso
1544
- }
1545
- }
1546
- };
1547
-
1548
1176
  return (
1549
- <a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
1177
+ <a href={hrefI18n} ref={ref} {...props}>
1550
1178
  {children}
1551
1179
  </a>
1552
1180
  );
1553
1181
  }
1554
1182
  );
1183
+
1184
+ Link.displayName = "Link";
1555
1185
  ```
1556
1186
 
1557
- ```jsx fileName="src/components/LocalizedLink.jsx" codeFormat="esm"
1187
+ ```jsx fileName="src/components/Link.jsx" codeFormat="esm"
1558
1188
  import { getLocalizedUrl } from "intlayer";
1559
1189
  import { useLocale } from "preact-intlayer";
1560
- import { useLocation, route } from "preact-iso"; // Импорт из preact-iso
1561
1190
  import { forwardRef } from "preact/compat";
1562
- import { h } from "preact"; // Для JSX
1563
1191
 
1192
+ /**
1193
+ * Вспомогательная функция для проверки, является ли данный URL внешним.
1194
+ * Если URL начинается с http:// или https://, он считается внешним.
1195
+ */
1564
1196
  export const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
1565
1197
 
1566
- export const LocalizedLink = forwardRef(
1567
- ({ href, children, onClick, replace = false, ...props }, ref) => {
1568
- const { locale } = useLocale();
1569
- const location = useLocation();
1570
- const isExternalLink = checkIsExternalLink(href);
1198
+ /**
1199
+ * Пользовательский компонент Link, который адаптирует атрибут href в зависимости от текущей локали.
1200
+ * Для внутренних ссылок он использует `getLocalizedUrl`, чтобы добавить префикс локали к URL (например, /fr/about).
1201
+ * Это гарантирует, что навигация остается в контексте той же локали.
1202
+ */
1203
+ export const Link = forwardRef(({ href, children, ...props }, ref) => {
1204
+ const { locale } = useLocale();
1205
+ const isExternalLink = checkIsExternalLink(href);
1571
1206
 
1572
- const hrefI18n =
1573
- href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1207
+ // Если ссылка внутренняя и предоставлен валидный href, получаем локализованный URL.
1208
+ const hrefI18n =
1209
+ href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1574
1210
 
1575
- const handleClick = (event) => {
1576
- if (onClick) {
1577
- onClick(event);
1578
- }
1579
- if (
1580
- !isExternalLink &&
1581
- href &&
1582
- event.button === 0 &&
1583
- !event.metaKey &&
1584
- !event.ctrlKey &&
1585
- !event.shiftKey &&
1586
- !event.altKey &&
1587
- !props.target
1588
- ) {
1589
- event.preventDefault();
1590
- if (location.url !== hrefI18n) {
1591
- route(hrefI18n, replace);
1592
- }
1593
- }
1594
- };
1211
+ return (
1212
+ <a href={hrefI18n} ref={ref} {...props}>
1213
+ {children}
1214
+ </a>
1215
+ );
1216
+ });
1595
1217
 
1596
- return (
1597
- <a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
1598
- {children}
1599
- </a>
1600
- );
1601
- }
1602
- );
1218
+ Link.displayName = "Link";
1603
1219
  ```
1604
1220
 
1605
- ```jsx fileName="src/components/LocalizedLink.cjsx" codeFormat="commonjs"
1221
+ ```jsx fileName="src/components/Link.cjsx" codeFormat="commonjs"
1606
1222
  const { getLocalizedUrl } = require("intlayer");
1607
1223
  const { useLocale } = require("preact-intlayer");
1608
- const { useLocation, route } = require("preact-iso"); // Импорт из preact-iso
1609
1224
  const { forwardRef } = require("preact/compat");
1610
- const { h } = require("preact"); // Для JSX
1611
1225
 
1226
+ /**
1227
+ * Вспомогательная функция для проверки, является ли данный URL внешним.
1228
+ * Если URL начинается с http:// или https://, он считается внешним.
1229
+ */
1612
1230
  const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
1613
1231
 
1614
- // Проверяет, является ли ссылка внешней
1615
- const LocalizedLink = forwardRef(
1616
- ({ href, children, onClick, replace = false, ...props }, ref) => {
1617
- const { locale } = useLocale(); // Получение текущей локали
1618
- const location = useLocation(); // Получение текущего местоположения
1619
- const isExternalLink = checkIsExternalLink(href); // Проверка, внешняя ли ссылка
1620
-
1621
- // Локализованный URL, если ссылка внутренняя
1622
- const hrefI18n =
1623
- href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1624
-
1625
- const handleClick = (event) => {
1626
- if (onClick) {
1627
- onClick(event);
1628
- }
1629
- if (
1630
- !isExternalLink &&
1631
- href &&
1632
- event.button === 0 &&
1633
- !event.metaKey &&
1634
- !event.ctrlKey &&
1635
- !event.shiftKey &&
1636
- !event.altKey &&
1637
- !props.target
1638
- ) {
1639
- event.preventDefault();
1640
- if (location.url !== hrefI18n) {
1641
- route(hrefI18n, replace);
1642
- }
1643
- }
1644
- };
1232
+ /**
1233
+ * Пользовательский компонент Link, который адаптирует атрибут href в зависимости от текущей локали.
1234
+ * Для внутренних ссылок он использует `getLocalizedUrl`, чтобы добавить префикс локали к URL (например, /fr/about).
1235
+ * Это гарантирует, что навигация остается в контексте той же локали.
1236
+ */
1237
+ const Link = forwardRef(({ href, children, ...props }, ref) => {
1238
+ const { locale } = useLocale();
1239
+ const isExternalLink = checkIsExternalLink(href);
1240
+
1241
+ // Если ссылка внутренняя и предоставлен валидный href, получаем локализованный URL.
1242
+ const hrefI18n =
1243
+ href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1244
+
1245
+ return h(
1246
+ "a",
1247
+ {
1248
+ href: hrefI18n,
1249
+ ref: ref,
1250
+ ...props,
1251
+ },
1252
+ children
1253
+ );
1254
+ });
1645
1255
 
1646
- return (
1647
- <a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
1648
- {children}
1649
- </a>
1650
- );
1651
- }
1652
- );
1256
+ Link.displayName = "Link";
1653
1257
 
1654
- module.exports = { LocalizedLink, checkIsExternalLink };
1258
+ module.exports = { Link, checkIsExternalLink };
1655
1259
  ```
1656
1260
 
1657
1261
  #### Как это работает
1658
1262
 
1659
1263
  - **Определение внешних ссылок**:
1660
- Вспомогательная функция `checkIsExternalLink` определяет, является ли URL внешним. Внешние ссылки остаются без изменений.
1264
+ Вспомогательная функция `checkIsExternalLink` определяет, является ли URL внешним. Внешние ссылки остаются без изменений, так как они не нуждаются в локализации.
1661
1265
  - **Получение текущей локали**:
1662
- Хук `useLocale` предоставляет текущую локаль.
1266
+ Хук `useLocale` предоставляет текущую локаль (например, `fr` для французского).
1663
1267
  - **Локализация URL**:
1664
- Для внутренних ссылок функция `getLocalizedUrl` добавляет префикс текущей локали к URL.
1665
- - **Навигация на стороне клиента**:
1666
- Функция `handleClick` проверяет, является ли ссылка внутренней и нужно ли предотвратить стандартную навигацию. Если да, она использует функцию `route` из `preact-iso` (полученную через `useLocation` или импортированную напрямую) для выполнения навигации на стороне клиента. Это обеспечивает поведение, похожее на SPA, без полной перезагрузки страницы.
1268
+ Для внутренних ссылок (т. е. не внешних) используется `getLocalizedUrl` для автоматического добавления префикса текущей локали к URL. Это означает, что если ваш пользователь использует французский язык, передача `/about` в качестве `href` преобразует его в `/fr/about`.
1667
1269
  - **Возврат ссылки**:
1668
- Компонент возвращает элемент `<a>` с локализованным URL и пользовательским обработчиком клика.
1270
+ Компонент возвращает элемент `<a>` с локализованным URL, гарантируя, что навигация соответствует локали.
1271
+
1272
+ ### (Необязательно) Шаг 11: Рендеринг Markdown и HTML
1273
+
1274
+ Intlayer поддерживает рендеринг контента в форматах Markdown и HTML в Preact.
1275
+
1276
+ Вы можете настроить рендеринг контента Markdown и HTML с помощью метода `.use()`. Этот метод позволяет переопределить стандартный рендеринг определенных тегов.
1277
+
1278
+ ```tsx
1279
+ import { useIntlayer } from "preact-intlayer";
1280
+
1281
+ const { myMarkdownContent, myHtmlContent } = useIntlayer("my-component");
1282
+
1283
+ // ...
1284
+
1285
+ return (
1286
+ <div>
1287
+ {/* Базовый рендеринг */}
1288
+ {myMarkdownContent}
1289
+
1290
+ {/* Пользовательский рендеринг для Markdown */}
1291
+ {myMarkdownContent.use({
1292
+ h1: (props) => <h1 style={{ color: "red" }} {...props} />,
1293
+ })}
1294
+
1295
+ {/* Базовый рендеринг для HTML */}
1296
+ {myHtmlContent}
1297
+
1298
+ {/* Пользовательский рендеринг для HTML */}
1299
+ {myHtmlContent.use({
1300
+ b: (props) => <strong style={{ color: "blue" }} {...props} />,
1301
+ })}
1302
+ </div>
1303
+ );
1304
+ ```
1669
1305
 
1670
1306
  ### Настройка TypeScript
1671
1307
 
1672
- Intlayer использует расширение модулей (module augmentation), чтобы получить преимущества TypeScript и сделать вашу кодовую базу более надежной.
1308
+ Intlayer использует расширение модулей (module augmentation) для получения преимуществ TypeScript и усиления вашей кодовой базы.
1673
1309
 
1674
1310
  ![Autocompletion](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)
1675
1311
 
1676
1312
  ![Translation error](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)
1677
1313
 
1678
- Убедитесь, что ваша конфигурация TypeScript включает автоматически сгенерированные типы.
1314
+ Убедитесь, что ваша конфигурация TypeScript включает автоматически генерируемые типы.
1679
1315
 
1680
1316
  ```json5 fileName="tsconfig.json"
1681
1317
  {
@@ -1688,43 +1324,43 @@ Intlayer использует расширение модулей (module augmen
1688
1324
  },
1689
1325
  "include": [
1690
1326
  // ... Ваши существующие конфигурации TypeScript
1691
- ".intlayer/**/*.ts", // Включить автоматически сгенерированные типы
1327
+ ".intlayer/**/*.ts", // Включить автоматически генерируемые типы
1692
1328
  ],
1693
1329
  }
1694
1330
  ```
1695
1331
 
1696
- > Убедитесь, что ваш `tsconfig.json` настроен для Preact, особенно параметры `jsx` и `jsxImportSource` или `jsxFactory`/`jsxFragmentFactory` для старых версий Preact, если вы не используете настройки по умолчанию `preset-vite`.
1332
+ > Убедитесь, что ваш `tsconfig.json` настроен для Preact, особенно `jsx` и `jsxImportSource` или `jsxFactory`/`jsxFragmentFactory` для старых версий Preact, если вы не используете настройки по умолчанию `preset-vite`.
1697
1333
 
1698
1334
  ### Конфигурация Git
1699
1335
 
1700
- Рекомендуется игнорировать файлы, сгенерированные Intlayer. Это позволит избежать их коммита в ваш Git-репозиторий.
1336
+ Рекомендуется игнорировать файлы, генерируемые Intlayer. Это позволит избежать их фиксации в вашем Git-репозитории.
1701
1337
 
1702
- Чтобы сделать это, вы можете добавить следующие инструкции в ваш файл `.gitignore`:
1338
+ Для этого вы можете добавить следующие инструкции в ваш файл `.gitignore`:
1703
1339
 
1704
1340
  ```plaintext
1705
- # Игнорировать файлы, сгенерированные Intlayer
1341
+ # Игнорировать файлы, генерируемые Intlayer
1706
1342
  .intlayer
1707
1343
  ```
1708
1344
 
1709
1345
  ### Расширение VS Code
1710
1346
 
1711
- Для улучшения вашего опыта разработки с Intlayer вы можете установить официальное **расширение Intlayer для VS Code**.
1347
+ Для улучшения опыта разработки с Intlayer вы можете установить официальное **расширение Intlayer для VS Code**.
1712
1348
 
1713
- [Установить из магазина расширений VS Code](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
1349
+ [Установить из VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
1714
1350
 
1715
1351
  Это расширение предоставляет:
1716
1352
 
1717
- - **Автозаполнение** ключей переводов.
1353
+ - **Автодополнение** ключей перевода.
1718
1354
  - **Обнаружение ошибок в реальном времени** для отсутствующих переводов.
1719
- - **Встроенный просмотр** переведенного контента.
1355
+ - **Встроенный предпросмотр** переведенного контента.
1720
1356
  - **Быстрые действия** для удобного создания и обновления переводов.
1721
1357
 
1722
- Для получения дополнительной информации о том, как использовать расширение, обратитесь к [документации по расширению Intlayer для VS Code](https://intlayer.org/doc/vs-code-extension).
1358
+ Для получения более подробной информации о том, как использовать расширение, обратитесь к [документации по расширению Intlayer для VS Code](https://intlayer.org/doc/vs-code-extension).
1723
1359
 
1724
1360
  ---
1725
1361
 
1726
- ### Продвинутые возможности
1362
+ ### Продвигайтесь дальше
1727
1363
 
1728
- Для расширения возможностей вы можете реализовать [визуальный редактор](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).
1364
+ Чтобы продвинуться дальше, вы можете реализовать [визуальный редактор](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).
1729
1365
 
1730
1366
  ---