@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,669 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-12-07
|
|
3
|
+
updatedAt: 2025-12-30
|
|
4
|
+
title: Як перекласти ваш додаток на React Router v7 (File-System Routes) — посібник з i18n 2026
|
|
5
|
+
description: Дізнайтеся, як додати інтернаціоналізацію (i18n) до вашого додатка на React Router v7 за допомогою Intlayer і маршрутизації на основі файлової системи. Дотримуйтеся цього вичерпного керівництва, щоб зробити ваш додаток багатомовним із локалізованою маршрутизацією.
|
|
6
|
+
keywords:
|
|
7
|
+
- Інтернаціоналізація
|
|
8
|
+
- Документація
|
|
9
|
+
- Intlayer
|
|
10
|
+
- React Router v7
|
|
11
|
+
- fs-routes
|
|
12
|
+
- Маршрути файлової системи
|
|
13
|
+
- React
|
|
14
|
+
- i18n
|
|
15
|
+
- TypeScript
|
|
16
|
+
- Локалізована маршрутизація
|
|
17
|
+
slugs:
|
|
18
|
+
- doc
|
|
19
|
+
- environment
|
|
20
|
+
- vite-and-react
|
|
21
|
+
- react-router-v7-fs-routes
|
|
22
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-react-router-v7-fs-routes-template
|
|
23
|
+
youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
|
|
24
|
+
history:
|
|
25
|
+
- version: 7.5.9
|
|
26
|
+
date: 2025-12-30
|
|
27
|
+
changes: Додано команду init
|
|
28
|
+
- version: 7.5.6
|
|
29
|
+
date: 2025-12-27
|
|
30
|
+
changes: Оновлено Layout та додано обробку 404
|
|
31
|
+
- version: 7.3.4
|
|
32
|
+
date: 2025-12-08
|
|
33
|
+
changes: Ініціалізовано history
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
# Перекладіть ваш вебсайт на React Router v7 (File-System Routes) за допомогою Intlayer | Інтернаціоналізація (i18n)
|
|
37
|
+
|
|
38
|
+
Цей посібник демонструє, як інтегрувати **Intlayer** для безшовної інтернаціоналізації в проєктах на React Router v7 з використанням **маршрутизації на основі файлової системи** (`@react-router/fs-routes`) із маршрутизацією, що враховує локаль, підтримкою TypeScript та сучасними практиками розробки.
|
|
39
|
+
|
|
40
|
+
Для клієнтської маршрутизації зверніться до посібника [Intlayer з React Router v7](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/intlayer_with_react_router_v7.md).
|
|
41
|
+
|
|
42
|
+
## Зміст
|
|
43
|
+
|
|
44
|
+
<TOC/>
|
|
45
|
+
|
|
46
|
+
## Що таке Intlayer?
|
|
47
|
+
|
|
48
|
+
**Intlayer** — інноваційна, open-source бібліотека інтернаціоналізації (i18n), створена для спрощення підтримки кількох мов у сучасних вебдодатках.
|
|
49
|
+
|
|
50
|
+
З Intlayer ви можете:
|
|
51
|
+
|
|
52
|
+
- **Легко керувати перекладами** за допомогою декларативних словників на рівні компонентів.
|
|
53
|
+
- **Динамічно локалізувати метадані**, маршрути та контент.
|
|
54
|
+
- **Забезпечити підтримку TypeScript** за допомогою автогенерованих типів, що покращує автодоповнення та виявлення помилок.
|
|
55
|
+
- **Використовувати розширені можливості**, такі як динамічне визначення локалі та її переключення.
|
|
56
|
+
- **Увімкнути маршрутизацію з урахуванням локалі** за допомогою файлово-системної маршрутизації React Router v7.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Покроковий посібник із налаштування Intlayer у додатку React Router v7 з файловою маршрутизацією
|
|
61
|
+
|
|
62
|
+
<Tab defaultTab="video">
|
|
63
|
+
<TabItem label="Відео" value="video">
|
|
64
|
+
|
|
65
|
+
<iframe title="Як перекласти ваш додаток React Router v7 (File-System Routes) за допомогою Intlayer" class="m-auto aspect-16/9 w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/dS9L7uJeak4?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
66
|
+
|
|
67
|
+
</TabItem>
|
|
68
|
+
<TabItem label="Код" value="code">
|
|
69
|
+
|
|
70
|
+
<iframe
|
|
71
|
+
src="https://stackblitz.com/github/aymericzip/intlayer-react-router-v7-fs-routes-template?embed=1&ctl=1&file=intlayer.config.ts"
|
|
72
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
73
|
+
title="Демо CodeSandbox — Як інтернаціоналізувати ваш додаток за допомогою Intlayer"
|
|
74
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
75
|
+
loading="lazy"
|
|
76
|
+
/>
|
|
77
|
+
|
|
78
|
+
</TabItem>
|
|
79
|
+
</Tab>
|
|
80
|
+
|
|
81
|
+
Дивіться [Application Template](https://github.com/aymericzip/intlayer-react-router-v7-fs-routes-template) на GitHub.
|
|
82
|
+
|
|
83
|
+
### Крок 1: Встановлення залежностей
|
|
84
|
+
|
|
85
|
+
Встановіть необхідні пакети, використовуючи обраний менеджер пакетів:
|
|
86
|
+
|
|
87
|
+
```bash packageManager="npm"
|
|
88
|
+
npm install intlayer react-intlayer
|
|
89
|
+
npm install vite-intlayer --save-dev
|
|
90
|
+
npm install @react-router/fs-routes --save-dev
|
|
91
|
+
npx intlayer init
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```bash packageManager="pnpm"
|
|
95
|
+
pnpm add intlayer react-intlayer
|
|
96
|
+
pnpm add vite-intlayer --save-dev
|
|
97
|
+
pnpm add @react-router/fs-routes --save-dev
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```bash packageManager="bun"
|
|
101
|
+
bun add intlayer react-intlayer
|
|
102
|
+
bun add vite-intlayer --dev
|
|
103
|
+
bun add @react-router/fs-routes --dev
|
|
104
|
+
bunx intlayer init
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- **intlayer**
|
|
108
|
+
|
|
109
|
+
Ядро пакета, яке надає інструменти для інтернаціоналізації: керування конфігурацією, перекладу, [оголошення контенту](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/dictionary/content_file.md), транспіляції та [CLI-команд](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/cli/index.md).
|
|
110
|
+
|
|
111
|
+
- **react-intlayer**
|
|
112
|
+
Пакет, який інтегрує Intlayer у React-застосунок. Надає провайдери контексту та хуки для інтернаціоналізації в React.
|
|
113
|
+
|
|
114
|
+
- **vite-intlayer**
|
|
115
|
+
Включає плагін Vite для інтеграції Intlayer з [Vite bundler](https://vite.dev/guide/why.html#why-bundle-for-production), а також middleware для визначення бажаної локалі користувача, управління куками та обробки перенаправлень URL.
|
|
116
|
+
|
|
117
|
+
- **@react-router/fs-routes**
|
|
118
|
+
Пакет, який дозволяє маршрутизацію на основі файлової системи для React Router v7.
|
|
119
|
+
|
|
120
|
+
### Крок 2: Конфігурація вашого проєкту
|
|
121
|
+
|
|
122
|
+
Створіть файл конфігурації для налаштування мов вашого застосунку:
|
|
123
|
+
|
|
124
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
125
|
+
import { type IntlayerConfig, Locales } from "intlayer";
|
|
126
|
+
|
|
127
|
+
const config: IntlayerConfig = {
|
|
128
|
+
internationalization: {
|
|
129
|
+
defaultLocale: Locales.ENGLISH,
|
|
130
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export default config;
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```javascript fileName="intlayer.config.mjs" codeFormat="esm"
|
|
138
|
+
import { Locales } from "intlayer";
|
|
139
|
+
|
|
140
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
141
|
+
// Налаштування Intlayer
|
|
142
|
+
const config = {
|
|
143
|
+
internationalization: {
|
|
144
|
+
defaultLocale: Locales.ENGLISH,
|
|
145
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export default config;
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
|
|
153
|
+
const { Locales } = require("intlayer");
|
|
154
|
+
|
|
155
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
156
|
+
// Налаштування Intlayer
|
|
157
|
+
const config = {
|
|
158
|
+
internationalization: {
|
|
159
|
+
defaultLocale: Locales.ENGLISH,
|
|
160
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
module.exports = config;
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
> За допомогою цього файлу конфігурації ви можете налаштувати локалізовані URL-адреси, перенаправлення в middleware, назви cookie, розташування та розширення ваших декларацій контенту, вимкнути логи Intlayer у консолі та інше. Для повного списку доступних параметрів див. [документацію з конфігурації](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/configuration.md).
|
|
168
|
+
|
|
169
|
+
### Крок 3: Інтегруйте Intlayer у вашу конфігурацію Vite
|
|
170
|
+
|
|
171
|
+
Додайте плагін intlayer до вашої конфігурації:
|
|
172
|
+
|
|
173
|
+
```typescript fileName="vite.config.ts"
|
|
174
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
175
|
+
import { defineConfig } from "vite";
|
|
176
|
+
import { intlayer } from "vite-intlayer";
|
|
177
|
+
import tsconfigPaths from "vite-tsconfig-paths";
|
|
178
|
+
|
|
179
|
+
export default defineConfig({
|
|
180
|
+
plugins: [reactRouter(), tsconfigPaths(), intlayer()],
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
> Плагін Vite `intlayer()` використовується для інтеграції Intlayer з Vite. Він забезпечує побудову файлів декларацій контенту та їх моніторинг у режимі розробки. Він визначає змінні середовища Intlayer у Vite-застосунку. Крім того, він додає аліаси для оптимізації продуктивності.
|
|
185
|
+
|
|
186
|
+
### Крок 4: Налаштування файлових маршрутів React Router v7
|
|
187
|
+
|
|
188
|
+
Налаштуйте конфігурацію маршрутизації для використання файлової маршрутизації за допомогою `flatRoutes`:
|
|
189
|
+
|
|
190
|
+
```typescript fileName="app/routes.ts"
|
|
191
|
+
import type { RouteConfig } from "@react-router/dev/routes";
|
|
192
|
+
import { flatRoutes } from "@react-router/fs-routes";
|
|
193
|
+
import { configuration } from "intlayer";
|
|
194
|
+
|
|
195
|
+
const routes: RouteConfig = flatRoutes({
|
|
196
|
+
// Ігнорувати файли декларацій контенту, щоб їх не обробляли як маршрути
|
|
197
|
+
ignoredRouteFiles: configuration.content.fileExtensions.map(
|
|
198
|
+
(fileExtension) => `**/*${fileExtension}`
|
|
199
|
+
),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
export default routes;
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
> Функція `flatRoutes` з `@react-router/fs-routes` дозволяє використовувати маршрутизацію на основі файлової системи, де структура файлів у директорії `routes/` визначає маршрути вашого застосунку. Опція `ignoredRouteFiles` гарантує, що файли декларації контенту Intlayer (наприклад, `.content.ts` тощо) не розглядатимуться як файли маршрутів.
|
|
206
|
+
|
|
207
|
+
### Крок 5: Створіть файли маршрутів за конвенціями файлової системи
|
|
208
|
+
|
|
209
|
+
При маршрутизації на основі файлової системи використовується плоска конвенція іменування, де крапки (`.`) позначають сегменти шляху, а дужки `()` — необов'язкові сегменти.
|
|
210
|
+
|
|
211
|
+
Створіть наступні файли у директорії `app/routes/`:
|
|
212
|
+
|
|
213
|
+
#### Структура файлів
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
app/
|
|
217
|
+
├── root.tsx # Обгортка Layout для маршрутів локалі
|
|
218
|
+
└──routes/
|
|
219
|
+
├── ($locale)._index.tsx # Головна сторінка (/, /es тощо)
|
|
220
|
+
├── ($locale)._index.content.ts # Вміст головної сторінки
|
|
221
|
+
├── ($locale).about.tsx # Сторінка About (/about, /es/about тощо)
|
|
222
|
+
└── ($locale).about.content.ts # Вміст сторінки About
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The naming conventions:
|
|
226
|
+
|
|
227
|
+
- `($locale)` - Необов'язковий динамічний сегмент для параметра locale
|
|
228
|
+
- `_layout` - Layout-маршрут, який обгортає дочірні маршрути
|
|
229
|
+
- `_index` - Індексний маршрут (відображається на батьківському шляху)
|
|
230
|
+
- `.` (dot) - Розділяє сегменти шляху (наприклад, `($locale).about` → `/:locale?/about`)
|
|
231
|
+
|
|
232
|
+
#### Компонент Layout
|
|
233
|
+
|
|
234
|
+
```tsx fileName="app/root.tsx"
|
|
235
|
+
import { getLocaleFromPath } from "intlayer";
|
|
236
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
237
|
+
import {
|
|
238
|
+
isRouteErrorResponse,
|
|
239
|
+
Meta,
|
|
240
|
+
Outlet,
|
|
241
|
+
Scripts,
|
|
242
|
+
ScrollRestoration,
|
|
243
|
+
useLoaderData,
|
|
244
|
+
} from "react-router";
|
|
245
|
+
|
|
246
|
+
import type { Route } from "./+types/root";
|
|
247
|
+
|
|
248
|
+
import "./app.css";
|
|
249
|
+
|
|
250
|
+
// ... App, links та код ErrorBoundary без змін
|
|
251
|
+
|
|
252
|
+
export async function loader({ request }: Route.LoaderArgs) {
|
|
253
|
+
const locale = getLocaleFromPath(request.url);
|
|
254
|
+
|
|
255
|
+
return { locale };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function Layout({
|
|
259
|
+
children,
|
|
260
|
+
}: { children: React.ReactNode } & Route.ComponentProps) {
|
|
261
|
+
const data = useLoaderData<typeof loader>();
|
|
262
|
+
const { locale } = data ?? {};
|
|
263
|
+
|
|
264
|
+
return (
|
|
265
|
+
<html lang={locale}>
|
|
266
|
+
<head>
|
|
267
|
+
<meta charSet="utf-8" />
|
|
268
|
+
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
|
269
|
+
<Meta />
|
|
270
|
+
<Links />
|
|
271
|
+
</head>
|
|
272
|
+
<body>
|
|
273
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
274
|
+
<ScrollRestoration />
|
|
275
|
+
<Scripts />
|
|
276
|
+
</body>
|
|
277
|
+
</html>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Головна сторінка
|
|
283
|
+
|
|
284
|
+
```tsx fileName="app/routes/($locale)._index.tsx"
|
|
285
|
+
import { getIntlayer, validatePrefix } from "intlayer";
|
|
286
|
+
import { useIntlayer } from "react-intlayer";
|
|
287
|
+
import { data } from "react-router";
|
|
288
|
+
|
|
289
|
+
import { LocaleSwitcher } from "~/components/locale-switcher";
|
|
290
|
+
import { Navbar } from "~/components/navbar";
|
|
291
|
+
|
|
292
|
+
import type { Route } from "./+types/($locale)._index";
|
|
293
|
+
|
|
294
|
+
export const loader = ({ params }: Route.LoaderArgs) => {
|
|
295
|
+
const { locale } = params;
|
|
296
|
+
|
|
297
|
+
const { isValid } = validatePrefix(locale);
|
|
298
|
+
|
|
299
|
+
if (!isValid) {
|
|
300
|
+
throw data("Локаль не підтримується", { status: 404 });
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export const meta: Route.MetaFunction = ({ params }) => {
|
|
305
|
+
const content = getIntlayer("page", params.locale);
|
|
306
|
+
|
|
307
|
+
return [
|
|
308
|
+
{ title: content.title },
|
|
309
|
+
{ content: content.description, name: "description" },
|
|
310
|
+
];
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
export default function Page() {
|
|
314
|
+
const { title, description, aboutLink } = useIntlayer("page");
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<div>
|
|
318
|
+
<h1>{title}</h1>
|
|
319
|
+
<p>{description}</p>
|
|
320
|
+
<nav>
|
|
321
|
+
<LocalizedLink to="/about">{aboutLink}</LocalizedLink>
|
|
322
|
+
</nav>
|
|
323
|
+
</div>
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
#### Сторінка «Про нас»
|
|
329
|
+
|
|
330
|
+
```tsx fileName="app/routes/($locale).about.tsx"
|
|
331
|
+
import { getIntlayer, validatePrefix } from "intlayer";
|
|
332
|
+
import { useIntlayer } from "react-intlayer";
|
|
333
|
+
import { data } from "react-router";
|
|
334
|
+
|
|
335
|
+
import { LocaleSwitcher } from "~/components/locale-switcher";
|
|
336
|
+
import { Navbar } from "~/components/navbar";
|
|
337
|
+
|
|
338
|
+
import type { Route } from "./+types/($locale).about";
|
|
339
|
+
|
|
340
|
+
export const loader = ({ params }: Route.LoaderArgs) => {
|
|
341
|
+
const { locale } = params;
|
|
342
|
+
|
|
343
|
+
const { isValid } = validatePrefix(locale);
|
|
344
|
+
|
|
345
|
+
if (!isValid) {
|
|
346
|
+
throw data("Локаль не підтримується", { status: 404 });
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
export const meta: Route.MetaFunction = ({ params }) => {
|
|
351
|
+
const content = getIntlayer("about", params.locale);
|
|
352
|
+
|
|
353
|
+
return [
|
|
354
|
+
{ title: content.title },
|
|
355
|
+
{ content: content.description, name: "description" },
|
|
356
|
+
];
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
export default function AboutPage() {
|
|
360
|
+
const { title, content, homeLink } = useIntlayer("about");
|
|
361
|
+
|
|
362
|
+
return (
|
|
363
|
+
<div>
|
|
364
|
+
<h1>{title}</h1>
|
|
365
|
+
<p>{content}</p>
|
|
366
|
+
<nav>
|
|
367
|
+
<LocalizedLink to="/">{homeLink}</LocalizedLink>
|
|
368
|
+
</nav>
|
|
369
|
+
</div>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Крок 6: Оголосіть свій контент
|
|
375
|
+
|
|
376
|
+
Створюйте та керуйте деклараціями контенту для зберігання перекладів. Розміщуйте файли контенту поруч із файлами маршрутів:
|
|
377
|
+
|
|
378
|
+
```tsx fileName="app/routes/($locale)._index.content.ts"
|
|
379
|
+
import { t, type Dictionary } from "intlayer";
|
|
380
|
+
|
|
381
|
+
const pageContent = {
|
|
382
|
+
key: "page",
|
|
383
|
+
content: {
|
|
384
|
+
title: t({
|
|
385
|
+
uk: "Ласкаво просимо до React Router v7 + Intlayer",
|
|
386
|
+
en: "Welcome to React Router v7 + Intlayer",
|
|
387
|
+
es: "Bienvenido a React Router v7 + Intlayer",
|
|
388
|
+
fr: "Bienvenue sur React Router v7 + Intlayer",
|
|
389
|
+
}),
|
|
390
|
+
description: t({
|
|
391
|
+
uk: "Створюйте багатомовні додатки легко, використовуючи React Router v7 та Intlayer.",
|
|
392
|
+
en: "Build multilingual applications with ease using React Router v7 and Intlayer.",
|
|
393
|
+
es: "Cree aplicaciones multilingües fácilmente usando React Router v7 y Intlayer.",
|
|
394
|
+
uk: "Створюйте багатомовні додатки легко за допомогою React Router v7 та Intlayer.",
|
|
395
|
+
fr: "Créez des applications multilingues facilement avec React Router v7 et Intlayer.",
|
|
396
|
+
}),
|
|
397
|
+
aboutLink: t({
|
|
398
|
+
uk: "Дізнатися про нас",
|
|
399
|
+
en: "Learn About Us",
|
|
400
|
+
es: "Aprender Sobre Nosotros",
|
|
401
|
+
fr: "En savoir plus sur nous",
|
|
402
|
+
}),
|
|
403
|
+
},
|
|
404
|
+
} satisfies Dictionary;
|
|
405
|
+
|
|
406
|
+
export default pageContent;
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
```tsx fileName="app/routes/($locale).about.content.ts"
|
|
410
|
+
import { t, type Dictionary } from "intlayer";
|
|
411
|
+
|
|
412
|
+
const aboutContent = {
|
|
413
|
+
key: "about",
|
|
414
|
+
content: {
|
|
415
|
+
title: t({
|
|
416
|
+
uk: "Про нас",
|
|
417
|
+
en: "About Us",
|
|
418
|
+
es: "Sobre Nosotros",
|
|
419
|
+
fr: "À propos de nous",
|
|
420
|
+
}),
|
|
421
|
+
content: t({
|
|
422
|
+
uk: "Це вміст сторінки «Про нас».",
|
|
423
|
+
en: "This is the about page content.",
|
|
424
|
+
es: "Este es el contenido de la página de información.",
|
|
425
|
+
fr: "Ceci est le contenu de la page à propos.",
|
|
426
|
+
}),
|
|
427
|
+
homeLink: t({
|
|
428
|
+
uk: "Головна",
|
|
429
|
+
en: "Home",
|
|
430
|
+
es: "Inicio",
|
|
431
|
+
fr: "Accueil",
|
|
432
|
+
}),
|
|
433
|
+
},
|
|
434
|
+
} satisfies Dictionary;
|
|
435
|
+
|
|
436
|
+
export default aboutContent;
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
> Ваші декларації контенту можуть бути визначені будь-де у вашому застосунку, як тільки вони будуть включені до директорії `contentDir` (за замовчуванням `./app`). І відповідати розширенню файлу декларації контенту (за замовчуванням `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
|
|
440
|
+
|
|
441
|
+
> Для детальнішої інформації див. [документацію щодо декларацій контенту](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/dictionary/content_file.md).
|
|
442
|
+
|
|
443
|
+
### Крок 7: Створіть локалізовані компоненти
|
|
444
|
+
|
|
445
|
+
Створіть компонент `LocalizedLink` для навігації з урахуванням локалі:
|
|
446
|
+
|
|
447
|
+
```tsx fileName="app/components/localized-link.tsx"
|
|
448
|
+
import type { FC } from "react";
|
|
449
|
+
|
|
450
|
+
import { getLocalizedUrl, type LocalesValues } from "intlayer";
|
|
451
|
+
import { useLocale } from "react-intlayer";
|
|
452
|
+
import { Link, type LinkProps, type To } from "react-router";
|
|
453
|
+
|
|
454
|
+
const isExternalLink = (to: string) => /^(https?:)?\/\//.test(to);
|
|
455
|
+
|
|
456
|
+
export const locacalizeTo = (to: To, locale: LocalesValues): To => {
|
|
457
|
+
if (typeof to === "string") {
|
|
458
|
+
if (isExternalLink(to)) {
|
|
459
|
+
return to;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return getLocalizedUrl(to, locale);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (isExternalLink(to.pathname ?? "")) {
|
|
466
|
+
return to;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return {
|
|
470
|
+
...to,
|
|
471
|
+
pathname: getLocalizedUrl(to.pathname ?? "", locale),
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
export const LocalizedLink: FC<LinkProps> = (props) => {
|
|
476
|
+
const { locale } = useLocale();
|
|
477
|
+
|
|
478
|
+
return <Link {...props} to={locacalizeTo(props.to, locale)} />;
|
|
479
|
+
};
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
У разі, якщо ви хочете переходити до локалізованих маршрутів, ви можете використати хук `useLocalizedNavigate`:
|
|
483
|
+
|
|
484
|
+
```tsx fileName="app/hooks/useLocalizedNavigate.ts"
|
|
485
|
+
import { useLocale } from "react.intlayer";
|
|
486
|
+
import { type NavigateOptions, type To, useNavigate } from "react-router";
|
|
487
|
+
|
|
488
|
+
import { locacalizeTo } from "~/components/localized-link";
|
|
489
|
+
|
|
490
|
+
export const useLocalizedNavigate = () => {
|
|
491
|
+
const navigate = useNavigate();
|
|
492
|
+
const { locale } = useLocale();
|
|
493
|
+
|
|
494
|
+
const localizedNavigate = (to: To, options?: NavigateOptions) => {
|
|
495
|
+
const localedTo = locacalizeTo(to, locale);
|
|
496
|
+
|
|
497
|
+
navigate(localedTo, options);
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
return localizedNavigate;
|
|
501
|
+
};
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Крок 8: Створіть компонент перемикача локалі
|
|
505
|
+
|
|
506
|
+
Створіть компонент, який дозволить користувачам змінювати мову:
|
|
507
|
+
|
|
508
|
+
```tsx fileName="app/components/locale-switcher.tsx"
|
|
509
|
+
import type { FC } from "react";
|
|
510
|
+
|
|
511
|
+
import {
|
|
512
|
+
getHTMLTextDir,
|
|
513
|
+
getLocaleName,
|
|
514
|
+
getLocalizedUrl,
|
|
515
|
+
getPathWithoutLocale,
|
|
516
|
+
Locales,
|
|
517
|
+
} from "intlayer";
|
|
518
|
+
import { useIntlayer, useLocale } from "react-intlayer";
|
|
519
|
+
import { Link, useLocation } from "react-router";
|
|
520
|
+
|
|
521
|
+
export const LocaleSwitcher: FC = () => {
|
|
522
|
+
const { localeSwitcherLabel } = useIntlayer("locale-switcher");
|
|
523
|
+
const { pathname } = useLocation();
|
|
524
|
+
|
|
525
|
+
const { availableLocales, locale } = useLocale();
|
|
526
|
+
|
|
527
|
+
const pathWithoutLocale = getPathWithoutLocale(pathname);
|
|
528
|
+
|
|
529
|
+
return (
|
|
530
|
+
<ol>
|
|
531
|
+
{availableLocales.map((localeItem) => (
|
|
532
|
+
<li key={localeItem}>
|
|
533
|
+
<Link
|
|
534
|
+
aria-current={localeItem === locale ? "page" : undefined}
|
|
535
|
+
aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeItem)}`}
|
|
536
|
+
reloadDocument // Перезавантажте сторінку, щоб застосувати нову локаль
|
|
537
|
+
to={getLocalizedUrl(pathWithoutLocale, localeItem)}
|
|
538
|
+
>
|
|
539
|
+
<span>
|
|
540
|
+
{/* Локаль — наприклад FR */}
|
|
541
|
+
{localeItem}
|
|
542
|
+
</span>
|
|
543
|
+
<span>
|
|
544
|
+
{/* Мова у власній локалі — наприклад Français */}
|
|
545
|
+
{getLocaleName(localeItem, locale)}
|
|
546
|
+
</span>
|
|
547
|
+
<span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
|
|
548
|
+
{/* Назва мови у поточній локалі — напр., Francés коли поточна локаль встановлена як Locales.SPANISH */}
|
|
549
|
+
{getLocaleName(localeItem)}
|
|
550
|
+
</span>
|
|
551
|
+
<span dir="ltr" lang={Locales.ENGLISH}>
|
|
552
|
+
{/* Назва мови англійською — напр., French */}
|
|
553
|
+
{getLocaleName(localeItem, Locales.ENGLISH)}
|
|
554
|
+
</span>
|
|
555
|
+
</Link>
|
|
556
|
+
</li>
|
|
557
|
+
))}
|
|
558
|
+
</ol>
|
|
559
|
+
);
|
|
560
|
+
};
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
> Щоб дізнатися більше про хук `useLocale`, зверніться до [документації](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/react-intlayer/useLocale.md).
|
|
564
|
+
|
|
565
|
+
### Крок 9: Додати керування атрибутами HTML (необов'язково)
|
|
566
|
+
|
|
567
|
+
Створіть хук для керування атрибутами lang та dir у HTML:
|
|
568
|
+
|
|
569
|
+
```tsx fileName="app/hooks/useI18nHTMLAttributes.tsx"
|
|
570
|
+
import { getHTMLTextDir } from "intlayer";
|
|
571
|
+
import { useEffect } from "react";
|
|
572
|
+
import { useLocale } from "react-intlayer";
|
|
573
|
+
|
|
574
|
+
export const useI18nHTMLAttributes = () => {
|
|
575
|
+
const { locale } = useLocale();
|
|
576
|
+
|
|
577
|
+
useEffect(() => {
|
|
578
|
+
document.documentElement.lang = locale;
|
|
579
|
+
document.documentElement.dir = getHTMLTextDir(locale);
|
|
580
|
+
}, [locale]);
|
|
581
|
+
};
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Цей хук уже використовується в компоненті макета (`($locale)._layout.tsx`), показаному в кроці 5.
|
|
585
|
+
|
|
586
|
+
### Крок 10: Додати middleware (необов'язково)
|
|
587
|
+
|
|
588
|
+
Ви також можете використовувати `intlayerProxy` для додавання server-side routing до вашого додатка. Цей плагін автоматично визначатиме поточну локаль за URL і встановлюватиме відповідний cookie локалі. Якщо локаль явно не вказана, плагін підбере найвідповіднішу локаль на основі мовних налаштувань браузера користувача. Якщо локаль не буде виявлена, він перенаправить на локаль за замовчуванням.
|
|
589
|
+
|
|
590
|
+
> Зауважте, що для використання `intlayerProxy` у production потрібно перемістити пакет `vite-intlayer` з `devDependencies` до `dependencies`.
|
|
591
|
+
|
|
592
|
+
```typescript {3,7} fileName="vite.config.ts"
|
|
593
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
594
|
+
import { defineConfig } from "vite";
|
|
595
|
+
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
596
|
+
import tsconfigPaths from "vite-tsconfig-paths";
|
|
597
|
+
|
|
598
|
+
export default defineConfig({
|
|
599
|
+
plugins: [reactRouter(), tsconfigPaths(), intlayer(), intlayerProxy()],
|
|
600
|
+
});
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## Налаштування TypeScript
|
|
606
|
+
|
|
607
|
+
Intlayer використовує розширення модулів (module augmentation), щоб отримати переваги TypeScript і зробити вашу codebase більш стійкою.
|
|
608
|
+
|
|
609
|
+
Переконайтеся, що ваша конфігурація TypeScript містить автогенеровані типи:
|
|
610
|
+
|
|
611
|
+
```json5 fileName="tsconfig.json"
|
|
612
|
+
{
|
|
613
|
+
// ... ваші існуючі конфігурації
|
|
614
|
+
include: [
|
|
615
|
+
// ... ваші існуючі include
|
|
616
|
+
".intlayer/**/*.ts", // Включити автогенеровані типи
|
|
617
|
+
],
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
## Налаштування Git
|
|
624
|
+
|
|
625
|
+
Рекомендується ігнорувати файли, згенеровані Intlayer. Це дозволяє уникнути їх коміту до вашого Git-репозиторію.
|
|
626
|
+
|
|
627
|
+
Для цього ви можете додати наступні інструкції до вашого файлу `.gitignore`:
|
|
628
|
+
|
|
629
|
+
```plaintext fileName=".gitignore"
|
|
630
|
+
# Ігнорувати файли, згенеровані Intlayer
|
|
631
|
+
.intlayer
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
636
|
+
## Розширення VS Code
|
|
637
|
+
|
|
638
|
+
Щоб покращити ваш досвід розробки з Intlayer, ви можете встановити офіційне **Intlayer VS Code Extension**.
|
|
639
|
+
|
|
640
|
+
[Встановити з VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
|
|
641
|
+
|
|
642
|
+
Це розширення надає:
|
|
643
|
+
|
|
644
|
+
- **Автодоповнення** для ключів перекладу.
|
|
645
|
+
- **Виявлення помилок у реальному часі** щодо відсутніх перекладів.
|
|
646
|
+
- **Вбудовані попередні перегляди** перекладеного вмісту.
|
|
647
|
+
- **Швидкі дії** для простого створення та оновлення перекладів.
|
|
648
|
+
|
|
649
|
+
Для детальнішої інформації про використання розширення зверніться до [документації Intlayer VS Code Extension](https://intlayer.org/doc/vs-code-extension).
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
## Розширені можливості
|
|
654
|
+
|
|
655
|
+
Щоб піти далі, ви можете реалізувати [візуальний редактор](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).
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
## Посилання на документацію
|
|
660
|
+
|
|
661
|
+
- [Документація Intlayer](https://intlayer.org)
|
|
662
|
+
- [Документація React Router v7](https://reactrouter.com/)
|
|
663
|
+
- [Документація React Router fs-routes](https://reactrouter.com/how-to/file-route-conventions)
|
|
664
|
+
- [Хук useIntlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/react-intlayer/useIntlayer.md)
|
|
665
|
+
- [Хук useLocale](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/packages/react-intlayer/useLocale.md)
|
|
666
|
+
- [Оголошення контенту](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/dictionary/content_file.md)
|
|
667
|
+
- [Конфігурація](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/configuration.md)
|
|
668
|
+
|
|
669
|
+
Цей вичерпний посібник містить усе необхідне для інтеграції Intlayer з React Router v7, використовуючи маршрутизацію на основі файлової системи, для повністю інтернаціоналізованого додатку з маршрутизацією з урахуванням локалі та підтримкою TypeScript.
|