@intlayer/docs 7.5.11 → 7.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/intlayer_with_i18next.md +0 -2
- package/blog/ar/intlayer_with_next-i18next.md +0 -2
- package/blog/ar/intlayer_with_react-i18next.md +0 -2
- package/blog/de/intlayer_with_i18next.md +0 -45
- package/blog/de/intlayer_with_next-i18next.md +0 -46
- package/blog/de/intlayer_with_react-i18next.md +0 -2
- package/blog/en/intlayer_with_i18next.md +0 -46
- package/blog/en/intlayer_with_next-i18next.md +0 -48
- package/blog/en/intlayer_with_next-intl.md +0 -44
- package/blog/en/intlayer_with_react-i18next.md +0 -44
- package/blog/en/intlayer_with_react-intl.md +0 -42
- package/blog/en/intlayer_with_vue-i18n.md +0 -44
- package/blog/en-GB/intlayer_with_i18next.md +0 -45
- package/blog/en-GB/intlayer_with_next-i18next.md +0 -47
- package/blog/en-GB/intlayer_with_next-intl.md +0 -42
- package/blog/en-GB/intlayer_with_react-i18next.md +0 -43
- package/blog/en-GB/intlayer_with_react-intl.md +0 -42
- package/blog/en-GB/intlayer_with_vue-i18n.md +0 -46
- package/blog/es/intlayer_with_i18next.md +0 -45
- package/blog/es/intlayer_with_next-i18next.md +0 -47
- package/blog/es/intlayer_with_next-intl.md +0 -42
- package/blog/es/intlayer_with_react-i18next.md +0 -43
- package/blog/es/intlayer_with_react-intl.md +0 -42
- package/blog/es/intlayer_with_vue-i18n.md +0 -46
- package/blog/fr/intlayer_with_i18next.md +0 -45
- package/blog/fr/intlayer_with_next-i18next.md +0 -47
- package/blog/fr/intlayer_with_next-intl.md +0 -42
- package/blog/fr/intlayer_with_react-i18next.md +0 -43
- package/blog/fr/intlayer_with_react-intl.md +0 -42
- package/blog/fr/intlayer_with_vue-i18n.md +0 -46
- package/blog/hi/intlayer_with_i18next.md +0 -2
- package/blog/hi/intlayer_with_next-i18next.md +0 -2
- package/blog/hi/intlayer_with_react-i18next.md +0 -2
- package/blog/id/intlayer_with_i18next.md +0 -2
- package/blog/id/intlayer_with_next-i18next.md +0 -2
- package/blog/id/intlayer_with_react-i18next.md +0 -2
- package/blog/it/intlayer_with_i18next.md +0 -2
- package/blog/it/intlayer_with_next-i18next.md +0 -2
- package/blog/it/intlayer_with_react-i18next.md +0 -2
- package/blog/ja/intlayer_with_i18next.md +0 -45
- package/blog/ja/intlayer_with_next-i18next.md +0 -46
- package/blog/ja/intlayer_with_next-intl.md +0 -42
- package/blog/ja/intlayer_with_react-i18next.md +0 -42
- package/blog/ja/intlayer_with_react-intl.md +0 -42
- package/blog/ja/intlayer_with_vue-i18n.md +0 -46
- package/blog/ko/intlayer_with_i18next.md +0 -2
- package/blog/ko/intlayer_with_next-i18next.md +0 -2
- package/blog/ko/intlayer_with_react-i18next.md +0 -1
- package/blog/pl/intlayer_with_i18next.md +0 -45
- package/blog/pl/intlayer_with_next-i18next.md +0 -46
- package/blog/pl/intlayer_with_next-intl.md +0 -42
- package/blog/pl/intlayer_with_react-i18next.md +0 -43
- package/blog/pl/intlayer_with_react-intl.md +0 -42
- package/blog/pl/intlayer_with_vue-i18n.md +0 -46
- package/blog/pt/intlayer_with_i18next.md +0 -2
- package/blog/pt/intlayer_with_next-i18next.md +0 -2
- package/blog/pt/intlayer_with_react-i18next.md +0 -2
- package/blog/ru/intlayer_with_i18next.md +0 -45
- package/blog/ru/intlayer_with_next-i18next.md +0 -47
- package/blog/ru/intlayer_with_next-intl.md +0 -42
- package/blog/ru/intlayer_with_react-i18next.md +0 -43
- package/blog/ru/intlayer_with_react-intl.md +0 -42
- package/blog/ru/intlayer_with_vue-i18n.md +0 -46
- package/blog/tr/intlayer_with_i18next.md +0 -2
- package/blog/tr/intlayer_with_next-i18next.md +0 -1
- package/blog/tr/intlayer_with_react-i18next.md +0 -2
- package/blog/uk/compiler_vs_declarative_i18n.md +224 -0
- package/blog/uk/i18n_using_next-i18next.md +1086 -0
- package/blog/uk/i18n_using_next-intl.md +760 -0
- package/blog/uk/index.md +69 -0
- package/blog/uk/internationalization_and_SEO.md +273 -0
- package/blog/uk/intlayer_with_i18next.md +211 -0
- package/blog/uk/intlayer_with_next-i18next.md +202 -0
- package/blog/uk/intlayer_with_next-intl.md +203 -0
- package/blog/uk/intlayer_with_react-i18next.md +200 -0
- package/blog/uk/intlayer_with_react-intl.md +202 -0
- package/blog/uk/intlayer_with_vue-i18n.md +206 -0
- package/blog/uk/l10n_platform_alternative/Lokalise.md +80 -0
- package/blog/uk/l10n_platform_alternative/crowdin.md +80 -0
- package/blog/uk/l10n_platform_alternative/phrase.md +78 -0
- package/blog/uk/list_i18n_technologies/CMS/drupal.md +143 -0
- package/blog/uk/list_i18n_technologies/CMS/wix.md +167 -0
- package/blog/uk/list_i18n_technologies/CMS/wordpress.md +189 -0
- package/blog/uk/list_i18n_technologies/frameworks/angular.md +125 -0
- package/blog/uk/list_i18n_technologies/frameworks/flutter.md +128 -0
- package/blog/uk/list_i18n_technologies/frameworks/react-native.md +217 -0
- package/blog/uk/list_i18n_technologies/frameworks/react.md +155 -0
- package/blog/uk/list_i18n_technologies/frameworks/svelte.md +145 -0
- package/blog/uk/list_i18n_technologies/frameworks/vue.md +144 -0
- package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +1499 -0
- package/blog/uk/nextjs-multilingual-seo-comparison.md +360 -0
- package/blog/uk/rag_powered_documentation_assistant.md +288 -0
- package/blog/uk/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
- package/blog/uk/vue-i18n_vs_intlayer.md +279 -0
- package/blog/uk/what_is_internationalization.md +167 -0
- package/blog/vi/intlayer_with_i18next.md +0 -2
- package/blog/vi/intlayer_with_next-i18next.md +0 -2
- package/blog/vi/intlayer_with_react-i18next.md +0 -2
- package/blog/zh/intlayer_with_i18next.md +0 -2
- package/blog/zh/intlayer_with_next-i18next.md +0 -2
- package/blog/zh/intlayer_with_react-i18next.md +0 -2
- package/blog/zh/intlayer_with_vue-i18n.md +0 -46
- package/dist/cjs/generated/blog.entry.cjs +58 -29
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +218 -99
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +50 -15
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +4 -2
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +58 -29
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +218 -99
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +50 -15
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs +4 -2
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/dist/types/generated/frequentQuestions.entry.d.ts +1 -0
- package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
- package/dist/types/generated/legal.entry.d.ts.map +1 -1
- package/docs/ar/configuration.md +6 -1
- package/docs/ar/dictionary/content_file.md +6 -1
- package/docs/ar/intlayer_with_next-i18next.md +0 -1
- package/docs/ar/intlayer_with_nextjs_14.md +28 -0
- package/docs/ar/intlayer_with_nextjs_15.md +28 -0
- package/docs/ar/intlayer_with_nextjs_16.md +28 -0
- package/docs/ar/intlayer_with_nextjs_no_locale_path.md +1159 -0
- package/docs/ar/plugins/sync-json.md +6 -2
- package/docs/de/configuration.md +6 -1
- package/docs/de/dictionary/content_file.md +6 -1
- package/docs/de/intlayer_with_next-i18next.md +0 -1
- package/docs/de/intlayer_with_nextjs_14.md +28 -0
- package/docs/de/intlayer_with_nextjs_15.md +28 -0
- package/docs/de/intlayer_with_nextjs_16.md +28 -0
- package/docs/de/intlayer_with_nextjs_no_locale_path.md +1152 -0
- package/docs/de/plugins/sync-json.md +6 -2
- package/docs/en/configuration.md +6 -1
- package/docs/en/dictionary/content_file.md +6 -1
- package/docs/en/intlayer_with_next-i18next.md +0 -1
- package/docs/en/intlayer_with_nextjs_14.md +28 -0
- package/docs/en/intlayer_with_nextjs_15.md +28 -0
- package/docs/en/intlayer_with_nextjs_16.md +31 -1
- package/docs/en/intlayer_with_nextjs_no_locale_path.md +1132 -0
- package/docs/en/plugins/sync-json.md +6 -2
- package/docs/en-GB/configuration.md +6 -1
- package/docs/en-GB/dictionary/content_file.md +3 -1
- package/docs/en-GB/intlayer_with_next-i18next.md +0 -1
- package/docs/en-GB/intlayer_with_nextjs_14.md +28 -0
- package/docs/en-GB/intlayer_with_nextjs_15.md +28 -0
- package/docs/en-GB/intlayer_with_nextjs_16.md +28 -0
- package/docs/en-GB/intlayer_with_nextjs_no_locale_path.md +1154 -0
- package/docs/en-GB/plugins/sync-json.md +6 -2
- package/docs/es/configuration.md +6 -1
- package/docs/es/dictionary/content_file.md +6 -1
- package/docs/es/intlayer_with_next-i18next.md +0 -1
- package/docs/es/intlayer_with_nextjs_14.md +28 -0
- package/docs/es/intlayer_with_nextjs_15.md +28 -0
- package/docs/es/intlayer_with_nextjs_16.md +28 -0
- package/docs/es/intlayer_with_nextjs_no_locale_path.md +1143 -0
- package/docs/es/plugins/sync-json.md +6 -2
- package/docs/fr/configuration.md +6 -1
- package/docs/fr/dictionary/content_file.md +3 -1
- package/docs/fr/intlayer_with_next-i18next.md +0 -1
- package/docs/fr/intlayer_with_nextjs_14.md +28 -0
- package/docs/fr/intlayer_with_nextjs_15.md +28 -0
- package/docs/fr/intlayer_with_nextjs_16.md +28 -0
- package/docs/fr/intlayer_with_nextjs_no_locale_path.md +1174 -0
- package/docs/fr/plugins/sync-json.md +9 -5
- package/docs/hi/configuration.md +6 -1
- package/docs/hi/dictionary/content_file.md +3 -1
- package/docs/hi/intlayer_with_next-i18next.md +0 -1
- package/docs/hi/intlayer_with_nextjs_14.md +28 -0
- package/docs/hi/intlayer_with_nextjs_15.md +28 -0
- package/docs/hi/intlayer_with_nextjs_16.md +28 -0
- package/docs/hi/intlayer_with_nextjs_no_locale_path.md +1151 -0
- package/docs/hi/plugins/sync-json.md +6 -2
- package/docs/id/configuration.md +6 -1
- package/docs/id/dictionary/content_file.md +3 -1
- package/docs/id/intlayer_with_next-i18next.md +0 -1
- package/docs/id/intlayer_with_nextjs_14.md +28 -0
- package/docs/id/intlayer_with_nextjs_15.md +28 -0
- package/docs/id/intlayer_with_nextjs_16.md +28 -0
- package/docs/id/intlayer_with_nextjs_no_locale_path.md +1154 -0
- package/docs/id/plugins/sync-json.md +6 -2
- package/docs/it/configuration.md +6 -1
- package/docs/it/dictionary/content_file.md +3 -1
- package/docs/it/intlayer_with_next-i18next.md +0 -1
- package/docs/it/intlayer_with_nextjs_14.md +28 -0
- package/docs/it/intlayer_with_nextjs_15.md +28 -0
- package/docs/it/intlayer_with_nextjs_16.md +28 -0
- package/docs/it/intlayer_with_nextjs_no_locale_path.md +1148 -0
- package/docs/it/plugins/sync-json.md +6 -2
- package/docs/ja/configuration.md +6 -1
- package/docs/ja/dictionary/content_file.md +3 -1
- package/docs/ja/intlayer_with_next-i18next.md +0 -1
- package/docs/ja/intlayer_with_nextjs_14.md +28 -0
- package/docs/ja/intlayer_with_nextjs_15.md +28 -0
- package/docs/ja/intlayer_with_nextjs_16.md +28 -0
- package/docs/ja/intlayer_with_nextjs_no_locale_path.md +1222 -0
- package/docs/ja/plugins/sync-json.md +6 -2
- package/docs/ko/configuration.md +6 -1
- package/docs/ko/dictionary/content_file.md +3 -1
- package/docs/ko/intlayer_with_next-i18next.md +0 -1
- package/docs/ko/intlayer_with_nextjs_14.md +28 -0
- package/docs/ko/intlayer_with_nextjs_15.md +28 -0
- package/docs/ko/intlayer_with_nextjs_16.md +28 -0
- package/docs/ko/intlayer_with_nextjs_no_locale_path.md +1205 -0
- package/docs/ko/plugins/sync-json.md +6 -2
- package/docs/pl/configuration.md +3 -1
- package/docs/pl/dictionary/content_file.md +3 -1
- package/docs/pl/intlayer_with_next-i18next.md +0 -1
- package/docs/pl/intlayer_with_nextjs_14.md +28 -0
- package/docs/pl/intlayer_with_nextjs_15.md +28 -0
- package/docs/pl/intlayer_with_nextjs_16.md +28 -0
- package/docs/pl/intlayer_with_nextjs_no_locale_path.md +1149 -0
- package/docs/pl/plugins/sync-json.md +6 -2
- package/docs/pt/configuration.md +6 -1
- package/docs/pt/dictionary/content_file.md +3 -1
- package/docs/pt/intlayer_with_next-i18next.md +0 -1
- package/docs/pt/intlayer_with_nextjs_14.md +28 -0
- package/docs/pt/intlayer_with_nextjs_15.md +28 -0
- package/docs/pt/intlayer_with_nextjs_16.md +28 -0
- package/docs/pt/intlayer_with_nextjs_no_locale_path.md +1152 -0
- package/docs/pt/plugins/sync-json.md +6 -2
- package/docs/ru/configuration.md +6 -1
- package/docs/ru/dictionary/content_file.md +6 -1
- package/docs/ru/intlayer_with_next-i18next.md +0 -1
- package/docs/ru/intlayer_with_nextjs_14.md +28 -0
- package/docs/ru/intlayer_with_nextjs_15.md +28 -0
- package/docs/ru/intlayer_with_nextjs_16.md +28 -0
- package/docs/ru/intlayer_with_nextjs_no_locale_path.md +1204 -0
- package/docs/ru/plugins/sync-json.md +6 -2
- package/docs/tr/configuration.md +6 -1
- package/docs/tr/dictionary/content_file.md +3 -1
- package/docs/tr/intlayer_with_next-i18next.md +0 -1
- package/docs/tr/intlayer_with_nextjs_14.md +28 -0
- package/docs/tr/intlayer_with_nextjs_15.md +28 -0
- package/docs/tr/intlayer_with_nextjs_16.md +28 -0
- package/docs/tr/intlayer_with_nextjs_no_locale_path.md +1159 -0
- package/docs/tr/plugins/sync-json.md +6 -2
- package/docs/uk/CI_CD.md +198 -0
- package/docs/uk/autoFill.md +307 -0
- package/docs/uk/bundle_optimization.md +185 -0
- package/docs/uk/cli/build.md +64 -0
- package/docs/uk/cli/ci.md +137 -0
- package/docs/uk/cli/configuration.md +63 -0
- package/docs/uk/cli/debug.md +46 -0
- package/docs/uk/cli/doc-review.md +43 -0
- package/docs/uk/cli/doc-translate.md +132 -0
- package/docs/uk/cli/editor.md +28 -0
- package/docs/uk/cli/fill.md +130 -0
- package/docs/uk/cli/index.md +190 -0
- package/docs/uk/cli/init.md +84 -0
- package/docs/uk/cli/list.md +90 -0
- package/docs/uk/cli/list_projects.md +128 -0
- package/docs/uk/cli/live.md +41 -0
- package/docs/uk/cli/login.md +157 -0
- package/docs/uk/cli/pull.md +78 -0
- package/docs/uk/cli/push.md +98 -0
- package/docs/uk/cli/sdk.md +71 -0
- package/docs/uk/cli/test.md +76 -0
- package/docs/uk/cli/transform.md +65 -0
- package/docs/uk/cli/version.md +24 -0
- package/docs/uk/cli/watch.md +37 -0
- package/docs/uk/compiler.md +133 -0
- package/docs/uk/component_i18n.md +194 -0
- package/docs/uk/configuration.md +742 -0
- package/docs/uk/dictionary/condition.md +237 -0
- package/docs/uk/dictionary/content_file.md +1134 -0
- package/docs/uk/dictionary/enumeration.md +245 -0
- package/docs/uk/dictionary/file.md +232 -0
- package/docs/uk/dictionary/function_fetching.md +212 -0
- package/docs/uk/dictionary/gender.md +273 -0
- package/docs/uk/dictionary/insertion.md +187 -0
- package/docs/uk/dictionary/markdown.md +383 -0
- package/docs/uk/dictionary/nesting.md +273 -0
- package/docs/uk/dictionary/translation.md +332 -0
- package/docs/uk/formatters.md +595 -0
- package/docs/uk/how_works_intlayer.md +256 -0
- package/docs/uk/index.md +175 -0
- package/docs/uk/interest_of_intlayer.md +297 -0
- package/docs/uk/intlayer_CMS.md +569 -0
- package/docs/uk/intlayer_visual_editor.md +292 -0
- package/docs/uk/intlayer_with_angular.md +710 -0
- package/docs/uk/intlayer_with_astro.md +256 -0
- package/docs/uk/intlayer_with_create_react_app.md +1258 -0
- package/docs/uk/intlayer_with_express.md +429 -0
- package/docs/uk/intlayer_with_fastify.md +446 -0
- package/docs/uk/intlayer_with_lynx+react.md +548 -0
- package/docs/uk/intlayer_with_nestjs.md +283 -0
- package/docs/uk/intlayer_with_next-i18next.md +640 -0
- package/docs/uk/intlayer_with_next-intl.md +456 -0
- package/docs/uk/intlayer_with_nextjs_14.md +1646 -0
- package/docs/uk/intlayer_with_nextjs_15.md +1910 -0
- package/docs/uk/intlayer_with_nextjs_16.md +1763 -0
- package/docs/uk/intlayer_with_nextjs_no_locale_path.md +1159 -0
- package/docs/uk/intlayer_with_nextjs_page_router.md +1541 -0
- package/docs/uk/intlayer_with_nuxt.md +711 -0
- package/docs/uk/intlayer_with_react_native+expo.md +715 -0
- package/docs/uk/intlayer_with_react_router_v7.md +600 -0
- package/docs/uk/intlayer_with_react_router_v7_fs_routes.md +669 -0
- package/docs/uk/intlayer_with_svelte_kit.md +579 -0
- package/docs/uk/intlayer_with_tanstack.md +818 -0
- package/docs/uk/intlayer_with_vite+preact.md +1748 -0
- package/docs/uk/intlayer_with_vite+react.md +1449 -0
- package/docs/uk/intlayer_with_vite+solid.md +302 -0
- package/docs/uk/intlayer_with_vite+svelte.md +520 -0
- package/docs/uk/intlayer_with_vite+vue.md +1113 -0
- package/docs/uk/introduction.md +222 -0
- package/docs/uk/locale_mapper.md +242 -0
- package/docs/uk/mcp_server.md +211 -0
- package/docs/uk/packages/express-intlayer/t.md +465 -0
- package/docs/uk/packages/intlayer/getConfiguration.md +145 -0
- package/docs/uk/packages/intlayer/getEnumeration.md +159 -0
- package/docs/uk/packages/intlayer/getHTMLTextDir.md +121 -0
- package/docs/uk/packages/intlayer/getLocaleLang.md +81 -0
- package/docs/uk/packages/intlayer/getLocaleName.md +135 -0
- package/docs/uk/packages/intlayer/getLocalizedUrl.md +338 -0
- package/docs/uk/packages/intlayer/getMultilingualUrls.md +359 -0
- package/docs/uk/packages/intlayer/getPathWithoutLocale.md +75 -0
- package/docs/uk/packages/intlayer/getPrefix.md +213 -0
- package/docs/uk/packages/intlayer/getTranslation.md +190 -0
- package/docs/uk/packages/intlayer/getTranslationContent.md +189 -0
- package/docs/uk/packages/next-intlayer/t.md +365 -0
- package/docs/uk/packages/next-intlayer/useDictionary.md +276 -0
- package/docs/uk/packages/next-intlayer/useIntlayer.md +263 -0
- package/docs/uk/packages/next-intlayer/useLocale.md +166 -0
- package/docs/uk/packages/react-intlayer/t.md +311 -0
- package/docs/uk/packages/react-intlayer/useDictionary.md +295 -0
- package/docs/uk/packages/react-intlayer/useI18n.md +250 -0
- package/docs/uk/packages/react-intlayer/useIntlayer.md +251 -0
- package/docs/uk/packages/react-intlayer/useLocale.md +210 -0
- package/docs/uk/per_locale_file.md +345 -0
- package/docs/uk/plugins/sync-json.md +398 -0
- package/docs/uk/readme.md +265 -0
- package/docs/uk/releases/v6.md +305 -0
- package/docs/uk/releases/v7.md +624 -0
- package/docs/uk/roadmap.md +346 -0
- package/docs/uk/testing.md +204 -0
- package/docs/uk/vs_code_extension.md +133 -0
- package/docs/vi/configuration.md +6 -1
- package/docs/vi/dictionary/content_file.md +6 -1
- package/docs/vi/intlayer_with_next-i18next.md +0 -1
- package/docs/vi/intlayer_with_nextjs_14.md +28 -0
- package/docs/vi/intlayer_with_nextjs_15.md +28 -0
- package/docs/vi/intlayer_with_nextjs_16.md +28 -0
- package/docs/vi/intlayer_with_nextjs_no_locale_path.md +1151 -0
- package/docs/vi/plugins/sync-json.md +6 -2
- package/docs/zh/configuration.md +6 -1
- package/docs/zh/dictionary/content_file.md +6 -1
- package/docs/zh/intlayer_with_next-i18next.md +0 -1
- package/docs/zh/intlayer_with_nextjs_14.md +28 -0
- package/docs/zh/intlayer_with_nextjs_15.md +28 -0
- package/docs/zh/intlayer_with_nextjs_16.md +28 -0
- package/docs/zh/intlayer_with_nextjs_no_locale_path.md +1206 -0
- package/docs/zh/plugins/sync-json.md +9 -5
- package/frequent_questions/ar/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/ar/error-vite-env-only.md +77 -0
- package/frequent_questions/de/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/de/error-vite-env-only.md +77 -0
- package/frequent_questions/en/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/en/error-vite-env-only.md +77 -0
- package/frequent_questions/en-GB/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/en-GB/error-vite-env-only.md +77 -0
- package/frequent_questions/es/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/es/error-vite-env-only.md +76 -0
- package/frequent_questions/fr/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/fr/error-vite-env-only.md +77 -0
- package/frequent_questions/hi/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/hi/error-vite-env-only.md +77 -0
- package/frequent_questions/id/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/id/error-vite-env-only.md +77 -0
- package/frequent_questions/it/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/it/error-vite-env-only.md +77 -0
- package/frequent_questions/ja/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/ja/error-vite-env-only.md +77 -0
- package/frequent_questions/ko/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/ko/error-vite-env-only.md +77 -0
- package/frequent_questions/pl/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/pl/error-vite-env-only.md +77 -0
- package/frequent_questions/pt/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/pt/error-vite-env-only.md +77 -0
- package/frequent_questions/ru/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/ru/error-vite-env-only.md +77 -0
- package/frequent_questions/tr/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/tr/error-vite-env-only.md +77 -0
- package/frequent_questions/uk/SSR_Next_no_[locale].md +104 -0
- package/frequent_questions/uk/array_as_content_declaration.md +72 -0
- package/frequent_questions/uk/build_dictionaries.md +58 -0
- package/frequent_questions/uk/build_error_CI_CD.md +74 -0
- package/frequent_questions/uk/bun_set_up.md +53 -0
- package/frequent_questions/uk/customized_locale_list.md +64 -0
- package/frequent_questions/uk/domain_routing.md +113 -0
- package/frequent_questions/uk/error-vite-env-only.md +77 -0
- package/frequent_questions/uk/esbuild_error.md +29 -0
- package/frequent_questions/uk/get_locale_cookie.md +142 -0
- package/frequent_questions/uk/intlayer_command_undefined.md +155 -0
- package/frequent_questions/uk/locale_incorect_in_url.md +73 -0
- package/frequent_questions/uk/package_version_error.md +181 -0
- package/frequent_questions/uk/static_rendering.md +44 -0
- package/frequent_questions/uk/translated_path_url.md +55 -0
- package/frequent_questions/uk/unknown_command.md +97 -0
- package/frequent_questions/vi/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/vi/error-vite-env-only.md +77 -0
- package/frequent_questions/zh/SSR_Next_no_[locale].md +1 -1
- package/frequent_questions/zh/error-vite-env-only.md +77 -0
- package/legal/uk/privacy_notice.md +83 -0
- package/legal/uk/terms_of_service.md +55 -0
- package/package.json +6 -6
- package/src/generated/blog.entry.ts +29 -0
- package/src/generated/docs.entry.ts +119 -0
- package/src/generated/frequentQuestions.entry.ts +35 -0
- package/src/generated/legal.entry.ts +2 -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
|
+

|
|
1215
|
+
|
|
1216
|
+

|
|
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).
|