@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,456 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-10-05
|
|
3
|
+
updatedAt: 2025-10-05
|
|
4
|
+
title: "Як перекласти Next.js 15 за допомогою next-intl — керівництво з i18n 2026"
|
|
5
|
+
description: "Дізнайтеся, як зробити ваш вебсайт на Next.js 15 (App Router) багатомовним. Дотримуйтеся документації, щоб інтернаціоналізувати (i18n) та перекласти його."
|
|
6
|
+
keywords:
|
|
7
|
+
- Інтернаціоналізація
|
|
8
|
+
- Документація
|
|
9
|
+
- Intlayer
|
|
10
|
+
- Next.js 15
|
|
11
|
+
- next-intl
|
|
12
|
+
- JavaScript
|
|
13
|
+
- React
|
|
14
|
+
slugs:
|
|
15
|
+
- doc
|
|
16
|
+
- next-intl
|
|
17
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-next-intl-template
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Перекладіть ваш вебсайт Next.js 15 з next-intl за допомогою Intlayer | Інтернаціоналізація (i18n)
|
|
21
|
+
|
|
22
|
+
Цей посібник проведе вас через кращі практики next-intl у застосунку Next.js 15 (App Router) і покаже, як накласти Intlayer зверху для надійного керування перекладами та автоматизації.
|
|
23
|
+
|
|
24
|
+
Дивіться порівняння в [next-i18next vs next-intl vs Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md).
|
|
25
|
+
|
|
26
|
+
- Для junior-розробників: дотримуйтесь покрокових розділів, щоб отримати працездатний мультимовний додаток.
|
|
27
|
+
- Для mid-level розробників: зверніть увагу на оптимізацію payload та розділення server/client.
|
|
28
|
+
- Для senior-розробників: зверніть увагу на static generation, middleware, інтеграцію SEO та automation hooks.
|
|
29
|
+
|
|
30
|
+
Що ми розглянемо:
|
|
31
|
+
|
|
32
|
+
- Налаштування та структура файлів
|
|
33
|
+
- Оптимізація завантаження повідомлень
|
|
34
|
+
- Використання клієнтських та серверних компонентів
|
|
35
|
+
- Метадані, sitemap, robots для SEO
|
|
36
|
+
- Middleware для маршрутизації локалі
|
|
37
|
+
- Додавання Intlayer поверх (CLI та автоматизація)
|
|
38
|
+
|
|
39
|
+
## Налаштуйте свій додаток за допомогою next-intl
|
|
40
|
+
|
|
41
|
+
Встановіть залежності next-intl:
|
|
42
|
+
|
|
43
|
+
```bash packageManager="npm"
|
|
44
|
+
npm install next-intl
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash packageManager="pnpm"
|
|
48
|
+
pnpm add next-intl
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```bash packageManager="yarn"
|
|
52
|
+
yarn add next-intl
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```bash packageManager="bun"
|
|
56
|
+
bun add next-intl
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
.
|
|
61
|
+
├── locales
|
|
62
|
+
│ ├── en
|
|
63
|
+
│ │ ├── common.json
|
|
64
|
+
│ │ └── about.json
|
|
65
|
+
│ ├── fr
|
|
66
|
+
│ │ ├── common.json
|
|
67
|
+
│ │ └── about.json
|
|
68
|
+
│ └── es
|
|
69
|
+
│ ├── common.json
|
|
70
|
+
│ └── about.json
|
|
71
|
+
└── src
|
|
72
|
+
├── i18n.ts
|
|
73
|
+
├── middleware.ts
|
|
74
|
+
├── app
|
|
75
|
+
│ └── [locale]
|
|
76
|
+
│ ├── layout.tsx
|
|
77
|
+
│ └── about
|
|
78
|
+
│ └── page.tsx
|
|
79
|
+
└── components
|
|
80
|
+
├── ClientComponentExample.tsx
|
|
81
|
+
└── ServerComponent.tsx
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Налаштування та завантаження контенту
|
|
85
|
+
|
|
86
|
+
Завантажуйте лише ті простори імен, які потрібні вашим маршрутам, і перевіряйте локалі на ранньому етапі. За можливості тримайте серверні компоненти синхронними та надсилайте на клієнт лише необхідні повідомлення.
|
|
87
|
+
|
|
88
|
+
```tsx fileName="src/i18n.ts"
|
|
89
|
+
import { getRequestConfig } from "next-intl/server";
|
|
90
|
+
import { notFound } from "next/navigation";
|
|
91
|
+
|
|
92
|
+
export const locales = ["en", "fr", "es"] as const;
|
|
93
|
+
export const defaultLocale = "en" as const;
|
|
94
|
+
|
|
95
|
+
async function loadMessages(locale: string) {
|
|
96
|
+
// Завантажуйте лише ті namespaces, які потрібні вашим layout/pages
|
|
97
|
+
const [common, about] = await Promise.all([
|
|
98
|
+
import(`../locales/${locale}/common.json`).then((m) => m.default),
|
|
99
|
+
import(`../locales/${locale}/about.json`).then((m) => m.default),
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
return { common, about } as const;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export default getRequestConfig(async ({ locale }) => {
|
|
106
|
+
if (!locales.includes(locale as any)) notFound();
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
messages: await loadMessages(locale),
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```tsx fileName="src/app/[locale]/layout.tsx"
|
|
115
|
+
import type { ReactNode } from "react";
|
|
116
|
+
import { locales } from "@/i18n";
|
|
117
|
+
import {
|
|
118
|
+
getLocaleDirection,
|
|
119
|
+
unstable_setRequestLocale,
|
|
120
|
+
} from "next-intl/server";
|
|
121
|
+
|
|
122
|
+
export const dynamic = "force-static";
|
|
123
|
+
|
|
124
|
+
export function generateStaticParams() {
|
|
125
|
+
return locales.map((locale) => ({ locale }));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default async function LocaleLayout({
|
|
129
|
+
children,
|
|
130
|
+
params,
|
|
131
|
+
}: {
|
|
132
|
+
children: ReactNode;
|
|
133
|
+
params: { locale: string };
|
|
134
|
+
}) {
|
|
135
|
+
const { locale } = params;
|
|
136
|
+
|
|
137
|
+
// Встановіть активну локаль запиту для цього серверного рендерингу (RSC)
|
|
138
|
+
unstable_setRequestLocale(locale);
|
|
139
|
+
|
|
140
|
+
const dir = getLocaleDirection(locale);
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<html lang={locale} dir={dir}>
|
|
144
|
+
<body>{children}</body>
|
|
145
|
+
</html>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```tsx fileName="src/app/[locale]/about/page.tsx"
|
|
151
|
+
import { getTranslations, getMessages, getFormatter } from "next-intl/server";
|
|
152
|
+
import { NextIntlClientProvider } from "next-intl";
|
|
153
|
+
import pick from "lodash/pick";
|
|
154
|
+
import ServerComponent from "@/components/ServerComponent";
|
|
155
|
+
import ClientComponentExample from "@/components/ClientComponentExample";
|
|
156
|
+
|
|
157
|
+
export const dynamic = "force-static";
|
|
158
|
+
|
|
159
|
+
export default async function AboutPage({
|
|
160
|
+
params,
|
|
161
|
+
}: {
|
|
162
|
+
params: { locale: string };
|
|
163
|
+
}) {
|
|
164
|
+
const { locale } = params;
|
|
165
|
+
|
|
166
|
+
// Повідомлення завантажуються на сервері. Передавайте клієнту лише те, що потрібно.
|
|
167
|
+
const messages = await getMessages();
|
|
168
|
+
const clientMessages = pick(messages, ["common", "about"]);
|
|
169
|
+
|
|
170
|
+
// Переклади та форматування, що виконуються виключно на сервері
|
|
171
|
+
const tAbout = await getTranslations("about");
|
|
172
|
+
const tCounter = await getTranslations("about.counter");
|
|
173
|
+
const format = await getFormatter();
|
|
174
|
+
|
|
175
|
+
const initialFormattedCount = format.number(0);
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<NextIntlClientProvider locale={locale} messages={clientMessages}>
|
|
179
|
+
<main>
|
|
180
|
+
<h1>{tAbout("title")}</h1>
|
|
181
|
+
<ClientComponentExample />
|
|
182
|
+
<ServerComponent
|
|
183
|
+
formattedCount={initialFormattedCount}
|
|
184
|
+
label={tCounter("label")}
|
|
185
|
+
increment={tCounter("increment")}
|
|
186
|
+
/>
|
|
187
|
+
</main>
|
|
188
|
+
</NextIntlClientProvider>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Використання в клієнтському компоненті
|
|
194
|
+
|
|
195
|
+
Розглянемо приклад клієнтського компонента, який відображає лічильник.
|
|
196
|
+
|
|
197
|
+
**Переклади (структура збережена; завантажте їх у повідомлення next-intl на свій розсуд)**
|
|
198
|
+
|
|
199
|
+
```json fileName="locales/en/about.json"
|
|
200
|
+
{
|
|
201
|
+
"counter": {
|
|
202
|
+
"label": "Лічильник",
|
|
203
|
+
"increment": "Збільшити"
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```json fileName="locales/fr/about.json"
|
|
209
|
+
{
|
|
210
|
+
"counter": {
|
|
211
|
+
"label": "Лічильник",
|
|
212
|
+
"increment": "Збільшити"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Клієнтський компонент**
|
|
218
|
+
|
|
219
|
+
```tsx fileName="src/components/ClientComponentExample.tsx"
|
|
220
|
+
"use client";
|
|
221
|
+
|
|
222
|
+
import React, { useState } from "react";
|
|
223
|
+
import { useTranslations, useFormatter } from "next-intl";
|
|
224
|
+
|
|
225
|
+
const ClientComponentExample = () => {
|
|
226
|
+
// Задаємо область безпосередньо для вкладеного об'єкта
|
|
227
|
+
const t = useTranslations("about.counter");
|
|
228
|
+
const format = useFormatter();
|
|
229
|
+
const [count, setCount] = useState(0);
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
<div>
|
|
233
|
+
<p>{format.number(count)}</p>
|
|
234
|
+
<button
|
|
235
|
+
aria-label={t("label")}
|
|
236
|
+
onClick={() => setCount((count) => count + 1)}
|
|
237
|
+
>
|
|
238
|
+
{t("increment")}
|
|
239
|
+
</button>
|
|
240
|
+
</div>
|
|
241
|
+
);
|
|
242
|
+
};
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
> Не забудьте додати повідомлення "about" у клієнтські повідомлення сторінки
|
|
246
|
+
> (включайте лише ті простори імен, які справді потрібні вашому клієнтському компоненту).
|
|
247
|
+
|
|
248
|
+
### Використання в серверному компоненті
|
|
249
|
+
|
|
250
|
+
Цей UI-компонент є серверним компонентом і може рендеритися під клієнтським компонентом (page → client → server). Зберігайте його синхронним, передаючи попередньо обчислені рядки.
|
|
251
|
+
|
|
252
|
+
```tsx fileName="src/components/ServerComponent.tsx"
|
|
253
|
+
type ServerComponentProps = {
|
|
254
|
+
formattedCount: string;
|
|
255
|
+
label: string;
|
|
256
|
+
increment: string;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const ServerComponent = ({
|
|
260
|
+
formattedCount,
|
|
261
|
+
label,
|
|
262
|
+
increment,
|
|
263
|
+
}: ServerComponentProps) => {
|
|
264
|
+
return (
|
|
265
|
+
<div>
|
|
266
|
+
<p>{formattedCount}</p>
|
|
267
|
+
<button aria-label={label}>{increment}</button>
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
|
+
};
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Примітки:
|
|
274
|
+
|
|
275
|
+
- Обчислюйте `formattedCount` на сервері (наприклад, `const initialFormattedCount = format.number(0)`).
|
|
276
|
+
- Уникайте передачі функцій або несеріалізованих об'єктів у server components.
|
|
277
|
+
|
|
278
|
+
```tsx fileName="src/app/[locale]/about/layout.tsx"
|
|
279
|
+
import type { Metadata } from "next";
|
|
280
|
+
import { locales, defaultLocale } from "@/i18n";
|
|
281
|
+
import { getTranslations } from "next-intl/server";
|
|
282
|
+
|
|
283
|
+
function localizedPath(locale: string, path: string) {
|
|
284
|
+
return locale === defaultLocale ? path : "/" + locale + path;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export async function generateMetadata({
|
|
288
|
+
params,
|
|
289
|
+
}: {
|
|
290
|
+
params: { locale: string };
|
|
291
|
+
}): Promise<Metadata> {
|
|
292
|
+
const { locale } = params;
|
|
293
|
+
const t = await getTranslations({ locale, namespace: "about" });
|
|
294
|
+
|
|
295
|
+
const url = "/about";
|
|
296
|
+
const languages = Object.fromEntries(
|
|
297
|
+
locales.map((locale) => [locale, localizedPath(locale, url)])
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
title: t("title"),
|
|
302
|
+
description: t("description"),
|
|
303
|
+
alternates: {
|
|
304
|
+
canonical: localizedPath(locale, url),
|
|
305
|
+
languages: { ...languages, "x-default": url },
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// ... Rest of the page code
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
```tsx fileName="src/app/sitemap.ts"
|
|
314
|
+
import type { MetadataRoute } from "next";
|
|
315
|
+
import { locales, defaultLocale } from "@/i18n";
|
|
316
|
+
|
|
317
|
+
const origin = "https://example.com";
|
|
318
|
+
|
|
319
|
+
const formatterLocalizedPath = (locale: string, path: string) =>
|
|
320
|
+
locale === defaultLocale ? origin + path : origin + "/" + locale + path;
|
|
321
|
+
|
|
322
|
+
export default function sitemap(): MetadataRoute.Sitemap {
|
|
323
|
+
const aboutLanguages = Object.fromEntries(
|
|
324
|
+
locales.map((l) => [l, formatterLocalizedPath(l, "/about")])
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
return [
|
|
328
|
+
{
|
|
329
|
+
url: formatterLocalizedPath(defaultLocale, "/about"),
|
|
330
|
+
lastModified: new Date(),
|
|
331
|
+
changeFrequency: "monthly",
|
|
332
|
+
priority: 0.7,
|
|
333
|
+
alternates: { languages: aboutLanguages },
|
|
334
|
+
},
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
```tsx fileName="src/app/robots.ts"
|
|
340
|
+
import type { MetadataRoute } from "next";
|
|
341
|
+
import { locales, defaultLocale } from "@/i18n";
|
|
342
|
+
|
|
343
|
+
const origin = "https://example.com";
|
|
344
|
+
const withAllLocales = (path: string) => [
|
|
345
|
+
path,
|
|
346
|
+
...locales
|
|
347
|
+
.filter((locale) => locale !== defaultLocale)
|
|
348
|
+
.map((locale) => "/" + locale + path),
|
|
349
|
+
];
|
|
350
|
+
|
|
351
|
+
export default function robots(): MetadataRoute.Robots {
|
|
352
|
+
const disallow = [
|
|
353
|
+
...withAllLocales("/dashboard"),
|
|
354
|
+
...withAllLocales("/admin"),
|
|
355
|
+
];
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
rules: { userAgent: "*", allow: ["/"], disallow },
|
|
359
|
+
host: origin,
|
|
360
|
+
sitemap: origin + "/sitemap.xml",
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Middleware для маршрутизації локалі
|
|
366
|
+
|
|
367
|
+
Додайте middleware для виявлення локалі та маршрутизації:
|
|
368
|
+
|
|
369
|
+
```ts fileName="src/middleware.ts"
|
|
370
|
+
import createMiddleware from "next-intl/middleware";
|
|
371
|
+
import { locales, defaultLocale } from "@/i18n";
|
|
372
|
+
|
|
373
|
+
export default createMiddleware({
|
|
374
|
+
locales: [...locales],
|
|
375
|
+
defaultLocale,
|
|
376
|
+
localeDetection: true,
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
export const config = {
|
|
380
|
+
// Пропустити API, внутрішні компоненти Next і статичні файли
|
|
381
|
+
matcher: ["/((?!api|_next|.*\\..*).*)"],
|
|
382
|
+
};
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Найкращі практики
|
|
386
|
+
|
|
387
|
+
- **Встановіть атрибути `lang` та `dir` для html**: У `src/app/[locale]/layout.tsx` обчисліть `dir` за допомогою `getLocaleDirection(locale)` і встановіть `<html lang={locale} dir={dir}>`.
|
|
388
|
+
- **Розділяйте повідомлення за просторами імен**: Організуйте JSON за локалями та просторами імен (наприклад, `common.json`, `about.json`).
|
|
389
|
+
- **Мінімізуйте навантаження на клієнт**: На сторінках надсилайте в `NextIntlClientProvider` лише необхідні простори імен (наприклад, `pick(messages, ['common', 'about'])`).
|
|
390
|
+
- **Віддавайте перевагу статичним сторінкам**: Експортуйте `export const dynamic = 'force-static'` та генеруйте статичні параметри для всіх `locales`.
|
|
391
|
+
- **Синхронні серверні компоненти**: Передавайте попередньо обчислені рядки (перекладені підписи, відформатовані числа) замість асинхронних викликів або несеріалізованих функцій.
|
|
392
|
+
|
|
393
|
+
## Впровадження Intlayer поверх next-intl
|
|
394
|
+
|
|
395
|
+
Встановіть залежності intlayer:
|
|
396
|
+
|
|
397
|
+
```bash packageManager="npm"
|
|
398
|
+
npm install intlayer @intlayer/sync-json-plugin --save-dev
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
```bash packageManager="yarn"
|
|
402
|
+
yarn add intlayer @intlayer/sync-json-plugin --dev
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
```bash packageManager="pnpm"
|
|
406
|
+
pnpm add intlayer @intlayer/sync-json-plugin --save-dev
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
```bash packageManager="bun"
|
|
410
|
+
bun add intlayer @intlayer/sync-json-plugin --dev
|
|
411
|
+
bunx intlayer init
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Створіть файл конфігурації intlayer:
|
|
415
|
+
|
|
416
|
+
```tsx fileName="intlayer.config.ts"
|
|
417
|
+
import { type IntlayerConfig, Locales } from "intlayer";
|
|
418
|
+
import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
419
|
+
|
|
420
|
+
const config: IntlayerConfig = {
|
|
421
|
+
internationalization: {
|
|
422
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
423
|
+
defaultLocale: Locales.ENGLISH,
|
|
424
|
+
},
|
|
425
|
+
ai: {
|
|
426
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
427
|
+
},
|
|
428
|
+
plugins: [
|
|
429
|
+
// Підтримуйте структуру папок для кожного namespace синхронізованою з Intlayer
|
|
430
|
+
syncJSON({
|
|
431
|
+
format: "icu",
|
|
432
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
433
|
+
}),
|
|
434
|
+
],
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
export default config;
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Додайте скрипти в `package.json`:
|
|
441
|
+
|
|
442
|
+
```json fileName="package.json"
|
|
443
|
+
{
|
|
444
|
+
"scripts": {
|
|
445
|
+
"i18n:fill": "intlayer fill",
|
|
446
|
+
"i18n:test": "intlayer test"
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Примітки:
|
|
452
|
+
|
|
453
|
+
- `intlayer fill`: використовує вашого AI-провайдера для заповнення відсутніх перекладів на основі налаштованих локалей.
|
|
454
|
+
- `intlayer test`: перевіряє на наявність відсутніх/недійсних перекладів (використовуйте у CI).
|
|
455
|
+
|
|
456
|
+
Ви можете налаштувати аргументи та провайдерів; див. [Intlayer CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/cli/index.md).
|