@intlayer/docs 7.5.12 → 7.5.14

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 (229) hide show
  1. package/blog/ar/per-component_vs_centralized_i18n.md +248 -0
  2. package/blog/de/per-component_vs_centralized_i18n.md +248 -0
  3. package/blog/en/_per-component_vs_centralized_i18n.md +252 -0
  4. package/blog/en/per-component_vs_centralized_i18n.md +248 -0
  5. package/blog/en-GB/per-component_vs_centralized_i18n.md +247 -0
  6. package/blog/es/per-component_vs_centralized_i18n.md +245 -0
  7. package/blog/fr/per-component_vs_centralized_i18n.md +245 -0
  8. package/blog/hi/per-component_vs_centralized_i18n.md +249 -0
  9. package/blog/id/per-component_vs_centralized_i18n.md +248 -0
  10. package/blog/it/per-component_vs_centralized_i18n.md +247 -0
  11. package/blog/ja/per-component_vs_centralized_i18n.md +247 -0
  12. package/blog/ko/per-component_vs_centralized_i18n.md +246 -0
  13. package/blog/pl/per-component_vs_centralized_i18n.md +247 -0
  14. package/blog/pt/per-component_vs_centralized_i18n.md +246 -0
  15. package/blog/ru/per-component_vs_centralized_i18n.md +251 -0
  16. package/blog/tr/per-component_vs_centralized_i18n.md +244 -0
  17. package/blog/uk/compiler_vs_declarative_i18n.md +224 -0
  18. package/blog/uk/i18n_using_next-i18next.md +1086 -0
  19. package/blog/uk/i18n_using_next-intl.md +760 -0
  20. package/blog/uk/index.md +69 -0
  21. package/blog/uk/internationalization_and_SEO.md +273 -0
  22. package/blog/uk/intlayer_with_i18next.md +211 -0
  23. package/blog/uk/intlayer_with_next-i18next.md +202 -0
  24. package/blog/uk/intlayer_with_next-intl.md +203 -0
  25. package/blog/uk/intlayer_with_react-i18next.md +200 -0
  26. package/blog/uk/intlayer_with_react-intl.md +202 -0
  27. package/blog/uk/intlayer_with_vue-i18n.md +206 -0
  28. package/blog/uk/l10n_platform_alternative/Lokalise.md +80 -0
  29. package/blog/uk/l10n_platform_alternative/crowdin.md +80 -0
  30. package/blog/uk/l10n_platform_alternative/phrase.md +78 -0
  31. package/blog/uk/list_i18n_technologies/CMS/drupal.md +143 -0
  32. package/blog/uk/list_i18n_technologies/CMS/wix.md +167 -0
  33. package/blog/uk/list_i18n_technologies/CMS/wordpress.md +189 -0
  34. package/blog/uk/list_i18n_technologies/frameworks/angular.md +125 -0
  35. package/blog/uk/list_i18n_technologies/frameworks/flutter.md +128 -0
  36. package/blog/uk/list_i18n_technologies/frameworks/react-native.md +217 -0
  37. package/blog/uk/list_i18n_technologies/frameworks/react.md +155 -0
  38. package/blog/uk/list_i18n_technologies/frameworks/svelte.md +145 -0
  39. package/blog/uk/list_i18n_technologies/frameworks/vue.md +144 -0
  40. package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +1499 -0
  41. package/blog/uk/nextjs-multilingual-seo-comparison.md +360 -0
  42. package/blog/uk/per-component_vs_centralized_i18n.md +248 -0
  43. package/blog/uk/rag_powered_documentation_assistant.md +288 -0
  44. package/blog/uk/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
  45. package/blog/uk/vue-i18n_vs_intlayer.md +279 -0
  46. package/blog/uk/what_is_internationalization.md +167 -0
  47. package/blog/vi/per-component_vs_centralized_i18n.md +246 -0
  48. package/blog/zh/per-component_vs_centralized_i18n.md +248 -0
  49. package/dist/cjs/common.cjs.map +1 -1
  50. package/dist/cjs/generated/blog.entry.cjs +20 -0
  51. package/dist/cjs/generated/blog.entry.cjs.map +1 -1
  52. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  53. package/dist/cjs/generated/frequentQuestions.entry.cjs +20 -0
  54. package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
  55. package/dist/cjs/generated/legal.entry.cjs.map +1 -1
  56. package/dist/esm/common.mjs.map +1 -1
  57. package/dist/esm/generated/blog.entry.mjs +20 -0
  58. package/dist/esm/generated/blog.entry.mjs.map +1 -1
  59. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  60. package/dist/esm/generated/frequentQuestions.entry.mjs +20 -0
  61. package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
  62. package/dist/esm/generated/legal.entry.mjs.map +1 -1
  63. package/dist/types/generated/blog.entry.d.ts +1 -0
  64. package/dist/types/generated/blog.entry.d.ts.map +1 -1
  65. package/dist/types/generated/frequentQuestions.entry.d.ts +1 -0
  66. package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
  67. package/docs/ar/configuration.md +6 -1
  68. package/docs/ar/dictionary/content_file.md +6 -1
  69. package/docs/de/configuration.md +6 -1
  70. package/docs/de/dictionary/content_file.md +6 -1
  71. package/docs/en/configuration.md +6 -1
  72. package/docs/en/dictionary/content_file.md +6 -1
  73. package/docs/en-GB/configuration.md +6 -1
  74. package/docs/en-GB/dictionary/content_file.md +3 -1
  75. package/docs/es/configuration.md +6 -1
  76. package/docs/es/dictionary/content_file.md +6 -1
  77. package/docs/fr/configuration.md +6 -1
  78. package/docs/fr/dictionary/content_file.md +3 -1
  79. package/docs/hi/configuration.md +6 -1
  80. package/docs/hi/dictionary/content_file.md +3 -1
  81. package/docs/id/configuration.md +6 -1
  82. package/docs/id/dictionary/content_file.md +3 -1
  83. package/docs/it/configuration.md +6 -1
  84. package/docs/it/dictionary/content_file.md +3 -1
  85. package/docs/ja/configuration.md +6 -1
  86. package/docs/ja/dictionary/content_file.md +3 -1
  87. package/docs/ko/configuration.md +6 -1
  88. package/docs/ko/dictionary/content_file.md +3 -1
  89. package/docs/pl/configuration.md +3 -1
  90. package/docs/pl/dictionary/content_file.md +3 -1
  91. package/docs/pt/configuration.md +6 -1
  92. package/docs/pt/dictionary/content_file.md +3 -1
  93. package/docs/ru/configuration.md +6 -1
  94. package/docs/ru/dictionary/content_file.md +6 -1
  95. package/docs/tr/configuration.md +6 -1
  96. package/docs/tr/dictionary/content_file.md +3 -1
  97. package/docs/uk/CI_CD.md +198 -0
  98. package/docs/uk/autoFill.md +307 -0
  99. package/docs/uk/bundle_optimization.md +185 -0
  100. package/docs/uk/cli/build.md +64 -0
  101. package/docs/uk/cli/ci.md +137 -0
  102. package/docs/uk/cli/configuration.md +63 -0
  103. package/docs/uk/cli/debug.md +46 -0
  104. package/docs/uk/cli/doc-review.md +43 -0
  105. package/docs/uk/cli/doc-translate.md +132 -0
  106. package/docs/uk/cli/editor.md +28 -0
  107. package/docs/uk/cli/fill.md +130 -0
  108. package/docs/uk/cli/index.md +190 -0
  109. package/docs/uk/cli/init.md +84 -0
  110. package/docs/uk/cli/list.md +90 -0
  111. package/docs/uk/cli/list_projects.md +128 -0
  112. package/docs/uk/cli/live.md +41 -0
  113. package/docs/uk/cli/login.md +157 -0
  114. package/docs/uk/cli/pull.md +78 -0
  115. package/docs/uk/cli/push.md +98 -0
  116. package/docs/uk/cli/sdk.md +71 -0
  117. package/docs/uk/cli/test.md +76 -0
  118. package/docs/uk/cli/transform.md +65 -0
  119. package/docs/uk/cli/version.md +24 -0
  120. package/docs/uk/cli/watch.md +37 -0
  121. package/docs/uk/configuration.md +742 -0
  122. package/docs/uk/dictionary/condition.md +237 -0
  123. package/docs/uk/dictionary/content_file.md +1134 -0
  124. package/docs/uk/dictionary/enumeration.md +245 -0
  125. package/docs/uk/dictionary/file.md +232 -0
  126. package/docs/uk/dictionary/function_fetching.md +212 -0
  127. package/docs/uk/dictionary/gender.md +273 -0
  128. package/docs/uk/dictionary/insertion.md +187 -0
  129. package/docs/uk/dictionary/markdown.md +383 -0
  130. package/docs/uk/dictionary/nesting.md +273 -0
  131. package/docs/uk/dictionary/translation.md +332 -0
  132. package/docs/uk/formatters.md +595 -0
  133. package/docs/uk/how_works_intlayer.md +256 -0
  134. package/docs/uk/index.md +175 -0
  135. package/docs/uk/interest_of_intlayer.md +297 -0
  136. package/docs/uk/intlayer_CMS.md +569 -0
  137. package/docs/uk/intlayer_visual_editor.md +292 -0
  138. package/docs/uk/intlayer_with_angular.md +710 -0
  139. package/docs/uk/intlayer_with_astro.md +256 -0
  140. package/docs/uk/intlayer_with_create_react_app.md +1258 -0
  141. package/docs/uk/intlayer_with_express.md +429 -0
  142. package/docs/uk/intlayer_with_fastify.md +446 -0
  143. package/docs/uk/intlayer_with_lynx+react.md +548 -0
  144. package/docs/uk/intlayer_with_nestjs.md +283 -0
  145. package/docs/uk/intlayer_with_next-i18next.md +640 -0
  146. package/docs/uk/intlayer_with_next-intl.md +456 -0
  147. package/docs/uk/intlayer_with_nextjs_page_router.md +1541 -0
  148. package/docs/uk/intlayer_with_nuxt.md +711 -0
  149. package/docs/uk/intlayer_with_react_router_v7.md +600 -0
  150. package/docs/uk/intlayer_with_react_router_v7_fs_routes.md +669 -0
  151. package/docs/uk/intlayer_with_svelte_kit.md +579 -0
  152. package/docs/uk/intlayer_with_tanstack.md +818 -0
  153. package/docs/uk/intlayer_with_vite+preact.md +1748 -0
  154. package/docs/uk/intlayer_with_vite+react.md +1449 -0
  155. package/docs/uk/intlayer_with_vite+solid.md +302 -0
  156. package/docs/uk/intlayer_with_vite+svelte.md +520 -0
  157. package/docs/uk/intlayer_with_vite+vue.md +1113 -0
  158. package/docs/uk/introduction.md +222 -0
  159. package/docs/uk/locale_mapper.md +242 -0
  160. package/docs/uk/mcp_server.md +211 -0
  161. package/docs/uk/packages/express-intlayer/t.md +465 -0
  162. package/docs/uk/packages/intlayer/getEnumeration.md +159 -0
  163. package/docs/uk/packages/intlayer/getHTMLTextDir.md +121 -0
  164. package/docs/uk/packages/intlayer/getLocaleLang.md +81 -0
  165. package/docs/uk/packages/intlayer/getLocaleName.md +135 -0
  166. package/docs/uk/packages/intlayer/getLocalizedUrl.md +338 -0
  167. package/docs/uk/packages/intlayer/getMultilingualUrls.md +359 -0
  168. package/docs/uk/packages/intlayer/getPathWithoutLocale.md +75 -0
  169. package/docs/uk/packages/intlayer/getPrefix.md +213 -0
  170. package/docs/uk/packages/intlayer/getTranslation.md +190 -0
  171. package/docs/uk/packages/intlayer/getTranslationContent.md +189 -0
  172. package/docs/uk/packages/next-intlayer/t.md +365 -0
  173. package/docs/uk/packages/next-intlayer/useDictionary.md +276 -0
  174. package/docs/uk/packages/next-intlayer/useIntlayer.md +263 -0
  175. package/docs/uk/packages/next-intlayer/useLocale.md +166 -0
  176. package/docs/uk/packages/react-intlayer/t.md +311 -0
  177. package/docs/uk/packages/react-intlayer/useDictionary.md +295 -0
  178. package/docs/uk/packages/react-intlayer/useI18n.md +250 -0
  179. package/docs/uk/packages/react-intlayer/useIntlayer.md +251 -0
  180. package/docs/uk/packages/react-intlayer/useLocale.md +210 -0
  181. package/docs/uk/per_locale_file.md +345 -0
  182. package/docs/uk/plugins/sync-json.md +398 -0
  183. package/docs/uk/readme.md +265 -0
  184. package/docs/uk/releases/v6.md +305 -0
  185. package/docs/uk/releases/v7.md +624 -0
  186. package/docs/uk/roadmap.md +346 -0
  187. package/docs/uk/testing.md +204 -0
  188. package/docs/vi/configuration.md +6 -1
  189. package/docs/vi/dictionary/content_file.md +6 -1
  190. package/docs/zh/configuration.md +6 -1
  191. package/docs/zh/dictionary/content_file.md +6 -1
  192. package/frequent_questions/ar/error-vite-env-only.md +77 -0
  193. package/frequent_questions/de/error-vite-env-only.md +77 -0
  194. package/frequent_questions/en/error-vite-env-only.md +77 -0
  195. package/frequent_questions/en-GB/error-vite-env-only.md +77 -0
  196. package/frequent_questions/es/error-vite-env-only.md +76 -0
  197. package/frequent_questions/fr/error-vite-env-only.md +77 -0
  198. package/frequent_questions/hi/error-vite-env-only.md +77 -0
  199. package/frequent_questions/id/error-vite-env-only.md +77 -0
  200. package/frequent_questions/it/error-vite-env-only.md +77 -0
  201. package/frequent_questions/ja/error-vite-env-only.md +77 -0
  202. package/frequent_questions/ko/error-vite-env-only.md +77 -0
  203. package/frequent_questions/pl/error-vite-env-only.md +77 -0
  204. package/frequent_questions/pt/error-vite-env-only.md +77 -0
  205. package/frequent_questions/ru/error-vite-env-only.md +77 -0
  206. package/frequent_questions/tr/error-vite-env-only.md +77 -0
  207. package/frequent_questions/uk/SSR_Next_no_[locale].md +104 -0
  208. package/frequent_questions/uk/array_as_content_declaration.md +72 -0
  209. package/frequent_questions/uk/build_dictionaries.md +58 -0
  210. package/frequent_questions/uk/build_error_CI_CD.md +74 -0
  211. package/frequent_questions/uk/bun_set_up.md +53 -0
  212. package/frequent_questions/uk/customized_locale_list.md +64 -0
  213. package/frequent_questions/uk/domain_routing.md +113 -0
  214. package/frequent_questions/uk/error-vite-env-only.md +77 -0
  215. package/frequent_questions/uk/esbuild_error.md +29 -0
  216. package/frequent_questions/uk/get_locale_cookie.md +142 -0
  217. package/frequent_questions/uk/intlayer_command_undefined.md +155 -0
  218. package/frequent_questions/uk/locale_incorect_in_url.md +73 -0
  219. package/frequent_questions/uk/package_version_error.md +181 -0
  220. package/frequent_questions/uk/static_rendering.md +44 -0
  221. package/frequent_questions/uk/translated_path_url.md +55 -0
  222. package/frequent_questions/uk/unknown_command.md +97 -0
  223. package/frequent_questions/vi/error-vite-env-only.md +77 -0
  224. package/frequent_questions/zh/error-vite-env-only.md +77 -0
  225. package/legal/uk/privacy_notice.md +83 -0
  226. package/legal/uk/terms_of_service.md +55 -0
  227. package/package.json +9 -9
  228. package/src/generated/blog.entry.ts +20 -0
  229. package/src/generated/frequentQuestions.entry.ts +20 -0
@@ -0,0 +1,1258 @@
1
+ ---
2
+ createdAt: 2025-08-23
3
+ updatedAt: 2025-12-30
4
+ title: Як перекласти ваш Create React App — посібник з i18n 2026
5
+ description: Дізнайтеся, як зробити ваш вебсайт на Create React App (CRA) багатомовним. Дотримуйтесь документації, щоб інтернаціоналізувати (i18n) та перекласти його.
6
+ keywords:
7
+ - Інтернаціоналізація
8
+ - Документація
9
+ - Intlayer
10
+ - Create React App
11
+ - CRA
12
+ - JavaScript
13
+ - React
14
+ slugs:
15
+ - doc
16
+ - environment
17
+ - create-react-app
18
+ applicationTemplate: https://github.com/aymericzip/intlayer-react-cra-template
19
+ history:
20
+ - version: 7.5.9
21
+ date: 2025-12-30
22
+ changes: Додано команду init
23
+ - version: 5.5.10
24
+ date: 2025-06-29
25
+ changes: Ініціалізовано історію
26
+ ---
27
+
28
+ # Перекладіть ваш вебсайт Create React App за допомогою Intlayer | Інтернаціоналізація (i18n)
29
+
30
+ <iframe
31
+ src="https://stackblitz.com/github/aymericzip/intlayer-react-cra-template?embed=1&ctl=1&file=intlayer.config.ts"
32
+ className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
33
+ title="Демо CodeSandbox — як інтернаціоналізувати ваш додаток за допомогою Intlayer"
34
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
35
+ loading="lazy"
36
+ />
37
+
38
+ Дивіться [шаблон додатку](https://github.com/aymericzip/intlayer-react-cra-template) на GitHub.
39
+
40
+ ## Що таке Intlayer?
41
+
42
+ **Intlayer** — інноваційна open-source бібліотека для інтернаціоналізації (i18n), розроблена, щоб спростити багатомовну підтримку в сучасних веб-застосунках.
43
+
44
+ За допомогою Intlayer ви можете:
45
+
46
+ - **Легко керуйте перекладами** за допомогою декларативних словників на рівні компонентів.
47
+ - **Динамічно локалізуйте метадані**, маршрути та контент.
48
+ - **Забезпечте підтримку TypeScript** за допомогою автогенерованих типів, що покращують автодоповнення та виявлення помилок.
49
+ - **Отримайте переваги від розширених можливостей**, таких як динамічне визначення та перемикання локалі.
50
+
51
+ ## Покроковий посібник з налаштування Intlayer у React-додатку
52
+
53
+ ### Крок 1: Встановіть залежності
54
+
55
+ Встановіть необхідні пакети за допомогою npm:
56
+
57
+ ```bash packageManager="npm"
58
+ npm install intlayer react-intlayer react-scripts-intlayer
59
+ npx intlayer init
60
+ ```
61
+
62
+ ```bash packageManager="pnpm"
63
+ pnpm add intlayer react-intlayer react-scripts-intlayer
64
+ pnpm intlayer init
65
+ ```
66
+
67
+ ```bash packageManager="yarn"
68
+ yarn add intlayer react-intlayer react-scripts-intlayer
69
+ yarn intlayer init
70
+ ```
71
+
72
+ ```bash packageManager="bun"
73
+ bun add intlayer react-intlayer react-scripts-intlayer
74
+ bunx intlayer init
75
+ ```
76
+
77
+ - **intlayer**
78
+
79
+ The core package that provides internationalization tools for configuration management, translation, [content declaration](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/dictionary/content_file.md), transpilation, and [CLI commands](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/cli/index.md).
80
+
81
+ - **react-intlayer**
82
+
83
+ The package that integrates Intlayer with React application. It provides context providers and hooks for React internationalization.
84
+
85
+ - **react-scripts-intlayer**
86
+
87
+ Містить команди та плагіни `react-scripts-intlayer` для інтеграції Intlayer у застосунок на базі Create React App. Ці плагіни базуються на [craco](https://craco.js.org/) і включають додаткову конфігурацію для бандлера [Webpack](https://webpack.js.org/).
88
+
89
+ ### Крок 2: Налаштування вашого проекту
90
+
91
+ Створіть файл конфігурації для налаштування мов вашого застосунку:
92
+
93
+ ```typescript fileName="intlayer.config.ts" codeFormat="typescript"
94
+ import { Locales, type IntlayerConfig } from "intlayer";
95
+
96
+ const config: IntlayerConfig = {
97
+ internationalization: {
98
+ locales: [
99
+ Locales.ENGLISH,
100
+ Locales.FRENCH,
101
+ Locales.SPANISH,
102
+ // Інші ваші локалі
103
+ ],
104
+ defaultLocale: Locales.ENGLISH,
105
+ },
106
+ };
107
+
108
+ export default config;
109
+ ```
110
+
111
+ ```javascript fileName="intlayer.config.mjs" codeFormat="esm"
112
+ import { Locales } from "intlayer";
113
+
114
+ /** @type {import('intlayer').IntlayerConfig} */
115
+ const config = {
116
+ internationalization: {
117
+ locales: [
118
+ Locales.ENGLISH,
119
+ Locales.FRENCH,
120
+ Locales.SPANISH,
121
+ // Ваші інші локалі
122
+ ],
123
+ defaultLocale: Locales.ENGLISH,
124
+ },
125
+ };
126
+
127
+ export default config;
128
+ ```
129
+
130
+ ```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
131
+ const { Locales } = require("intlayer");
132
+
133
+ /** @type {import('intlayer').IntlayerConfig} */
134
+ const config = {
135
+ internationalization: {
136
+ locales: [
137
+ Locales.ENGLISH,
138
+ Locales.FRENCH,
139
+ Locales.SPANISH,
140
+ // Ваші інші локалі
141
+ ],
142
+ defaultLocale: Locales.ENGLISH,
143
+ },
144
+ };
145
+
146
+ module.exports = config;
147
+ ```
148
+
149
+ > За допомогою цього файлу конфігурації ви можете налаштувати локалізовані URL-адреси, перенаправлення через middleware, імена cookie, розташування та розширення ваших декларацій контенту, вимкнути логи Intlayer у консолі та інше. Для повного переліку доступних параметрів зверніться до [документації з конфігурації](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/configuration.md).
150
+
151
+ ### Крок 3: Інтегруйте Intlayer у конфігурацію CRA
152
+
153
+ Змініть ваші скрипти, щоб використовувати react-intlayer
154
+
155
+ ```json fileName="package.json"
156
+ "scripts": {
157
+ "build": "react-scripts-intlayer build",
158
+ "start": "react-scripts-intlayer start",
159
+ "transpile": "intlayer build"
160
+ },
161
+ ```
162
+
163
+ > `react-scripts-intlayer` scripts are based on [CRACO](https://craco.js.org/). You can also implement your own setup based on the intlayer craco plugin. [See example here](https://github.com/aymericzip/intlayer/blob/main/examples/react-app/craco.config.js).
164
+
165
+ ### Крок 4: Оголосіть свій вміст
166
+
167
+ Create and manage your content declarations to store translations:
168
+
169
+ ```tsx fileName="src/app.content.tsx" codeFormat="typescript"
170
+ import { t, type Dictionary } from "intlayer";
171
+ import React, { type ReactNode } from "react";
172
+
173
+ const appContent = {
174
+ key: "app",
175
+ content: {
176
+ getStarted: t<ReactNode>({
177
+ uk: (
178
+ <>
179
+ Відредагуйте <code>src/App.tsx</code> та збережіть, щоб
180
+ перезавантажити
181
+ </>
182
+ ),
183
+ en: (
184
+ <>
185
+ Edit <code>src/App.tsx</code> and save to reload
186
+ </>
187
+ ),
188
+ fr: (
189
+ <>
190
+ Éditez <code>src/App.tsx</code> et enregistrez pour recharger
191
+ </>
192
+ ),
193
+ uk: (
194
+ <>
195
+ Редагуйте <code>src/App.tsx</code> і збережіть, щоб перезавантажити
196
+ </>
197
+ ),
198
+ es: (
199
+ <>
200
+ Edita <code>src/App.tsx</code> y guarda para recargar
201
+ </>
202
+ ),
203
+ }),
204
+ reactLink: {
205
+ href: "https://reactjs.org",
206
+ content: t({
207
+ uk: "Вивчити React",
208
+ en: "Learn React",
209
+ fr: "Apprendre React",
210
+ es: "Aprender React",
211
+ }),
212
+ },
213
+ },
214
+ } satisfies Dictionary;
215
+
216
+ export default appContent;
217
+ ```
218
+
219
+ ```jsx fileName="src/app.content.mjx" codeFormat="esm"
220
+ import { t } from "intlayer";
221
+
222
+ /** @type {import('intlayer').Dictionary} */
223
+ const appContent = {
224
+ key: "app",
225
+ content: {
226
+ getStarted: t({
227
+ uk: "Почніть з редагування",
228
+ en: "Get started by editing",
229
+ fr: "Commencez par éditer",
230
+ es: "Comience por editar",
231
+ }),
232
+ reactLink: {
233
+ href: "https://reactjs.org",
234
+ content: t({
235
+ uk: "Вивчити React",
236
+ en: "Learn React",
237
+ uk: "Вивчити React",
238
+ fr: "Apprendre React",
239
+ es: "Aprender React",
240
+ }),
241
+ },
242
+ },
243
+ };
244
+
245
+ export default appContent;
246
+ ```
247
+
248
+ ```jsx fileName="src/app.content.csx" codeFormat="commonjs"
249
+ const { t } = require("intlayer");
250
+
251
+ /** @type {import('intlayer').Dictionary} */
252
+ const appContent = {
253
+ key: "app",
254
+ content: {
255
+ getStarted: t({
256
+ uk: "Почніть із редагування",
257
+ en: "Get started by editing",
258
+ fr: "Commencez par éditer",
259
+ es: "Comience por editar",
260
+ }),
261
+ reactLink: {
262
+ href: "https://reactjs.org",
263
+ content: t({
264
+ uk: "Вивчити React",
265
+ en: "Learn React",
266
+ fr: "Apprendre React",
267
+ es: "Aprender React",
268
+ }),
269
+ },
270
+ },
271
+ };
272
+
273
+ module.exports = appContent;
274
+ ```
275
+
276
+ > Ваші декларації контенту можуть бути визначені в будь-якому місці вашого застосунку, якщо вони включені до директорії `contentDir` (за замовчуванням, `./src`). І вони повинні відповідати розширенню файлу декларації контенту (за замовчуванням, `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
277
+
278
+ > Для отримання детальнішої інформації зверніться до [документації щодо декларації контенту](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/dictionary/content_file.md).
279
+
280
+ > Якщо ваш файл контенту містить код TSX, слід розглянути імпорт `import React from "react";` у вашому файлі контенту.
281
+
282
+ ### Крок 5: Використання Intlayer у вашому коді
283
+
284
+ Отримуйте доступ до словників контенту у всьому застосунку:
285
+
286
+ ```tsx {4,7} fileName="src/App.tsx" codeFormat="typescript"
287
+ import logo from "./logo.svg";
288
+ import "./App.css";
289
+ import type { FC } from "react";
290
+ import { IntlayerProvider, useIntlayer } from "react-intlayer";
291
+
292
+ const AppContent: FC = () => {
293
+ const content = useIntlayer("app");
294
+
295
+ return (
296
+ <div className="App">
297
+ <img src={logo} className="App-logo" alt="логотип" />
298
+
299
+ {content.getStarted}
300
+ <a
301
+ className="App-link"
302
+ href={content.reactLink.href.value}
303
+ target="_blank"
304
+ rel="noopener noreferrer"
305
+ >
306
+ {content.reactLink.content}
307
+ </a>
308
+ </div>
309
+ );
310
+ };
311
+
312
+ const App: FC = () => (
313
+ <IntlayerProvider>
314
+ <AppContent />
315
+ </IntlayerProvider>
316
+ );
317
+
318
+ export default App;
319
+ ```
320
+
321
+ ```jsx {3,6} fileName="src/App.mjx" codeFormat="esm"
322
+ import "./App.css";
323
+ import logo from "./logo.svg";
324
+ import { IntlayerProvider, useIntlayer } from "react-intlayer";
325
+
326
+ const AppContent = () => {
327
+ const content = useIntlayer("app");
328
+
329
+ return (
330
+ <div className="App">
331
+ <img src={logo} className="App-logo" alt="логотип" />
332
+
333
+ {content.getStarted}
334
+ <a
335
+ className="App-link"
336
+ href={content.reactLink.href.value}
337
+ target="_blank"
338
+ rel="noopener noreferrer"
339
+ >
340
+ {content.reactLink.content}
341
+ </a>
342
+ </div>
343
+ );
344
+ };
345
+
346
+ const App = () => (
347
+ <IntlayerProvider>
348
+ <AppContent />
349
+ </IntlayerProvider>
350
+ );
351
+ ```
352
+
353
+ ```jsx {3,6} fileName="src/App.csx" codeFormat="commonjs"
354
+ require("./App.css");
355
+ const logo = require("./logo.svg");
356
+ const { IntlayerProvider, useIntlayer } = require("react-intlayer");
357
+
358
+ const AppContent = () => {
359
+ const content = useIntlayer("app");
360
+
361
+ return (
362
+ <div className="App">
363
+ <img src={logo} className="App-logo" alt="logo" />
364
+
365
+ {content.getStarted}
366
+ <a
367
+ className="App-link"
368
+ href={content.reactLink.href.value}
369
+ target="_blank"
370
+ rel="noopener noreferrer"
371
+ >
372
+ {content.reactLink.content}
373
+ </a>
374
+ </div>
375
+ );
376
+ };
377
+
378
+ const App = () => (
379
+ <IntlayerProvider>
380
+ <AppContent />
381
+ </IntlayerProvider>
382
+ );
383
+ ```
384
+
385
+ > Примітка: Якщо ви хочете використовувати ваш контент у `string` атрибуті, наприклад `alt`, `title`, `href`, `aria-label` тощо, ви повинні викликати значення функції, як-от:
386
+
387
+ > ```jsx
388
+ > <img src={content.image.src.value} alt={content.image.value} />
389
+ > ```
390
+
391
+ > Щоб дізнатися більше про хук `useIntlayer`, перегляньте [документацію](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/react-intlayer/useIntlayer.md).
392
+
393
+ ### (Необов'язково) Крок 6: Зміна мови вашого контенту
394
+
395
+ Щоб змінити мову контенту, ви можете використати функцію `setLocale`, що надається хуком `useLocale`. Ця функція дозволяє встановити locale застосунку та відповідно оновити контент.
396
+
397
+ ```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
398
+ import { Locales } from "intlayer";
399
+ import { useLocale } from "react-intlayer";
400
+
401
+ const LocaleSwitcher = () => {
402
+ const { setLocale } = useLocale();
403
+
404
+ return (
405
+ <button onClick={() => setLocale(Locales.English)}>
406
+ Change Language to English
407
+ </button>
408
+ );
409
+ };
410
+ ```
411
+
412
+ ```jsx fileName="src/components/LocaleSwitcher.mjx" codeFormat="esm"
413
+ import { Locales } from "intlayer";
414
+ import { useLocale } from "react-intlayer";
415
+
416
+ const LocaleSwitcher = () => {
417
+ const { setLocale } = useLocale();
418
+
419
+ return (
420
+ <button onClick={() => setLocale(Locales.English)}>
421
+ Змінити мову на англійську
422
+ </button>
423
+ );
424
+ };
425
+ ```
426
+
427
+ ```jsx fileName="src/components/LocaleSwitcher.csx" codeFormat="commonjs"
428
+ const { Locales } = require("intlayer");
429
+ const { useLocale } = require("react-intlayer");
430
+
431
+ const LocaleSwitcher = () => {
432
+ const { setLocale } = useLocale();
433
+
434
+ return (
435
+ <button onClick={() => setLocale(Locales.English)}>
436
+ Змінити мову на англійську
437
+ </button>
438
+ );
439
+ };
440
+ ```
441
+
442
+ > Щоб дізнатися більше про хук `useLocale`, зверніться до [документації](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/react-intlayer/useLocale.md).
443
+
444
+ ### (Необов'язково) Крок 7: Додайте локалізовану маршрутизацію до вашого додатку
445
+
446
+ Мета цього кроку — створити унікальні маршрути для кожної мови. Це корисно для SEO та SEO-дружніх URL-адрес.
447
+ Приклад:
448
+
449
+ ```plaintext
450
+ - https://example.com/about
451
+ - https://example.com/es/about
452
+ - https://example.com/fr/about
453
+ ```
454
+
455
+ > За замовчуванням маршрути не мають префікса для локалі за замовчуванням. Якщо ви хочете додати префікс і для локалі за замовчуванням, встановіть опцію `middleware.prefixDefault` в `true` у вашій конфігурації. Див. [документацію з конфігурації](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/configuration.md) для докладнішої інформації.
456
+
457
+ Щоб додати локалізовану маршрутизацію у ваш застосунок, можна створити компонент `LocaleRouter`, який обгортає маршрути вашого застосунку й обробляє маршрутизацію на основі локалі. Ось приклад з використанням [React Router](https://reactrouter.com/home):
458
+
459
+ ```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
460
+ // Імпорт необхідних залежностей та функцій
461
+ import { type Locales, configuration, getPathWithoutLocale } from "intlayer"; // Утиліти та типи з 'intlayer'
462
+ // Утиліти та типи з 'intlayer'
463
+ import type { FC, PropsWithChildren } from "react"; // Типи React для функціональних компонентів та пропсів
464
+ import { IntlayerProvider } from "react-intlayer"; // Провайдер контексту інтернаціоналізації
465
+ import {
466
+ BrowserRouter,
467
+ Routes,
468
+ Route,
469
+ Navigate,
470
+ useLocation,
471
+ } from "react-router-dom"; // Компоненти роутера для керування навігацією
472
+
473
+ // Деструктуризація конфігурації з Intlayer
474
+ const { internationalization, middleware } = configuration;
475
+ const { locales, defaultLocale } = internationalization;
476
+
477
+ /**
478
+ * Компонент, що обробляє локалізацію та обгортає дочірні елементи у відповідний контекст локалі.
479
+ */
480
+ * Виконує визначення та перевірку локалі на основі URL.
481
+ */
482
+ const AppLocalized: FC<PropsWithChildren<{ locale: Locales }>> = ({
483
+ children,
484
+ locale,
485
+ }) => {
486
+ const { pathname, search } = useLocation(); // Отримати поточний шлях URL
487
+
488
+ // Визначає поточну локаль, за відсутності значення використовується локаль за замовчуванням
489
+ const currentLocale = locale ?? defaultLocale;
490
+
491
+ // Видаляє префікс локалі з шляху для побудови базового шляху
492
+ const pathWithoutLocale = getPathWithoutLocale(
493
+ pathname // Поточний шлях URL
494
+ );
495
+
496
+ /**
497
+ * Якщо middleware.prefixDefault дорівнює true, локаль за замовчуванням завжди повинна мати префікс.
498
+ */
499
+ if (middleware.prefixDefault) {
500
+ // Перевірити локаль
501
+ if (!locale || !locales.includes(locale)) {
502
+ // Перенаправити на локаль за замовчуванням зі оновленим шляхом
503
+ return (
504
+ <Navigate
505
+ to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
506
+ replace // Замінити поточний запис історії на новий
507
+ />
508
+ );
509
+ }
510
+
511
+ // Огорнути дочірні елементи IntlayerProvider та встановити поточну локаль
512
+ return (
513
+ <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
514
+ );
515
+ } else {
516
+ /**
517
+ * Коли middleware.prefixDefault дорівнює false, за замовчуванням локаль не має префікса.
518
+ * Переконайтеся, що поточна локаль є дійсною і не є локаллю за замовчуванням.
519
+ */
520
+ if (
521
+ currentLocale.toString() !== defaultLocale.toString() &&
522
+ !locales
523
+ .filter(
524
+ (locale) => locale.toString() !== defaultLocale.toString() // Виключити локаль за замовчуванням
525
+ )
526
+ .includes(currentLocale) // Перевіряє, чи поточна локаль входить до списку дійсних локалей
527
+ ) {
528
+ // Перенаправляє на шлях без префікса локалі
529
+ return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
530
+ }
531
+
532
+ // Обгортає дочірні елементи IntlayerProvider та встановлює поточну локаль
533
+ return (
534
+ <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
535
+ );
536
+ }
537
+ };
538
+
539
+ /**
540
+ * Компонент маршрутизатора, який налаштовує маршрути, специфічні для локалі.
541
+ * Використовує React Router для керування навігацією та відображення локалізованих компонентів.
542
+ */
543
+ export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
544
+ <BrowserRouter>
545
+ <Routes>
546
+ {locales
547
+ .filter(
548
+ (locale) => middleware.prefixDefault || locale !== defaultLocale
549
+ )
550
+ .map((locale) => (
551
+ <Route
552
+ // Шаблон маршруту для захоплення локалі (наприклад, /en/, /fr/) і відповідності всім наступним шляхам
553
+ path={`/${locale}/*`}
554
+ key={locale}
555
+ element={<AppLocalized locale={locale}>{children}</AppLocalized>} // Обгортає дочірні елементи з управлінням локаллю
556
+ />
557
+ ))}
558
+
559
+ {
560
+ // Якщо префіксування локалі за замовчуванням відключено, відобразити дочірні елементи безпосередньо за кореневим шляхом
561
+ !middleware.prefixDefault && (
562
+ <Route
563
+ path="*"
564
+ element={
565
+ <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
566
+ } // Обгортає дочірні елементи з управлінням локаллю
567
+ />
568
+ )
569
+ }
570
+ </Routes>
571
+ </BrowserRouter>
572
+ );
573
+ ```
574
+
575
+ ```jsx fileName="src/components/LocaleRouter.mjx" codeFormat="esm"
576
+ // Імпорт необхідних залежностей та функцій
577
+ import { configuration, getPathWithoutLocale } from "intlayer"; // Утилітні функції та типи з 'intlayer'
578
+ // Утилітні функції та типи з 'intlayer'
579
+ import { IntlayerProvider } from "react-intlayer"; // Провайдер для контексту інтернаціоналізації
580
+ import {
581
+ BrowserRouter,
582
+ Routes,
583
+ Route,
584
+ Navigate,
585
+ useLocation,
586
+ } from "react-router-dom"; // Компоненти роутера для керування навігацією
587
+
588
+ // Деструктуризація конфігурації з Intlayer
589
+ const { internationalization, middleware } = configuration;
590
+ const { locales, defaultLocale } = internationalization;
591
+
592
+ /**
593
+ * Компонент, який керує локалізацією та обгортає дочірні елементи відповідним контекстом локалі.
594
+ */
595
+ * Він керує виявленням локалі на основі URL і її перевіркою.
596
+ */
597
+ const AppLocalized = ({ children, locale }) => {
598
+ const { pathname, search } = useLocation(); // Отримати поточний шлях URL
599
+
600
+ // Визначити поточну локаль, за відсутності — використовувати локаль за замовчуванням
601
+ const currentLocale = locale ?? defaultLocale;
602
+
603
+ // Видалити префікс локалі з шляху, щоб побудувати базовий шлях
604
+ const pathWithoutLocale = getPathWithoutLocale(
605
+ pathname // Поточний шлях URL
606
+ );
607
+
608
+ /**
609
+ * Якщо middleware.prefixDefault встановлено в true, локаль за замовчуванням завжди має бути з префіксом.
610
+ */
611
+ if (middleware.prefixDefault) {
612
+ // Перевірити локаль
613
+ if (!locale || !locales.includes(locale)) {
614
+ // Перенаправити на локаль за замовчуванням з оновленим шляхом
615
+ return (
616
+ <Navigate
617
+ to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
618
+ replace // Замінити поточний запис у історії на новий
619
+ />
620
+ );
621
+ }
622
+
623
+ // Обгорнути children за допомогою IntlayerProvider і встановити поточну локаль
624
+ return (
625
+ <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
626
+ );
627
+ } else {
628
+ /**
629
+ * Коли middleware.prefixDefault має значення false, префікс для локалі за замовчуванням не додається.
630
+ * Переконайтесь, що поточна локаль дійсна і не є локаллю за замовчуванням.
631
+ */
632
+ if (
633
+ currentLocale.toString() !== defaultLocale.toString() &&
634
+ !locales
635
+ .filter(
636
+ (locale) => locale.toString() !== defaultLocale.toString() // Виключити локаль за замовчуванням
637
+ )
638
+ .includes(currentLocale) // Перевіряє, чи поточна локаль є у списку допустимих локалей
639
+ ) {
640
+ // Перенаправляє на шлях без префікса локалі
641
+ return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
642
+ }
643
+
644
+ // Обгортає дочірні елементи IntlayerProvider і встановлює поточну локаль
645
+ return (
646
+ <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
647
+ );
648
+ }
649
+ };
650
+
651
+ /**
652
+ * Компонент маршрутизатора, який налаштовує маршрути, специфічні для локалі.
653
+ * Використовує React Router для управління навігацією та рендерингу локалізованих компонентів.
654
+ */
655
+ export const LocaleRouter = ({ children }) => (
656
+ <BrowserRouter>
657
+ <Routes>
658
+ {locales
659
+ .filter(
660
+ (locale) => middleware.prefixDefault || locale !== defaultLocale
661
+ )
662
+ .map((locale) => (
663
+ <Route
664
+ // Шаблон маршруту для захоплення локалі (наприклад, /en/, /fr/) і відповідності всім наступним шляхам
665
+ path={`/${locale}/*`}
666
+ key={locale}
667
+ element={<AppLocalized locale={locale}>{children}</AppLocalized>} // Огортає children контекстом локалізації
668
+ />
669
+ ))}
670
+
671
+ {
672
+ // Якщо префіксування локалі за замовчуванням вимкнено, рендерити children безпосередньо за кореневим шляхом
673
+ !middleware.prefixDefault && (
674
+ <Route
675
+ path="*"
676
+ element={
677
+ <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
678
+ } // Огортає children контекстом локалізації
679
+ />
680
+ )
681
+ }
682
+ </Routes>
683
+ </BrowserRouter>
684
+ );
685
+ ```
686
+
687
+ ```jsx fileName="src/components/LocaleRouter.cjx" codeFormat="commonjs"
688
+ // Імпортування необхідних залежностей та функцій
689
+ const { configuration, getPathWithoutLocale } = require("intlayer"); // Утиліти та типи з 'intlayer'
690
+ const { IntlayerProvider, useLocale } = require("react-intlayer"); // Провайдер для контексту інтернаціоналізації
691
+ const {
692
+ BrowserRouter,
693
+ Routes,
694
+ Route,
695
+ Navigate,
696
+ useLocation,
697
+ } = require("react-router-dom"); // Компоненти роутера для керування навігацією
698
+
699
+ // Деструктуризація конфігурації з Intlayer
700
+ const { internationalization, middleware } = configuration;
701
+ const { locales, defaultLocale } = internationalization;
702
+
703
+ /**
704
+ * Компонент, який обробляє локалізацію та обгортає children у відповідний контекст локалі.
705
+ * Він керує визначенням локалі на основі URL та її валідацією.
706
+ */
707
+ const AppLocalized = ({ children, locale }) => {
708
+ const { pathname, search } = useLocation(); // Отримати поточний шлях URL
709
+
710
+ // Визначити поточну локаль, за потреби використати локаль за замовчуванням
711
+ const currentLocale = locale ?? defaultLocale;
712
+
713
+ // Видалити префікс локалі з шляху, щоб побудувати базовий шлях
714
+ const pathWithoutLocale = getPathWithoutLocale(
715
+ pathname // Поточний шлях URL
716
+ );
717
+
718
+ /**
719
+ * Якщо middleware.prefixDefault встановлено в true, локаль за замовчуванням має завжди бути з префіксом.
720
+ */
721
+ if (middleware.prefixDefault) {
722
+ // Перевірити локаль
723
+ if (!locale || !locales.includes(locale)) {
724
+ // Перенаправити на локаль за замовчуванням з оновленим шляхом
725
+ return (
726
+ <Navigate
727
+ to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
728
+ replace // Замінити поточний запис в історії на новий
729
+ />
730
+ );
731
+ }
732
+
733
+ // Обгорнути children у IntlayerProvider та встановити поточну локаль
734
+ return (
735
+ <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
736
+ );
737
+ } else {
738
+ /**
739
+ * Коли middleware.prefixDefault встановлено в false, локаль за замовчуванням не має префіксу.
740
+ * Переконатися, що поточна локаль є дійсною та не є локаллю за замовчуванням.
741
+ */
742
+ if (
743
+ currentLocale.toString() !== defaultLocale.toString() &&
744
+ !locales
745
+ .filter(
746
+ (locale) => locale.toString() !== defaultLocale.toString() // Виключити локаль за замовчуванням
747
+ )
748
+ .includes(currentLocale) // Перевірити, чи поточна локаль є в списку допустимих локалей
749
+ ) {
750
+ // Перенаправлення на шлях без префікса локалі
751
+ return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
752
+ }
753
+
754
+ // Обгорнути children в IntlayerProvider та встановити поточну локаль
755
+ return (
756
+ <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
757
+ );
758
+ }
759
+ };
760
+
761
+ /**
762
+ * Компонент роутера, який налаштовує маршрути для кожної локалі.
763
+ * Використовує React Router для керування навігацією та рендерингу локалізованих компонентів.
764
+ */
765
+ const LocaleRouter = ({ children }) => (
766
+ <BrowserRouter>
767
+ <Routes>
768
+ {locales
769
+ .filter(
770
+ (locale) => middleware.prefixDefault || locale !== defaultLocale
771
+ )
772
+ .map((locale) => (
773
+ <Route
774
+ // Шаблон маршруту для захоплення локалі (наприклад, /en/, /fr/) і відповідності всім наступним шляхам
775
+ path={`/${locale}/*`}
776
+ key={locale}
777
+ element={<AppLocalized locale={locale}>{children}</AppLocalized>} // Обгортає дочірні елементи управлінням локаллю
778
+ />
779
+ ))}
780
+
781
+ {
782
+ // Якщо префіксування локалі за замовчуванням вимкнено, відрендерити дочірні елементи безпосередньо на кореневому шляху
783
+ !middleware.prefixDefault && (
784
+ <Route
785
+ path="*"
786
+ element={
787
+ <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
788
+ } // Обгортає дочірні елементи управлінням локаллю
789
+ />
790
+ )
791
+ }
792
+ </Routes>
793
+ </BrowserRouter>
794
+ );
795
+ ```
796
+
797
+ Потім ви можете використовувати компонент `LocaleRouter` у вашому застосунку:
798
+
799
+ ```tsx fileName="src/App.tsx" codeFormat="typescript"
800
+ import { LocaleRouter } from "./components/LocaleRouter";
801
+ import type { FC } from "react";
802
+
803
+ // ... Ваш компонент AppContent
804
+
805
+ const App: FC = () => (
806
+ <LocaleRouter>
807
+ <AppContent />
808
+ </LocaleRouter>
809
+ );
810
+ ```
811
+
812
+ ```jsx fileName="src/App.mjx" codeFormat="esm"
813
+ import { LocaleRouter } from "./components/LocaleRouter";
814
+
815
+ // ... Ваш компонент AppContent
816
+
817
+ const App = () => (
818
+ <LocaleRouter>
819
+ <AppContent />
820
+ </LocaleRouter>
821
+ );
822
+ ```
823
+
824
+ ```jsx fileName="src/App.cjx" codeFormat="commonjs"
825
+ const { LocaleRouter } = require("./components/LocaleRouter");
826
+
827
+ // ... Ваш компонент AppContent
828
+
829
+ const App = () => (
830
+ <LocaleRouter>
831
+ <AppContent />
832
+ </LocaleRouter>
833
+ );
834
+ ```
835
+
836
+ ### (Необов'язково) Крок 8: Змінити URL при зміні локалі
837
+
838
+ Щоб змінювати URL при зміні локалі, ви можете використовувати проп `onLocaleChange`, що надається хуком `useLocale`. Паралельно можна використовувати хуки `useLocation` та `useNavigate` з `react-router-dom` для оновлення шляху URL.
839
+
840
+ ```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
841
+ import { useLocation, useNavigate } from "react-router-dom";
842
+ import {
843
+ Locales,
844
+ getHTMLTextDir,
845
+ getLocaleName,
846
+ getLocalizedUrl,
847
+ } from "intlayer";
848
+ import { useLocale } from "react-intlayer";
849
+ import { type FC } from "react";
850
+
851
+ const LocaleSwitcher: FC = () => {
852
+ const { pathname, search } = useLocation(); // Отримати поточний шлях URL. Приклад: /fr/about?foo=bar
853
+ const navigate = useNavigate();
854
+
855
+ const { locale, availableLocales, setLocale } = useLocale({
856
+ onLocaleChange: (locale) => {
857
+ // Сформувати URL з оновленою локаллю
858
+ // Приклад: /es/about?foo=bar
859
+ const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
860
+
861
+ // Оновити шлях URL
862
+ navigate(pathWithLocale);
863
+ },
864
+ });
865
+
866
+ return (
867
+ <div>
868
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
869
+ <div id="localePopover" popover="auto">
870
+ {availableLocales.map((localeItem) => (
871
+ <a
872
+ href={getLocalizedUrl(location.pathname, localeItem)}
873
+ hrefLang={localeItem}
874
+ aria-current={locale === localeItem ? "page" : undefined}
875
+ onClick={(e) => {
876
+ e.preventDefault();
877
+ setLocale(localeItem);
878
+ }}
879
+ key={localeItem}
880
+ >
881
+ <span>
882
+ {/* Локаль — напр. FR */}
883
+ {localeItem}
884
+ </span>
885
+ <span>
886
+ {/* Назва мови у її власній локалі — напр. Français */}
887
+ {getLocaleName(localeItem, locale)}
888
+ </span>
889
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
890
+ {/* Назва мови у поточній локалі — напр. Francés, коли поточна локаль встановлена на Locales.SPANISH */}
891
+ {getLocaleName(localeItem)}
892
+ </span>
893
+ <span dir="ltr" lang={Locales.ENGLISH}>
894
+ {/* Назва мови англійською — напр. French */}
895
+ {getLocaleName(localeItem, Locales.ENGLISH)}
896
+ </span>
897
+ </a>
898
+ ))}
899
+ </div>
900
+ </div>
901
+ );
902
+ };
903
+ ```
904
+
905
+ ```jsx fileName="src/components/LocaleSwitcher.msx" codeFormat="esm"
906
+ import { useLocation, useNavigate } from "react-router-dom";
907
+ import {
908
+ Locales,
909
+ getHTMLTextDir,
910
+ getLocaleName,
911
+ getLocalizedUrl,
912
+ } from "intlayer";
913
+ import { useLocale } from "react-intlayer";
914
+
915
+ const LocaleSwitcher = () => {
916
+ const { pathname, search } = useLocation(); // Отримати поточний шлях URL. Приклад: /fr/about?foo=bar
917
+ const navigate = useNavigate();
918
+
919
+ const { locale, availableLocales, setLocale } = useLocale({
920
+ onLocaleChange: (locale) => {
921
+ // Сформувати URL з оновленою локаллю
922
+ // Приклад: /es/about?foo=bar
923
+ const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
924
+
925
+ // Оновити шлях URL
926
+ navigate(pathWithLocale);
927
+ },
928
+ });
929
+
930
+ return (
931
+ <div>
932
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
933
+ <div id="localePopover" popover="auto">
934
+ {availableLocales.map((localeItem) => (
935
+ <a
936
+ href={getLocalizedUrl(location.pathname, localeItem)}
937
+ hrefLang={localeItem}
938
+ aria-current={locale === localeItem ? "page" : undefined}
939
+ onClick={(e) => {
940
+ e.preventDefault();
941
+ setLocale(localeItem);
942
+ }}
943
+ key={localeItem}
944
+ >
945
+ <span>
946
+ {/* Локаль — напр., FR */}
947
+ {localeItem}
948
+ </span>
949
+ <span>
950
+ {/* Назва мови у своїй локалі — напр., Français */}
951
+ {getLocaleName(localeItem, locale)}
952
+ </span>
953
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
954
+ {/* Мова у поточній локалі — наприклад «Francés», якщо поточна локаль встановлена як Locales.SPANISH */}
955
+ {getLocaleName(localeItem)}
956
+ </span>
957
+ <span dir="ltr" lang={Locales.ENGLISH}>
958
+ {/* Мова англійською — наприклад «French» */}
959
+ {getLocaleName(localeItem, Locales.ENGLISH)}
960
+ </span>
961
+ </a>
962
+ ))}
963
+ </div>
964
+ </div>
965
+ );
966
+ };
967
+ ```
968
+
969
+ ```jsx fileName="src/components/LocaleSwitcher.csx" codeFormat="commonjs"
970
+ const { useLocation, useNavigate } = require("react-router-dom");
971
+ const {
972
+ Locales,
973
+ getHTMLTextDir,
974
+ getLocaleName,
975
+ getLocalizedUrl,
976
+ } = require("intlayer");
977
+ const { useLocale } = require("react-intlayer");
978
+
979
+ const LocaleSwitcher = () => {
980
+ const { pathname, search } = useLocation(); // Отримати поточний шлях URL. Наприклад: /fr/about?foo=bar
981
+ const navigate = useNavigate();
982
+
983
+ const { locale, availableLocales, setLocale } = useLocale({
984
+ onLocaleChange: (locale) => {
985
+ // Побудувати URL з оновленою локаллю
986
+ // Наприклад: /es/about?foo=bar
987
+ const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
988
+
989
+ // Оновити шлях URL
990
+ navigate(pathWithLocale);
991
+ },
992
+ });
993
+
994
+ return (
995
+ <div>
996
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
997
+ <div id="localePopover" popover="auto">
998
+ {availableLocales.map((localeItem) => (
999
+ <a
1000
+ href={getLocalizedUrl(location.pathname, localeItem)}
1001
+ hrefLang={localeItem}
1002
+ aria-current={locale === localeItem ? "page" : undefined}
1003
+ onClick={(e) => {
1004
+ e.preventDefault();
1005
+ setLocale(localeItem);
1006
+ }}
1007
+ key={localeItem}
1008
+ >
1009
+ <span>
1010
+ {/* Локаль - наприклад FR */}
1011
+ {localeItem}
1012
+ </span>
1013
+ <span>
1014
+ {/* Мова у власній локалі - наприклад Français */}
1015
+ {getLocaleName(localeItem, locale)}
1016
+ </span>
1017
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1018
+ {/* Мова в поточній локалі - наприклад Francés, коли поточна локаль встановлена як Locales.SPANISH */}
1019
+ {getLocaleName(localeItem)}
1020
+ </span>
1021
+ <span dir="ltr" lang={Locales.ENGLISH}>
1022
+ {/* Мова англійською - наприклад French */}
1023
+ {getLocaleName(localeItem, Locales.ENGLISH)}
1024
+ </span>
1025
+ </a>
1026
+ ))}
1027
+ </div>
1028
+ </div>
1029
+ );
1030
+ };
1031
+ ```
1032
+
1033
+ > Посилання на документацію:
1034
+ >
1035
+ > - [Хук `useLocale`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/react-intlayer/useLocale.md)
1036
+ > - [Хук `getLocaleName`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/intlayer/getLocaleName.md)
1037
+ > - [Хук `getLocalizedUrl`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/intlayer/getLocalizedUrl.md)
1038
+ > - [Хук `getHTMLTextDir`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/intlayer/getHTMLTextDir.md)
1039
+ > - [Атрибут `hrefLang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
1040
+ > - [Атрибут `lang`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang)
1041
+ > - [Атрибут `dir`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir)
1042
+ > - [Атрибут `aria-current`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)
1043
+
1044
+ ### (Необов'язково) Крок 9: Змінити атрибути мови та напрямку HTML
1045
+
1046
+ Коли ваш застосунок підтримує кілька мов, важливо оновлювати атрибути `lang` та `dir` тега `<html>`, щоб вони відповідали поточній локалі. Це забезпечує:
1047
+
1048
+ - **Доступність**: Екранні читачі та допоміжні технології покладаються на правильний атрибут `lang` для точного вимови та інтерпретації контенту.
1049
+ - **Відображення тексту**: Атрибут `dir` (напрямок) забезпечує правильний порядок відображення тексту (наприклад, зліва направо для англійської, справа наліво для арабської або івриту), що важливо для читабельності.
1050
+ - **SEO**: Пошукові системи використовують атрибут `lang` для визначення мови вашої сторінки, допомагаючи показувати правильний локалізований контент у результатах пошуку.
1051
+
1052
+ Оновлюючи ці атрибути динамічно при зміні локалі, ви гарантуєте послідовний та доступний досвід для користувачів усіх підтримуваних мов.
1053
+
1054
+ #### Реалізація хука
1055
+
1056
+ Створіть власний хук для керування атрибутами HTML. Хук слухає зміни локалі та відповідно оновлює атрибути:
1057
+
1058
+ ```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat="typescript"
1059
+ import { useEffect } from "react";
1060
+ import { useLocale } from "react-intlayer";
1061
+ import { getHTMLTextDir } from "intlayer";
1062
+
1063
+ /**
1064
+ * Оновлює атрибути `lang` та `dir` елемента HTML <html> на основі поточної локалі.
1065
+ * - `lang`: Повідомляє браузери та пошукові системи про мову сторінки.
1066
+ * - `dir`: Забезпечує правильний порядок читання (наприклад, 'ltr' для англійської, 'rtl' для арабської).
1067
+ *
1068
+ * Це динамічне оновлення важливе для правильного відображення тексту, доступності та SEO.
1069
+ */
1070
+ export const useI18nHTMLAttributes = () => {
1071
+ const { locale } = useLocale();
1072
+
1073
+ useEffect(() => {
1074
+ // Оновити атрибут мови на поточну локаль.
1075
+ document.documentElement.lang = locale;
1076
+
1077
+ // Встановити напрямок тексту на основі поточної локалі.
1078
+ document.documentElement.dir = getHTMLTextDir(locale);
1079
+ }, [locale]);
1080
+ };
1081
+ ```
1082
+
1083
+ ```jsx fileName="src/hooks/useI18nHTMLAttributes.msx" codeFormat="esm"
1084
+ import { useEffect } from "react";
1085
+ import { useLocale } from "react-intlayer";
1086
+ import { getHTMLTextDir } from "intlayer";
1087
+
1088
+ /**
1089
+ * Оновлює атрибути `lang` та `dir` елемента HTML <html> на основі поточної локалі.
1090
+ * - `lang`: Повідомляє браузери та пошукові системи про мову сторінки.
1091
+ * - `dir`: Забезпечує правильний порядок читання (наприклад, 'ltr' для англійської, 'rtl' для арабської).
1092
+ *
1093
+ * Це динамічне оновлення важливе для правильного відображення тексту, доступності та SEO.
1094
+ */
1095
+ export const useI18nHTMLAttributes = () => {
1096
+ const { locale } = useLocale();
1097
+
1098
+ useEffect(() => {
1099
+ // Оновити атрибут мови на поточну локаль.
1100
+ document.documentElement.lang = locale;
1101
+
1102
+ // Встановити напрямок тексту на основі поточної локалі.
1103
+ document.documentElement.dir = getHTMLTextDir(locale);
1104
+ }, [locale]);
1105
+ };
1106
+ ```
1107
+
1108
+ ```jsx fileName="src/hooks/useI18nHTMLAttributes.csx" codeFormat="commonjs"
1109
+ const { useEffect } = require("react");
1110
+ const { useLocale } = require("react-intlayer");
1111
+ const { getHTMLTextDir } = require("intlayer");
1112
+
1113
+ /**
1114
+ * Оновлює атрибути `lang` та `dir` елемента HTML <html> на основі поточної локалі.
1115
+ * - `lang`: Повідомляє браузери та пошукові системи про мову сторінки.
1116
+ * - `dir`: Забезпечує правильний порядок читання (наприклад, 'ltr' для англійської, 'rtl' для арабської).
1117
+ *
1118
+ * Це динамічне оновлення важливе для правильного відображення тексту, доступності та SEO.
1119
+ */
1120
+ const useI18nHTMLAttributes = () => {
1121
+ const { locale } = useLocale();
1122
+
1123
+ useEffect(() => {
1124
+ // Оновити атрибут мови на поточну локаль.
1125
+ document.documentElement.lang = locale;
1126
+
1127
+ // Встановити напрямок тексту на основі поточної локалі.
1128
+ document.documentElement.dir = getHTMLTextDir(locale);
1129
+ }, [locale]);
1130
+ };
1131
+
1132
+ module.exports = { useI18nHTMLAttributes };
1133
+ ```
1134
+
1135
+ #### Використання хука у вашому застосунку
1136
+
1137
+ Інтегруйте хук у ваш основний компонент, щоб атрибути HTML оновлювалися щоразу, коли змінюється локаль:
1138
+
1139
+ ```tsx fileName="src/App.tsx" codeFormat="typescript"
1140
+ import type { FC } from "react";
1141
+ import { IntlayerProvider, useIntlayer } from "react-intlayer";
1142
+ import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
1143
+ import "./App.css";
1144
+
1145
+ const AppContent: FC = () => {
1146
+ // Застосувати хук для оновлення атрибутів `lang` та `dir` тега <html> на основі локалі.
1147
+ useI18nHTMLAttributes();
1148
+
1149
+ // ... Решта вашого компонента
1150
+ };
1151
+
1152
+ const App: FC = () => (
1153
+ <IntlayerProvider>
1154
+ <AppContent />
1155
+ </IntlayerProvider>
1156
+ );
1157
+
1158
+ export default App;
1159
+ ```
1160
+
1161
+ ```jsx fileName="src/App.msx" codeFormat="esm"
1162
+ import { IntlayerProvider, useIntlayer } from "react-intlayer";
1163
+ import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
1164
+ import "./App.css";
1165
+
1166
+ const AppContent = () => {
1167
+ // Застосувати хук для оновлення атрибутів `lang` та `dir` тега <html> на основі локалі.
1168
+ useI18nHTMLAttributes();
1169
+
1170
+ // ... Решта вашого компонента
1171
+ };
1172
+
1173
+ const App = () => (
1174
+ <IntlayerProvider>
1175
+ <AppContent />
1176
+ </IntlayerProvider>
1177
+ );
1178
+
1179
+ export default App;
1180
+ ```
1181
+
1182
+ ```jsx fileName="src/App.csx" codeFormat="commonjs"
1183
+ const { FC } = require("react");
1184
+ const { IntlayerProvider, useIntlayer } = require("react-intlayer");
1185
+ const { useI18nHTMLAttributes } = require("./hooks/useI18nHTMLAttributes");
1186
+ require("./App.css");
1187
+
1188
+ const AppContent = () => {
1189
+ // Застосувати хук для оновлення атрибутів `lang` та `dir` тега <html> на основі локалі.
1190
+ useI18nHTMLAttributes();
1191
+
1192
+ // ... Решта вашого компонента
1193
+ };
1194
+
1195
+ const App = () => (
1196
+ <IntlayerProvider>
1197
+ <AppContent />
1198
+ </IntlayerProvider>
1199
+ );
1200
+
1201
+ module.exports = App;
1202
+ ```
1203
+
1204
+ Застосувавши ці зміни, ваш застосунок буде:
1205
+
1206
+ - Забезпечувати правильне відображення атрибута **мови** (`lang`) відповідно до поточної локалі, що важливо для SEO та поведінки браузера.
1207
+ - Налаштовувати **напрямок тексту** (`dir`) відповідно до локалі, покращуючи читабельність та зручність використання для мов з різним порядком читання.
1208
+ - Забезпечувати більш **доступний** досвід, оскільки допоміжні технології покладаються на ці атрибути для оптимальної роботи.
1209
+
1210
+ ### Налаштування TypeScript
1211
+
1212
+ Intlayer використовує module augmentation для отримання переваг TypeScript та зміцнення вашої кодової бази.
1213
+
1214
+ ![Автодоповнення](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)
1215
+
1216
+ ![Помилка перекладу](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)
1217
+
1218
+ Переконайтеся, що ваша конфігурація TypeScript включає автогенеровані типи.
1219
+
1220
+ ```json5 fileName="tsconfig.json"
1221
+ {
1222
+ // ... Ваші існуючі конфігурації TypeScript
1223
+ "include": [
1224
+ // ... Ваші існуючі конфігурації TypeScript
1225
+ ".intlayer/**/*.ts", // Включити автогенеровані типи
1226
+ ],
1227
+ }
1228
+ ```
1229
+
1230
+ ### Конфігурація Git
1231
+
1232
+ Рекомендується ігнорувати файли, згенеровані Intlayer. Це дозволяє уникнути їх коміту до вашого репозиторію Git.
1233
+
1234
+ Для цього додайте наступні інструкції до вашого файлу `.gitignore`:
1235
+
1236
+ ```plaintext fileName=".gitignore"
1237
+ # Ігнорувати файли, згенеровані Intlayer
1238
+ .intlayer
1239
+ ```
1240
+
1241
+ ### Розширення VS Code
1242
+
1243
+ Щоб покращити ваш досвід розробки з Intlayer, ви можете встановити офіційне **Розширення Intlayer VS Code**.
1244
+
1245
+ [Встановити з VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
1246
+
1247
+ Це розширення надає:
1248
+
1249
+ - **Автодоповнення** для ключів перекладу.
1250
+ - **Виявлення помилок у реальному часі** для відсутніх перекладів.
1251
+ - **Вбудовані попередні перегляди** перекладеного контенту.
1252
+ - **Швидкі дії** для легкого створення та оновлення перекладів.
1253
+
1254
+ Для отримання додаткової інформації про використання розширення зверніться до [документації розширення Intlayer VS Code](https://intlayer.org/doc/vs-code-extension).
1255
+
1256
+ ### Піти далі
1257
+
1258
+ Щоб піти далі, ви можете реалізувати [візуальний редактор](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/intlayer_visual_editor.md) або винести ваш контент за допомогою [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/intlayer_CMS.md).