@intlayer/docs 7.0.7 → 7.0.8
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/i18n_using_next-i18next.md +1068 -0
- package/blog/ar/i18n_using_next-intl.md +768 -0
- package/blog/ar/intlayer_with_react-intl.md +0 -4
- package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +5 -4
- package/blog/de/i18n_using_next-i18next.md +1107 -0
- package/blog/de/i18n_using_next-intl.md +760 -0
- package/blog/de/intlayer_with_react-intl.md +0 -4
- package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/en/i18n_using_next-i18next.md +1073 -0
- package/blog/en/i18n_using_next-intl.md +757 -0
- package/blog/en/intlayer_with_i18next.md +71 -8
- package/blog/en/intlayer_with_next-i18next.md +71 -8
- package/blog/en/intlayer_with_next-intl.md +71 -8
- package/blog/en/intlayer_with_react-i18next.md +69 -8
- package/blog/en/intlayer_with_react-intl.md +68 -9
- package/blog/en/intlayer_with_vue-i18n.md +68 -7
- package/blog/en/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
- package/blog/en/vue-i18n_vs_intlayer.md +2 -0
- package/blog/en-GB/i18n_using_next-i18next.md +1074 -0
- package/blog/en-GB/i18n_using_next-intl.md +757 -0
- package/blog/en-GB/intlayer_with_i18next.md +15 -6
- package/blog/en-GB/intlayer_with_next-i18next.md +16 -6
- package/blog/en-GB/intlayer_with_next-intl.md +16 -6
- package/blog/en-GB/intlayer_with_react-i18next.md +16 -7
- package/blog/en-GB/intlayer_with_react-intl.md +14 -9
- package/blog/en-GB/intlayer_with_vue-i18n.md +16 -7
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/en-GB/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
- package/blog/en-GB/vue-i18n_vs_intlayer.md +2 -0
- package/blog/es/i18n_using_next-i18next.md +1066 -0
- package/blog/es/i18n_using_next-intl.md +757 -0
- package/blog/es/intlayer_with_react-intl.md +0 -4
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/fr/i18n_using_next-i18next.md +1078 -0
- package/blog/fr/i18n_using_next-intl.md +759 -0
- package/blog/fr/intlayer_with_react-intl.md +0 -4
- package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/hi/i18n_using_next-i18next.md +1068 -0
- package/blog/hi/i18n_using_next-intl.md +758 -0
- package/blog/hi/intlayer_with_react-intl.md +0 -4
- package/blog/hi/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/id/i18n_using_next-i18next.md +1078 -0
- package/blog/id/i18n_using_next-intl.md +757 -0
- package/blog/id/index.md +69 -0
- package/blog/id/internationalization_and_SEO.md +364 -0
- package/blog/id/intlayer_with_react-intl.md +0 -4
- package/blog/id/list_i18n_technologies/CMS/drupal.md +143 -0
- package/blog/id/list_i18n_technologies/CMS/wix.md +167 -0
- package/blog/id/list_i18n_technologies/CMS/wordpress.md +188 -0
- package/blog/id/list_i18n_technologies/frameworks/angular.md +125 -0
- package/blog/id/list_i18n_technologies/frameworks/flutter.md +150 -0
- package/blog/id/list_i18n_technologies/frameworks/react-native.md +217 -0
- package/blog/id/list_i18n_technologies/frameworks/react.md +155 -0
- package/blog/id/list_i18n_technologies/frameworks/svelte.md +131 -0
- package/blog/id/list_i18n_technologies/frameworks/vue.md +130 -0
- package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +1500 -0
- package/blog/id/nextjs-multilingual-seo-comparison.md +361 -0
- package/blog/id/rag_powered_documentation_assistant.md +288 -0
- package/blog/id/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
- package/blog/id/vue-i18n_vs_intlayer.md +278 -0
- package/blog/id/what_is_internationalization.md +166 -0
- package/blog/it/i18n_using_next-i18next.md +1078 -0
- package/blog/it/i18n_using_next-intl.md +758 -0
- package/blog/it/intlayer_with_react-intl.md +0 -4
- package/blog/it/react-i18next_vs_react-intl_vs_intlayer.md +4 -0
- package/blog/it/vue-i18n_vs_intlayer.md +2 -0
- package/blog/ja/i18n_using_next-i18next.md +1078 -0
- package/blog/ja/i18n_using_next-intl.md +758 -0
- package/blog/ja/intlayer_with_react-intl.md +0 -4
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/ko/i18n_using_next-i18next.md +1075 -0
- package/blog/ko/i18n_using_next-intl.md +759 -0
- package/blog/ko/intlayer_with_react-intl.md +0 -4
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/pl/i18n_using_next-i18next.md +1078 -0
- package/blog/pl/i18n_using_next-intl.md +758 -0
- package/blog/pl/index.md +69 -0
- package/blog/pl/internationalization_and_SEO.md +363 -0
- package/blog/pl/intlayer_with_react-intl.md +0 -4
- package/blog/pl/list_i18n_technologies/CMS/drupal.md +143 -0
- package/blog/pl/list_i18n_technologies/CMS/wix.md +167 -0
- package/blog/pl/list_i18n_technologies/CMS/wordpress.md +196 -0
- package/blog/pl/list_i18n_technologies/frameworks/angular.md +125 -0
- package/blog/pl/list_i18n_technologies/frameworks/flutter.md +151 -0
- package/blog/pl/list_i18n_technologies/frameworks/react-native.md +217 -0
- package/blog/pl/list_i18n_technologies/frameworks/react.md +155 -0
- package/blog/pl/list_i18n_technologies/frameworks/svelte.md +131 -0
- package/blog/pl/list_i18n_technologies/frameworks/vue.md +130 -0
- package/blog/pl/next-i18next_vs_next-intl_vs_intlayer.md +1501 -0
- package/blog/pl/nextjs-multilingual-seo-comparison.md +362 -0
- package/blog/pl/rag_powered_documentation_assistant.md +288 -0
- package/blog/pl/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
- package/blog/pl/vue-i18n_vs_intlayer.md +278 -0
- package/blog/pl/what_is_internationalization.md +167 -0
- package/blog/pt/i18n_using_next-i18next.md +1067 -0
- package/blog/pt/i18n_using_next-intl.md +760 -0
- package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/ru/i18n_using_next-i18next.md +1106 -0
- package/blog/ru/i18n_using_next-intl.md +759 -0
- package/blog/ru/intlayer_with_react-intl.md +0 -4
- package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/tr/i18n_using_next-i18next.md +1078 -0
- package/blog/tr/i18n_using_next-intl.md +760 -0
- package/blog/tr/intlayer_with_react-intl.md +0 -4
- package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/tr/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
- package/blog/tr/vue-i18n_vs_intlayer.md +2 -0
- package/blog/vi/i18n_using_next-i18next.md +1080 -0
- package/blog/vi/i18n_using_next-intl.md +758 -0
- package/blog/vi/index.md +69 -0
- package/blog/vi/internationalization_and_SEO.md +363 -0
- package/blog/vi/intlayer_with_react-intl.md +0 -4
- package/blog/vi/list_i18n_technologies/CMS/drupal.md +143 -0
- package/blog/vi/list_i18n_technologies/CMS/wix.md +167 -0
- package/blog/vi/list_i18n_technologies/CMS/wordpress.md +188 -0
- package/blog/vi/list_i18n_technologies/frameworks/angular.md +125 -0
- package/blog/vi/list_i18n_technologies/frameworks/flutter.md +150 -0
- package/blog/vi/list_i18n_technologies/frameworks/react-native.md +217 -0
- package/blog/vi/list_i18n_technologies/frameworks/react.md +155 -0
- package/blog/vi/list_i18n_technologies/frameworks/svelte.md +131 -0
- package/blog/vi/list_i18n_technologies/frameworks/vue.md +130 -0
- package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +1520 -0
- package/blog/vi/nextjs-multilingual-seo-comparison.md +362 -0
- package/blog/vi/rag_powered_documentation_assistant.md +288 -0
- package/blog/vi/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
- package/blog/vi/vue-i18n_vs_intlayer.md +278 -0
- package/blog/vi/what_is_internationalization.md +168 -0
- package/blog/zh/i18n_using_next-i18next.md +1105 -0
- package/blog/zh/i18n_using_next-intl.md +758 -0
- package/blog/zh/intlayer_with_react-intl.md +0 -4
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/zh/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
- package/dist/cjs/common.cjs +0 -4
- package/dist/cjs/common.cjs.map +1 -1
- package/dist/cjs/generated/blog.entry.cjs +38 -6
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +0 -6
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +0 -6
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +0 -6
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +38 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts +2 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/docs/ar/component_i18n.md +1 -1
- package/docs/ar/configuration.md +6 -0
- package/docs/ar/intlayer_cli.md +8 -3
- package/docs/ar/intlayer_with_next-i18next.md +619 -0
- package/docs/ar/intlayer_with_next-intl.md +446 -0
- package/docs/ar/intlayer_with_nextjs_16.md +21 -0
- package/docs/ar/intlayer_with_tanstack.md +4 -0
- package/docs/ar/intlayer_with_vite+react.md +4 -0
- package/docs/de/component_i18n.md +1 -1
- package/docs/de/configuration.md +6 -0
- package/docs/de/intlayer_cli.md +8 -3
- package/docs/de/intlayer_with_next-i18next.md +627 -0
- package/docs/de/intlayer_with_next-intl.md +451 -0
- package/docs/de/intlayer_with_nextjs_16.md +21 -0
- package/docs/de/intlayer_with_tanstack.md +4 -0
- package/docs/de/intlayer_with_vite+react.md +4 -0
- package/docs/en/component_i18n.md +1 -1
- package/docs/en/intlayer_cli.md +8 -1
- package/docs/en/intlayer_with_astro.md +10 -2
- package/docs/en/intlayer_with_create_react_app.md +8 -0
- package/docs/en/intlayer_with_lynx+react.md +8 -0
- package/docs/en/intlayer_with_nestjs.md +10 -0
- package/docs/en/intlayer_with_nextjs_14.md +10 -2
- package/docs/en/intlayer_with_nextjs_15.md +21 -4
- package/docs/en/intlayer_with_nextjs_16.md +17 -0
- package/docs/en/intlayer_with_nuxt.md +8 -0
- package/docs/en/intlayer_with_react_native+expo.md +10 -2
- package/docs/en/intlayer_with_react_router_v7.md +8 -0
- package/docs/en/intlayer_with_tanstack.md +10 -0
- package/docs/en/intlayer_with_vite+preact.md +10 -2
- package/docs/en/intlayer_with_vite+react.md +21 -4
- package/docs/en/intlayer_with_vite+vue.md +10 -2
- package/docs/en-GB/component_i18n.md +1 -1
- package/docs/en-GB/configuration.md +6 -0
- package/docs/en-GB/intlayer_cli.md +8 -3
- package/docs/en-GB/intlayer_with_angular.md +4 -4
- package/docs/en-GB/intlayer_with_express.md +4 -4
- package/docs/en-GB/intlayer_with_lynx+react.md +12 -12
- package/{blog/en/_intlayer_with_next-i18next.md → docs/en-GB/intlayer_with_next-i18next.md} +241 -42
- package/{blog/en/_intlayer_with_next-intl.md → docs/en-GB/intlayer_with_next-intl.md} +144 -29
- package/docs/en-GB/intlayer_with_nextjs_16.md +21 -0
- package/docs/en-GB/intlayer_with_tanstack.md +5 -1
- package/docs/en-GB/intlayer_with_vite+react.md +4 -0
- package/docs/en-GB/packages/next-intlayer/t.md +2 -2
- package/docs/es/component_i18n.md +1 -1
- package/docs/es/configuration.md +6 -0
- package/docs/es/intlayer_cli.md +8 -3
- package/docs/es/intlayer_with_next-i18next.md +628 -0
- package/docs/es/intlayer_with_next-intl.md +446 -0
- package/docs/es/intlayer_with_nextjs_16.md +21 -0
- package/docs/es/intlayer_with_tanstack.md +4 -0
- package/docs/es/intlayer_with_vite+react.md +4 -0
- package/docs/fr/configuration.md +6 -0
- package/docs/fr/intlayer_cli.md +8 -3
- package/docs/fr/intlayer_with_next-i18next.md +628 -0
- package/docs/fr/intlayer_with_next-intl.md +446 -0
- package/docs/fr/intlayer_with_nextjs_16.md +23 -2
- package/docs/fr/intlayer_with_tanstack.md +4 -0
- package/docs/fr/intlayer_with_vite+react.md +4 -0
- package/docs/hi/component_i18n.md +1 -1
- package/docs/hi/configuration.md +6 -0
- package/docs/hi/intlayer_cli.md +8 -0
- package/docs/hi/intlayer_with_next-i18next.md +628 -0
- package/docs/hi/intlayer_with_next-intl.md +446 -0
- package/docs/hi/intlayer_with_nextjs_16.md +21 -0
- package/docs/hi/intlayer_with_tanstack.md +4 -0
- package/docs/hi/intlayer_with_vite+react.md +4 -0
- package/docs/id/CI_CD.md +198 -0
- package/docs/id/autoFill.md +284 -0
- package/docs/id/component_i18n.md +186 -0
- package/docs/id/configuration.md +710 -0
- package/docs/id/dictionary/condition.md +231 -0
- package/docs/id/dictionary/content_file.md +1092 -0
- package/docs/id/dictionary/enumeration.md +245 -0
- package/docs/id/dictionary/file.md +237 -0
- package/docs/id/dictionary/function_fetching.md +214 -0
- package/docs/id/dictionary/gender.md +273 -0
- package/docs/id/dictionary/insertion.md +192 -0
- package/docs/id/dictionary/markdown.md +381 -0
- package/docs/id/dictionary/nesting.md +273 -0
- package/docs/id/dictionary/translation.md +310 -0
- package/docs/id/formatters.md +596 -0
- package/docs/id/how_works_intlayer.md +256 -0
- package/docs/id/index.md +176 -0
- package/docs/id/interest_of_intlayer.md +293 -0
- package/docs/id/intlayer_CMS.md +549 -0
- package/docs/id/intlayer_cli.md +850 -0
- package/docs/id/intlayer_visual_editor.md +288 -0
- package/docs/id/intlayer_with_angular.md +694 -0
- package/docs/id/intlayer_with_astro.md +252 -0
- package/docs/id/intlayer_with_create_react_app.md +1233 -0
- package/docs/id/intlayer_with_express.md +411 -0
- package/docs/id/intlayer_with_lynx+react.md +518 -0
- package/docs/id/intlayer_with_nestjs.md +272 -0
- package/docs/id/intlayer_with_next-i18next.md +628 -0
- package/docs/id/intlayer_with_next-intl.md +446 -0
- package/docs/id/intlayer_with_nextjs_14.md +1617 -0
- package/docs/id/intlayer_with_nextjs_15.md +1698 -0
- package/docs/id/intlayer_with_nextjs_16.md +21 -0
- package/docs/id/intlayer_with_nextjs_page_router.md +1478 -0
- package/docs/id/intlayer_with_nuxt.md +808 -0
- package/docs/id/intlayer_with_react_native+expo.md +699 -0
- package/docs/id/intlayer_with_react_router_v7.md +496 -0
- package/docs/id/intlayer_with_tanstack.md +564 -0
- package/docs/id/intlayer_with_vite+preact.md +1737 -0
- package/docs/id/intlayer_with_vite+react.md +1413 -0
- package/docs/id/intlayer_with_vite+solid.md +289 -0
- package/docs/id/intlayer_with_vite+svelte.md +289 -0
- package/docs/id/intlayer_with_vite+vue.md +1088 -0
- package/docs/id/introduction.md +218 -0
- package/docs/id/locale_mapper.md +242 -0
- package/docs/id/mcp_server.md +211 -0
- package/docs/id/packages/express-intlayer/t.md +458 -0
- package/docs/id/packages/intlayer/getConfiguration.md +145 -0
- package/docs/id/packages/intlayer/getEnumeration.md +159 -0
- package/docs/id/packages/intlayer/getHTMLTextDir.md +122 -0
- package/docs/id/packages/intlayer/getLocaleLang.md +81 -0
- package/docs/id/packages/intlayer/getLocaleName.md +119 -0
- package/docs/id/packages/intlayer/getLocalizedUrl.md +309 -0
- package/docs/id/packages/intlayer/getMultilingualUrls.md +223 -0
- package/docs/id/packages/intlayer/getPathWithoutLocale.md +75 -0
- package/docs/id/packages/intlayer/getTranslation.md +190 -0
- package/docs/id/packages/intlayer/getTranslationContent.md +188 -0
- package/docs/id/packages/next-intlayer/t.md +352 -0
- package/docs/id/packages/next-intlayer/useDictionary.md +271 -0
- package/docs/id/packages/next-intlayer/useIntlayer.md +264 -0
- package/docs/id/packages/next-intlayer/useLocale.md +166 -0
- package/docs/id/packages/react-intlayer/t.md +303 -0
- package/docs/id/packages/react-intlayer/useDictionary.md +287 -0
- package/docs/id/packages/react-intlayer/useI18n.md +267 -0
- package/docs/id/packages/react-intlayer/useIntlayer.md +254 -0
- package/docs/id/packages/react-intlayer/useLocale.md +210 -0
- package/docs/id/per_locale_file.md +323 -0
- package/docs/id/readme.md +261 -0
- package/docs/id/releases/v6.md +305 -0
- package/docs/id/roadmap.md +362 -0
- package/docs/id/testing.md +202 -0
- package/docs/id/vs_code_extension.md +126 -0
- package/docs/it/component_i18n.md +1 -1
- package/docs/it/configuration.md +6 -0
- package/docs/it/intlayer_cli.md +8 -3
- package/docs/it/intlayer_with_next-i18next.md +628 -0
- package/docs/it/intlayer_with_next-intl.md +446 -0
- package/docs/it/intlayer_with_nextjs_16.md +21 -0
- package/docs/it/intlayer_with_tanstack.md +4 -0
- package/docs/it/intlayer_with_vite+react.md +4 -0
- package/docs/ja/component_i18n.md +1 -1
- package/docs/ja/configuration.md +6 -0
- package/docs/ja/intlayer_cli.md +8 -3
- package/docs/ja/intlayer_with_next-i18next.md +627 -0
- package/docs/ja/intlayer_with_next-intl.md +446 -0
- package/docs/ja/intlayer_with_nextjs_16.md +21 -0
- package/docs/ja/intlayer_with_tanstack.md +4 -0
- package/docs/ja/intlayer_with_vite+react.md +4 -0
- package/docs/ko/configuration.md +6 -0
- package/docs/ko/intlayer_cli.md +8 -3
- package/docs/ko/intlayer_with_next-i18next.md +627 -0
- package/docs/ko/intlayer_with_next-intl.md +446 -0
- package/docs/ko/intlayer_with_nextjs_16.md +21 -0
- package/docs/ko/intlayer_with_tanstack.md +4 -0
- package/docs/ko/intlayer_with_vite+react.md +4 -0
- package/docs/pl/CI_CD.md +198 -0
- package/docs/pl/autoFill.md +284 -0
- package/docs/pl/component_i18n.md +186 -0
- package/docs/pl/configuration.md +710 -0
- package/docs/pl/dictionary/condition.md +232 -0
- package/docs/pl/dictionary/content_file.md +1130 -0
- package/docs/pl/dictionary/enumeration.md +245 -0
- package/docs/pl/dictionary/file.md +234 -0
- package/docs/pl/dictionary/function_fetching.md +214 -0
- package/docs/pl/dictionary/gender.md +276 -0
- package/docs/pl/dictionary/insertion.md +188 -0
- package/docs/pl/dictionary/markdown.md +408 -0
- package/docs/pl/dictionary/nesting.md +273 -0
- package/docs/pl/dictionary/translation.md +310 -0
- package/docs/pl/formatters.md +596 -0
- package/docs/pl/how_works_intlayer.md +256 -0
- package/docs/pl/index.md +176 -0
- package/docs/pl/interest_of_intlayer.md +291 -0
- package/docs/pl/intlayer_CMS.md +549 -0
- package/docs/pl/intlayer_cli.md +857 -0
- package/docs/pl/intlayer_visual_editor.md +288 -0
- package/docs/pl/intlayer_with_angular.md +690 -0
- package/docs/pl/intlayer_with_astro.md +280 -0
- package/docs/pl/intlayer_with_create_react_app.md +1235 -0
- package/docs/pl/intlayer_with_express.md +411 -0
- package/docs/pl/intlayer_with_lynx+react.md +518 -0
- package/docs/pl/intlayer_with_nestjs.md +272 -0
- package/docs/pl/intlayer_with_next-i18next.md +628 -0
- package/docs/pl/intlayer_with_next-intl.md +446 -0
- package/docs/pl/intlayer_with_nextjs_14.md +1594 -0
- package/docs/pl/intlayer_with_nextjs_15.md +1701 -0
- package/docs/pl/intlayer_with_nextjs_16.md +21 -0
- package/docs/pl/intlayer_with_nextjs_page_router.md +1513 -0
- package/docs/pl/intlayer_with_nuxt.md +885 -0
- package/docs/pl/intlayer_with_react_native+expo.md +698 -0
- package/docs/pl/intlayer_with_react_router_v7.md +503 -0
- package/docs/pl/intlayer_with_tanstack.md +562 -0
- package/docs/pl/intlayer_with_vite+preact.md +1736 -0
- package/docs/pl/intlayer_with_vite+react.md +1438 -0
- package/docs/pl/intlayer_with_vite+solid.md +290 -0
- package/docs/pl/intlayer_with_vite+svelte.md +289 -0
- package/docs/pl/intlayer_with_vite+vue.md +1116 -0
- package/docs/pl/introduction.md +209 -0
- package/docs/pl/locale_mapper.md +242 -0
- package/docs/pl/mcp_server.md +211 -0
- package/docs/pl/packages/express-intlayer/t.md +458 -0
- package/docs/pl/packages/intlayer/getConfiguration.md +146 -0
- package/docs/pl/packages/intlayer/getEnumeration.md +160 -0
- package/docs/pl/packages/intlayer/getHTMLTextDir.md +121 -0
- package/docs/pl/packages/intlayer/getLocaleLang.md +81 -0
- package/docs/pl/packages/intlayer/getLocaleName.md +118 -0
- package/docs/pl/packages/intlayer/getLocalizedUrl.md +300 -0
- package/docs/pl/packages/intlayer/getMultilingualUrls.md +221 -0
- package/docs/pl/packages/intlayer/getPathWithoutLocale.md +75 -0
- package/docs/pl/packages/intlayer/getTranslation.md +190 -0
- package/docs/pl/packages/intlayer/getTranslationContent.md +189 -0
- package/docs/pl/packages/next-intlayer/t.md +353 -0
- package/docs/pl/packages/next-intlayer/useDictionary.md +270 -0
- package/docs/pl/packages/next-intlayer/useIntlayer.md +263 -0
- package/docs/pl/packages/next-intlayer/useLocale.md +166 -0
- package/docs/pl/packages/react-intlayer/t.md +303 -0
- package/docs/pl/packages/react-intlayer/useDictionary.md +289 -0
- package/docs/pl/packages/react-intlayer/useI18n.md +249 -0
- package/docs/pl/packages/react-intlayer/useIntlayer.md +256 -0
- package/docs/pl/packages/react-intlayer/useLocale.md +210 -0
- package/docs/pl/per_locale_file.md +321 -0
- package/docs/pl/readme.md +261 -0
- package/docs/pl/releases/v6.md +305 -0
- package/docs/pl/roadmap.md +362 -0
- package/docs/pl/testing.md +202 -0
- package/docs/pl/vs_code_extension.md +126 -0
- package/docs/pt/component_i18n.md +1 -1
- package/docs/pt/configuration.md +6 -0
- package/docs/pt/intlayer_cli.md +8 -3
- package/docs/pt/intlayer_with_next-i18next.md +627 -0
- package/docs/pt/intlayer_with_next-intl.md +446 -0
- package/docs/pt/intlayer_with_nextjs_16.md +21 -0
- package/docs/pt/intlayer_with_tanstack.md +4 -0
- package/docs/pt/intlayer_with_vite+react.md +4 -0
- package/docs/ru/component_i18n.md +1 -1
- package/docs/ru/configuration.md +6 -0
- package/docs/ru/intlayer_cli.md +301 -22
- package/docs/ru/intlayer_with_next-i18next.md +629 -0
- package/docs/ru/intlayer_with_next-intl.md +448 -0
- package/docs/ru/intlayer_with_nextjs_16.md +21 -0
- package/docs/ru/intlayer_with_tanstack.md +4 -0
- package/docs/ru/intlayer_with_vite+react.md +4 -0
- package/docs/tr/component_i18n.md +1 -1
- package/docs/tr/configuration.md +6 -0
- package/docs/tr/intlayer_cli.md +8 -0
- package/docs/tr/intlayer_with_next-i18next.md +627 -0
- package/docs/tr/intlayer_with_next-intl.md +446 -0
- package/docs/tr/intlayer_with_nextjs_16.md +21 -0
- package/docs/tr/intlayer_with_tanstack.md +4 -0
- package/docs/tr/intlayer_with_vite+react.md +4 -0
- package/docs/vi/CI_CD.md +198 -0
- package/docs/vi/autoFill.md +284 -0
- package/docs/vi/component_i18n.md +186 -0
- package/docs/vi/configuration.md +710 -0
- package/docs/vi/dictionary/condition.md +237 -0
- package/docs/vi/dictionary/content_file.md +1115 -0
- package/docs/vi/dictionary/enumeration.md +255 -0
- package/docs/vi/dictionary/file.md +234 -0
- package/docs/vi/dictionary/function_fetching.md +212 -0
- package/docs/vi/dictionary/gender.md +275 -0
- package/docs/vi/dictionary/insertion.md +191 -0
- package/docs/vi/dictionary/markdown.md +381 -0
- package/docs/vi/dictionary/nesting.md +273 -0
- package/docs/vi/dictionary/translation.md +309 -0
- package/docs/vi/formatters.md +595 -0
- package/docs/vi/how_works_intlayer.md +256 -0
- package/docs/vi/index.md +174 -0
- package/docs/vi/interest_of_intlayer.md +292 -0
- package/docs/vi/intlayer_CMS.md +549 -0
- package/docs/vi/intlayer_cli.md +850 -0
- package/docs/vi/intlayer_visual_editor.md +288 -0
- package/docs/vi/intlayer_with_angular.md +692 -0
- package/docs/vi/intlayer_with_astro.md +252 -0
- package/docs/vi/intlayer_with_create_react_app.md +1230 -0
- package/docs/vi/intlayer_with_express.md +409 -0
- package/docs/vi/intlayer_with_lynx+react.md +520 -0
- package/docs/vi/intlayer_with_nestjs.md +272 -0
- package/docs/vi/intlayer_with_next-i18next.md +628 -0
- package/docs/vi/intlayer_with_next-intl.md +446 -0
- package/docs/vi/intlayer_with_nextjs_14.md +1584 -0
- package/docs/vi/intlayer_with_nextjs_15.md +1738 -0
- package/docs/vi/intlayer_with_nextjs_16.md +21 -0
- package/docs/vi/intlayer_with_nextjs_page_router.md +1504 -0
- package/docs/vi/intlayer_with_nuxt.md +821 -0
- package/docs/vi/intlayer_with_react_native+expo.md +700 -0
- package/docs/vi/intlayer_with_react_router_v7.md +498 -0
- package/docs/vi/intlayer_with_tanstack.md +562 -0
- package/docs/vi/intlayer_with_vite+preact.md +1722 -0
- package/docs/vi/intlayer_with_vite+react.md +1407 -0
- package/docs/vi/intlayer_with_vite+solid.md +287 -0
- package/docs/vi/intlayer_with_vite+svelte.md +289 -0
- package/docs/vi/intlayer_with_vite+vue.md +1071 -0
- package/docs/vi/introduction.md +215 -0
- package/docs/vi/locale_mapper.md +242 -0
- package/docs/vi/mcp_server.md +211 -0
- package/docs/vi/packages/express-intlayer/t.md +457 -0
- package/docs/vi/packages/intlayer/getConfiguration.md +145 -0
- package/docs/vi/packages/intlayer/getEnumeration.md +162 -0
- package/docs/vi/packages/intlayer/getHTMLTextDir.md +121 -0
- package/docs/vi/packages/intlayer/getLocaleLang.md +81 -0
- package/docs/vi/packages/intlayer/getLocaleName.md +129 -0
- package/docs/vi/packages/intlayer/getLocalizedUrl.md +309 -0
- package/docs/vi/packages/intlayer/getMultilingualUrls.md +221 -0
- package/docs/vi/packages/intlayer/getPathWithoutLocale.md +75 -0
- package/docs/vi/packages/intlayer/getTranslation.md +201 -0
- package/docs/vi/packages/intlayer/getTranslationContent.md +188 -0
- package/docs/vi/packages/next-intlayer/t.md +352 -0
- package/docs/vi/packages/next-intlayer/useDictionary.md +273 -0
- package/docs/vi/packages/next-intlayer/useIntlayer.md +264 -0
- package/docs/vi/packages/next-intlayer/useLocale.md +166 -0
- package/docs/vi/packages/react-intlayer/t.md +304 -0
- package/docs/vi/packages/react-intlayer/useDictionary.md +288 -0
- package/docs/vi/packages/react-intlayer/useI18n.md +295 -0
- package/docs/vi/packages/react-intlayer/useIntlayer.md +256 -0
- package/docs/vi/packages/react-intlayer/useLocale.md +210 -0
- package/docs/vi/per_locale_file.md +326 -0
- package/docs/vi/readme.md +261 -0
- package/docs/vi/releases/v6.md +305 -0
- package/docs/vi/roadmap.md +346 -0
- package/docs/vi/testing.md +202 -0
- package/docs/vi/vs_code_extension.md +126 -0
- package/docs/zh/configuration.md +6 -0
- package/docs/zh/intlayer_cli.md +8 -3
- package/docs/zh/intlayer_with_next-i18next.md +628 -0
- package/docs/zh/intlayer_with_next-intl.md +448 -0
- package/docs/zh/intlayer_with_nextjs_16.md +21 -0
- package/docs/zh/intlayer_with_tanstack.md +4 -0
- package/docs/zh/intlayer_with_vite+react.md +4 -0
- package/frequent_questions/ar/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/ar/array_as_content_declaration.md +1 -2
- package/frequent_questions/ar/build_dictionaries.md +1 -2
- package/frequent_questions/ar/build_error_CI_CD.md +1 -2
- package/frequent_questions/ar/bun_set_up.md +1 -2
- package/frequent_questions/ar/customized_locale_list.md +1 -2
- package/frequent_questions/ar/domain_routing.md +1 -2
- package/frequent_questions/ar/esbuild_error.md +1 -2
- package/frequent_questions/ar/get_locale_cookie.md +1 -2
- package/frequent_questions/ar/intlayer_command_undefined.md +1 -2
- package/frequent_questions/ar/locale_incorect_in_url.md +1 -2
- package/frequent_questions/ar/static_rendering.md +1 -3
- package/frequent_questions/ar/translated_path_url.md +1 -2
- package/frequent_questions/ar/unknown_command.md +1 -2
- package/frequent_questions/de/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/de/array_as_content_declaration.md +1 -2
- package/frequent_questions/de/build_dictionaries.md +1 -2
- package/frequent_questions/de/build_error_CI_CD.md +1 -2
- package/frequent_questions/de/bun_set_up.md +1 -2
- package/frequent_questions/de/customized_locale_list.md +1 -2
- package/frequent_questions/de/domain_routing.md +1 -2
- package/frequent_questions/de/esbuild_error.md +1 -2
- package/frequent_questions/de/get_locale_cookie.md +1 -2
- package/frequent_questions/de/intlayer_command_undefined.md +1 -2
- package/frequent_questions/de/locale_incorect_in_url.md +1 -2
- package/frequent_questions/de/static_rendering.md +1 -3
- package/frequent_questions/de/translated_path_url.md +1 -2
- package/frequent_questions/de/unknown_command.md +1 -2
- package/frequent_questions/en/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/en/array_as_content_declaration.md +1 -2
- package/frequent_questions/en/build_dictionaries.md +1 -2
- package/frequent_questions/en/build_error_CI_CD.md +1 -2
- package/frequent_questions/en/bun_set_up.md +1 -2
- package/frequent_questions/en/customized_locale_list.md +1 -2
- package/frequent_questions/en/domain_routing.md +1 -2
- package/frequent_questions/en/esbuild_error.md +1 -2
- package/frequent_questions/en/get_locale_cookie.md +1 -2
- package/frequent_questions/en/intlayer_command_undefined.md +1 -2
- package/frequent_questions/en/locale_incorect_in_url.md +1 -2
- package/frequent_questions/en/static_rendering.md +1 -3
- package/frequent_questions/en/translated_path_url.md +1 -2
- package/frequent_questions/en/unknown_command.md +1 -2
- package/frequent_questions/en-GB/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/en-GB/array_as_content_declaration.md +1 -2
- package/frequent_questions/en-GB/build_dictionaries.md +1 -2
- package/frequent_questions/en-GB/build_error_CI_CD.md +1 -2
- package/frequent_questions/en-GB/bun_set_up.md +1 -2
- package/frequent_questions/en-GB/customized_locale_list.md +1 -2
- package/frequent_questions/en-GB/domain_routing.md +1 -2
- package/frequent_questions/en-GB/esbuild_error.md +1 -2
- package/frequent_questions/en-GB/get_locale_cookie.md +1 -2
- package/frequent_questions/en-GB/intlayer_command_undefined.md +1 -2
- package/frequent_questions/en-GB/locale_incorect_in_url.md +1 -2
- package/frequent_questions/en-GB/static_rendering.md +1 -3
- package/frequent_questions/en-GB/translated_path_url.md +1 -2
- package/frequent_questions/en-GB/unknown_command.md +1 -2
- package/frequent_questions/es/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/es/array_as_content_declaration.md +1 -2
- package/frequent_questions/es/build_dictionaries.md +1 -2
- package/frequent_questions/es/build_error_CI_CD.md +1 -2
- package/frequent_questions/es/bun_set_up.md +1 -2
- package/frequent_questions/es/customized_locale_list.md +1 -2
- package/frequent_questions/es/domain_routing.md +1 -2
- package/frequent_questions/es/esbuild_error.md +1 -2
- package/frequent_questions/es/get_locale_cookie.md +1 -2
- package/frequent_questions/es/intlayer_command_undefined.md +1 -2
- package/frequent_questions/es/locale_incorect_in_url.md +1 -2
- package/frequent_questions/es/static_rendering.md +1 -3
- package/frequent_questions/es/translated_path_url.md +1 -2
- package/frequent_questions/es/unknown_command.md +1 -2
- package/frequent_questions/fr/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/fr/array_as_content_declaration.md +1 -2
- package/frequent_questions/fr/build_dictionaries.md +1 -2
- package/frequent_questions/fr/build_error_CI_CD.md +1 -2
- package/frequent_questions/fr/bun_set_up.md +1 -2
- package/frequent_questions/fr/customized_locale_list.md +1 -2
- package/frequent_questions/fr/domain_routing.md +1 -2
- package/frequent_questions/fr/esbuild_error.md +1 -2
- package/frequent_questions/fr/get_locale_cookie.md +1 -2
- package/frequent_questions/fr/intlayer_command_undefined.md +1 -2
- package/frequent_questions/fr/locale_incorect_in_url.md +1 -2
- package/frequent_questions/fr/static_rendering.md +1 -3
- package/frequent_questions/fr/translated_path_url.md +1 -2
- package/frequent_questions/fr/unknown_command.md +1 -2
- package/frequent_questions/hi/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/hi/array_as_content_declaration.md +1 -2
- package/frequent_questions/hi/build_dictionaries.md +1 -2
- package/frequent_questions/hi/build_error_CI_CD.md +1 -2
- package/frequent_questions/hi/bun_set_up.md +1 -2
- package/frequent_questions/hi/customized_locale_list.md +1 -2
- package/frequent_questions/hi/domain_routing.md +1 -2
- package/frequent_questions/hi/esbuild_error.md +1 -2
- package/frequent_questions/hi/get_locale_cookie.md +1 -2
- package/frequent_questions/hi/intlayer_command_undefined.md +1 -2
- package/frequent_questions/hi/locale_incorect_in_url.md +1 -2
- package/frequent_questions/hi/static_rendering.md +1 -3
- package/frequent_questions/hi/translated_path_url.md +1 -2
- package/frequent_questions/hi/unknown_command.md +1 -2
- package/frequent_questions/id/SSR_Next_no_[locale].md +104 -0
- package/frequent_questions/id/array_as_content_declaration.md +71 -0
- package/frequent_questions/id/build_dictionaries.md +58 -0
- package/frequent_questions/id/build_error_CI_CD.md +74 -0
- package/frequent_questions/id/bun_set_up.md +53 -0
- package/frequent_questions/id/customized_locale_list.md +64 -0
- package/frequent_questions/id/domain_routing.md +113 -0
- package/frequent_questions/id/esbuild_error.md +29 -0
- package/frequent_questions/id/get_locale_cookie.md +142 -0
- package/frequent_questions/id/intlayer_command_undefined.md +155 -0
- package/frequent_questions/id/locale_incorect_in_url.md +73 -0
- package/frequent_questions/id/static_rendering.md +44 -0
- package/frequent_questions/id/translated_path_url.md +55 -0
- package/frequent_questions/id/unknown_command.md +97 -0
- package/frequent_questions/it/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/it/array_as_content_declaration.md +1 -2
- package/frequent_questions/it/build_dictionaries.md +1 -2
- package/frequent_questions/it/build_error_CI_CD.md +1 -2
- package/frequent_questions/it/bun_set_up.md +1 -2
- package/frequent_questions/it/customized_locale_list.md +1 -2
- package/frequent_questions/it/domain_routing.md +1 -2
- package/frequent_questions/it/esbuild_error.md +1 -2
- package/frequent_questions/it/get_locale_cookie.md +1 -2
- package/frequent_questions/it/intlayer_command_undefined.md +1 -2
- package/frequent_questions/it/locale_incorect_in_url.md +1 -2
- package/frequent_questions/it/static_rendering.md +1 -3
- package/frequent_questions/it/translated_path_url.md +1 -2
- package/frequent_questions/it/unknown_command.md +1 -2
- package/frequent_questions/ja/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/ja/array_as_content_declaration.md +1 -2
- package/frequent_questions/ja/build_dictionaries.md +1 -2
- package/frequent_questions/ja/build_error_CI_CD.md +1 -2
- package/frequent_questions/ja/bun_set_up.md +1 -2
- package/frequent_questions/ja/customized_locale_list.md +1 -2
- package/frequent_questions/ja/domain_routing.md +1 -2
- package/frequent_questions/ja/esbuild_error.md +1 -2
- package/frequent_questions/ja/get_locale_cookie.md +1 -2
- package/frequent_questions/ja/intlayer_command_undefined.md +1 -2
- package/frequent_questions/ja/locale_incorect_in_url.md +1 -2
- package/frequent_questions/ja/static_rendering.md +1 -3
- package/frequent_questions/ja/translated_path_url.md +1 -2
- package/frequent_questions/ja/unknown_command.md +1 -2
- package/frequent_questions/ko/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/ko/array_as_content_declaration.md +1 -2
- package/frequent_questions/ko/build_dictionaries.md +1 -2
- package/frequent_questions/ko/build_error_CI_CD.md +1 -2
- package/frequent_questions/ko/bun_set_up.md +1 -2
- package/frequent_questions/ko/customized_locale_list.md +1 -2
- package/frequent_questions/ko/domain_routing.md +1 -2
- package/frequent_questions/ko/esbuild_error.md +1 -2
- package/frequent_questions/ko/get_locale_cookie.md +1 -2
- package/frequent_questions/ko/intlayer_command_undefined.md +1 -2
- package/frequent_questions/ko/locale_incorect_in_url.md +1 -2
- package/frequent_questions/ko/static_rendering.md +1 -3
- package/frequent_questions/ko/translated_path_url.md +1 -2
- package/frequent_questions/ko/unknown_command.md +1 -2
- package/frequent_questions/pl/SSR_Next_no_[locale].md +104 -0
- package/frequent_questions/pl/array_as_content_declaration.md +71 -0
- package/frequent_questions/pl/build_dictionaries.md +58 -0
- package/frequent_questions/pl/build_error_CI_CD.md +74 -0
- package/frequent_questions/pl/bun_set_up.md +54 -0
- package/frequent_questions/pl/customized_locale_list.md +64 -0
- package/frequent_questions/pl/domain_routing.md +113 -0
- package/frequent_questions/pl/esbuild_error.md +29 -0
- package/frequent_questions/pl/get_locale_cookie.md +142 -0
- package/frequent_questions/pl/intlayer_command_undefined.md +155 -0
- package/frequent_questions/pl/locale_incorect_in_url.md +73 -0
- package/frequent_questions/pl/static_rendering.md +44 -0
- package/frequent_questions/pl/translated_path_url.md +55 -0
- package/frequent_questions/pl/unknown_command.md +97 -0
- package/frequent_questions/pt/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/pt/array_as_content_declaration.md +1 -2
- package/frequent_questions/pt/build_dictionaries.md +1 -2
- package/frequent_questions/pt/build_error_CI_CD.md +1 -2
- package/frequent_questions/pt/bun_set_up.md +1 -2
- package/frequent_questions/pt/customized_locale_list.md +1 -2
- package/frequent_questions/pt/domain_routing.md +1 -2
- package/frequent_questions/pt/esbuild_error.md +1 -2
- package/frequent_questions/pt/get_locale_cookie.md +1 -2
- package/frequent_questions/pt/intlayer_command_undefined.md +1 -2
- package/frequent_questions/pt/locale_incorect_in_url.md +1 -2
- package/frequent_questions/pt/static_rendering.md +1 -3
- package/frequent_questions/pt/translated_path_url.md +1 -2
- package/frequent_questions/pt/unknown_command.md +1 -2
- package/frequent_questions/ru/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/ru/array_as_content_declaration.md +1 -2
- package/frequent_questions/ru/build_dictionaries.md +1 -2
- package/frequent_questions/ru/build_error_CI_CD.md +1 -2
- package/frequent_questions/ru/bun_set_up.md +1 -2
- package/frequent_questions/ru/customized_locale_list.md +1 -2
- package/frequent_questions/ru/domain_routing.md +1 -2
- package/frequent_questions/ru/esbuild_error.md +1 -2
- package/frequent_questions/ru/get_locale_cookie.md +1 -2
- package/frequent_questions/ru/intlayer_command_undefined.md +1 -2
- package/frequent_questions/ru/locale_incorect_in_url.md +1 -2
- package/frequent_questions/ru/static_rendering.md +1 -2
- package/frequent_questions/ru/translated_path_url.md +1 -2
- package/frequent_questions/ru/unknown_command.md +1 -2
- package/frequent_questions/tr/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/tr/array_as_content_declaration.md +1 -2
- package/frequent_questions/tr/build_dictionaries.md +1 -2
- package/frequent_questions/tr/build_error_CI_CD.md +1 -2
- package/frequent_questions/tr/bun_set_up.md +1 -2
- package/frequent_questions/tr/customized_locale_list.md +1 -2
- package/frequent_questions/tr/domain_routing.md +1 -2
- package/frequent_questions/tr/esbuild_error.md +1 -2
- package/frequent_questions/tr/get_locale_cookie.md +1 -2
- package/frequent_questions/tr/intlayer_command_undefined.md +1 -2
- package/frequent_questions/tr/locale_incorect_in_url.md +1 -2
- package/frequent_questions/tr/static_rendering.md +1 -2
- package/frequent_questions/tr/translated_path_url.md +1 -2
- package/frequent_questions/tr/unknown_command.md +1 -2
- package/frequent_questions/vi/SSR_Next_no_[locale].md +106 -0
- package/frequent_questions/vi/array_as_content_declaration.md +71 -0
- package/frequent_questions/vi/build_dictionaries.md +58 -0
- package/frequent_questions/vi/build_error_CI_CD.md +74 -0
- package/frequent_questions/vi/bun_set_up.md +53 -0
- package/frequent_questions/vi/customized_locale_list.md +64 -0
- package/frequent_questions/vi/domain_routing.md +113 -0
- package/frequent_questions/vi/esbuild_error.md +29 -0
- package/frequent_questions/vi/get_locale_cookie.md +142 -0
- package/frequent_questions/vi/intlayer_command_undefined.md +155 -0
- package/frequent_questions/vi/locale_incorect_in_url.md +73 -0
- package/frequent_questions/vi/static_rendering.md +44 -0
- package/frequent_questions/vi/translated_path_url.md +55 -0
- package/frequent_questions/vi/unknown_command.md +97 -0
- package/frequent_questions/zh/SSR_Next_no_[locale].md +1 -2
- package/frequent_questions/zh/array_as_content_declaration.md +1 -2
- package/frequent_questions/zh/build_dictionaries.md +1 -2
- package/frequent_questions/zh/build_error_CI_CD.md +1 -2
- package/frequent_questions/zh/bun_set_up.md +1 -2
- package/frequent_questions/zh/customized_locale_list.md +1 -2
- package/frequent_questions/zh/domain_routing.md +1 -2
- package/frequent_questions/zh/esbuild_error.md +1 -2
- package/frequent_questions/zh/get_locale_cookie.md +1 -2
- package/frequent_questions/zh/intlayer_command_undefined.md +1 -2
- package/frequent_questions/zh/locale_incorect_in_url.md +1 -2
- package/frequent_questions/zh/static_rendering.md +1 -3
- package/frequent_questions/zh/translated_path_url.md +1 -2
- package/frequent_questions/zh/unknown_command.md +1 -2
- package/legal/id/privacy_notice.md +83 -0
- package/legal/id/terms_of_service.md +55 -0
- package/legal/pl/privacy_notice.md +83 -0
- package/legal/pl/terms_of_service.md +55 -0
- package/legal/vi/privacy_notice.md +83 -0
- package/legal/vi/terms_of_service.md +55 -0
- package/package.json +19 -18
- package/src/generated/blog.entry.ts +38 -0
|
@@ -0,0 +1,1438 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2024-03-07
|
|
3
|
+
updatedAt: 2024-03-07
|
|
4
|
+
title: Jak przetłumaczyć swoją aplikację Vite i React – przewodnik i18n 2025
|
|
5
|
+
description: Dowiedz się, jak dodać internacjonalizację (i18n) do swojej aplikacji Vite i React za pomocą Intlayer. Postępuj zgodnie z tym przewodnikiem, aby uczynić swoją aplikację wielojęzyczną.
|
|
6
|
+
keywords:
|
|
7
|
+
- Internacjonalizacja
|
|
8
|
+
- Dokumentacja
|
|
9
|
+
- Intlayer
|
|
10
|
+
- Vite
|
|
11
|
+
- React
|
|
12
|
+
- i18n
|
|
13
|
+
- JavaScript
|
|
14
|
+
slugs:
|
|
15
|
+
- doc
|
|
16
|
+
- environment
|
|
17
|
+
- vite-and-react
|
|
18
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-vite-react-template
|
|
19
|
+
youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
|
|
20
|
+
history:
|
|
21
|
+
- version: 5.5.10
|
|
22
|
+
date: 2025-06-29
|
|
23
|
+
changes: Inicjalizacja historii
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Przetłumacz swoją stronę Vite i React za pomocą Intlayer | Internacjonalizacja (i18n)
|
|
27
|
+
|
|
28
|
+
## Spis treści
|
|
29
|
+
|
|
30
|
+
<TOC/>
|
|
31
|
+
|
|
32
|
+
## Czym jest Intlayer?
|
|
33
|
+
|
|
34
|
+
**Intlayer** to innowacyjna, open-source'owa biblioteka do internacjonalizacji (i18n), zaprojektowana, aby uprościć wsparcie wielojęzyczne w nowoczesnych aplikacjach webowych.
|
|
35
|
+
|
|
36
|
+
Dzięki Intlayer możesz:
|
|
37
|
+
|
|
38
|
+
- **Łatwo zarządzać tłumaczeniami** za pomocą deklaratywnych słowników na poziomie komponentów.
|
|
39
|
+
- **Dynamicznie lokalizować metadane**, trasy i treści.
|
|
40
|
+
- **Zapewnić wsparcie dla TypeScript** dzięki automatycznie generowanym typom, co poprawia autouzupełnianie i wykrywanie błędów.
|
|
41
|
+
- **Korzystać z zaawansowanych funkcji**, takich jak dynamiczne wykrywanie i przełączanie lokalizacji.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Przewodnik krok po kroku: jak skonfigurować Intlayer w aplikacji Vite i React
|
|
46
|
+
|
|
47
|
+
<Tab defaultTab="video">
|
|
48
|
+
<TabItem label="Wideo" value="video">
|
|
49
|
+
|
|
50
|
+
<iframe title="Najlepsze rozwiązanie i18n dla Vite i React? Odkryj 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?si=VaKmrYMmXjo3xpk2"/>
|
|
51
|
+
|
|
52
|
+
</TabItem>
|
|
53
|
+
<TabItem label="Kod" value="code">
|
|
54
|
+
|
|
55
|
+
<iframe
|
|
56
|
+
src="https://stackblitz.com/github/aymericzip/intlayer-vite-react-template?embed=1&ctl=1&file=intlayer.config.ts"
|
|
57
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
58
|
+
title="Demo CodeSandbox - Jak internacjonalizować swoją aplikację za pomocą Intlayer"
|
|
59
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
60
|
+
loading="lazy"
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
</TabItem>
|
|
64
|
+
</Tab>
|
|
65
|
+
|
|
66
|
+
Zobacz [Application Template](https://github.com/aymericzip/intlayer-vite-react-template) na GitHub.
|
|
67
|
+
|
|
68
|
+
### Krok 1: Instalacja zależności
|
|
69
|
+
|
|
70
|
+
Zainstaluj niezbędne pakiety za pomocą npm:
|
|
71
|
+
|
|
72
|
+
```bash packageManager="npm"
|
|
73
|
+
npm install intlayer react-intlayer
|
|
74
|
+
npm install vite-intlayer --save-dev
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```bash packageManager="pnpm"
|
|
78
|
+
pnpm add intlayer react-intlayer
|
|
79
|
+
pnpm add vite-intlayer --save-dev
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```bash packageManager="yarn"
|
|
83
|
+
yarn add intlayer react-intlayer
|
|
84
|
+
yarn add vite-intlayer --save-dev
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- **intlayer**
|
|
88
|
+
|
|
89
|
+
- **intlayer**
|
|
90
|
+
|
|
91
|
+
Podstawowy pakiet, który dostarcza narzędzia do internacjonalizacji do zarządzania konfiguracją, tłumaczeń, [deklaracji treści](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/content_file.md), transpilecji oraz [poleceń CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_cli.md).
|
|
92
|
+
|
|
93
|
+
- **react-intlayer**
|
|
94
|
+
Pakiet integrujący Intlayer z aplikacją React. Zapewnia dostawców kontekstu oraz hooki do internacjonalizacji w React.
|
|
95
|
+
|
|
96
|
+
- **vite-intlayer**
|
|
97
|
+
Zawiera wtyczkę Vite do integracji Intlayer z [bundlerem Vite](https://vite.dev/guide/why.html#why-bundle-for-production), a także middleware do wykrywania preferowanego języka użytkownika, zarządzania ciasteczkami oraz obsługi przekierowań URL.
|
|
98
|
+
|
|
99
|
+
### Krok 2: Konfiguracja projektu
|
|
100
|
+
|
|
101
|
+
Utwórz plik konfiguracyjny, aby skonfigurować języki swojej aplikacji:
|
|
102
|
+
|
|
103
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
104
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
105
|
+
|
|
106
|
+
const config: IntlayerConfig = {
|
|
107
|
+
internationalization: {
|
|
108
|
+
locales: [
|
|
109
|
+
Locales.ENGLISH,
|
|
110
|
+
Locales.FRENCH,
|
|
111
|
+
Locales.SPANISH,
|
|
112
|
+
// Twoje inne lokalizacje
|
|
113
|
+
],
|
|
114
|
+
defaultLocale: Locales.ENGLISH,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export default config;
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```javascript fileName="intlayer.config.mjs" codeFormat="esm"
|
|
122
|
+
import { Locales } from "intlayer";
|
|
123
|
+
|
|
124
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
125
|
+
const config = {
|
|
126
|
+
internationalization: {
|
|
127
|
+
locales: [
|
|
128
|
+
Locales.ENGLISH,
|
|
129
|
+
Locales.FRENCH,
|
|
130
|
+
Locales.SPANISH,
|
|
131
|
+
// Twoje inne lokalizacje
|
|
132
|
+
],
|
|
133
|
+
defaultLocale: Locales.ENGLISH,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export default config;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
|
|
141
|
+
const { Locales } = require("intlayer");
|
|
142
|
+
|
|
143
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
144
|
+
// konfiguracja międzynarodowa
|
|
145
|
+
const config = {
|
|
146
|
+
internationalization: {
|
|
147
|
+
locales: [
|
|
148
|
+
Locales.ENGLISH,
|
|
149
|
+
Locales.FRENCH,
|
|
150
|
+
Locales.SPANISH,
|
|
151
|
+
// Twoje inne lokalizacje
|
|
152
|
+
],
|
|
153
|
+
defaultLocale: Locales.ENGLISH,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
module.exports = config;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
> Poprzez ten plik konfiguracyjny możesz ustawić zlokalizowane adresy URL, przekierowania middleware, nazwy ciasteczek, lokalizację i rozszerzenie deklaracji treści, wyłączyć logi Intlayer w konsoli i wiele więcej. Aby uzyskać pełną listę dostępnych parametrów, zapoznaj się z [dokumentacją konfiguracji](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/configuration.md).
|
|
161
|
+
|
|
162
|
+
### Krok 3: Zintegruj Intlayer w swojej konfiguracji Vite
|
|
163
|
+
|
|
164
|
+
Dodaj wtyczkę intlayer do swojej konfiguracji.
|
|
165
|
+
|
|
166
|
+
```typescript fileName="vite.config.ts" codeFormat="typescript"
|
|
167
|
+
import { defineConfig } from "vite";
|
|
168
|
+
import react from "@vitejs/plugin-react-swc";
|
|
169
|
+
import { intlayer } from "vite-intlayer";
|
|
170
|
+
|
|
171
|
+
// https://vitejs.dev/config/
|
|
172
|
+
export default defineConfig({
|
|
173
|
+
plugins: [react(), intlayer()],
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
```javascript fileName="vite.config.mjs" codeFormat="esm"
|
|
178
|
+
import { defineConfig } from "vite";
|
|
179
|
+
import react from "@vitejs/plugin-react-swc";
|
|
180
|
+
import { intlayer } from "vite-intlayer";
|
|
181
|
+
|
|
182
|
+
// https://vitejs.dev/config/
|
|
183
|
+
export default defineConfig({
|
|
184
|
+
plugins: [react(), intlayer()],
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```javascript fileName="vite.config.cjs" codeFormat="commonjs"
|
|
189
|
+
const { defineConfig } = require("vite");
|
|
190
|
+
const react = require("@vitejs/plugin-react-swc");
|
|
191
|
+
const { intlayer } = require("vite-intlayer");
|
|
192
|
+
|
|
193
|
+
// https://vitejs.dev/config/
|
|
194
|
+
module.exports = defineConfig({
|
|
195
|
+
plugins: [react(), intlayer()],
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
> Wtyczka Vite `intlayer()` służy do integracji Intlayer z Vite. Zapewnia budowanie plików deklaracji treści oraz monitoruje je w trybie deweloperskim. Definiuje zmienne środowiskowe Intlayer w aplikacji Vite. Dodatkowo dostarcza aliasy w celu optymalizacji wydajności.
|
|
200
|
+
|
|
201
|
+
### Krok 4: Zadeklaruj swoją treść
|
|
202
|
+
|
|
203
|
+
Utwórz i zarządzaj deklaracjami treści, aby przechowywać tłumaczenia:
|
|
204
|
+
|
|
205
|
+
```tsx fileName="src/app.content.tsx" contentDeclarationFormat="typescript"
|
|
206
|
+
import { t, type Dictionary } from "intlayer";
|
|
207
|
+
import type { ReactNode } from "react";
|
|
208
|
+
|
|
209
|
+
const appContent = {
|
|
210
|
+
key: "app",
|
|
211
|
+
content: {
|
|
212
|
+
viteLogo: t({
|
|
213
|
+
en: "Vite logo",
|
|
214
|
+
fr: "Logo Vite",
|
|
215
|
+
es: "Logo Vite",
|
|
216
|
+
}),
|
|
217
|
+
reactLogo: t({
|
|
218
|
+
en: "React logo",
|
|
219
|
+
fr: "Logo React",
|
|
220
|
+
es: "Logo React",
|
|
221
|
+
}),
|
|
222
|
+
|
|
223
|
+
title: "Vite + React",
|
|
224
|
+
|
|
225
|
+
count: t({
|
|
226
|
+
en: "count is ",
|
|
227
|
+
fr: "le compte est ",
|
|
228
|
+
es: "el recuento es ",
|
|
229
|
+
}),
|
|
230
|
+
|
|
231
|
+
edit: t<ReactNode>({
|
|
232
|
+
en: (
|
|
233
|
+
<>
|
|
234
|
+
Edytuj <code>src/App.tsx</code> i zapisz, aby przetestować HMR
|
|
235
|
+
</>
|
|
236
|
+
),
|
|
237
|
+
fr: (
|
|
238
|
+
<>
|
|
239
|
+
Éditez <code>src/App.tsx</code> et enregistrez pour tester HMR
|
|
240
|
+
</>
|
|
241
|
+
),
|
|
242
|
+
es: (
|
|
243
|
+
<>
|
|
244
|
+
Edita <code>src/App.tsx</code> y guarda para probar HMR
|
|
245
|
+
</>
|
|
246
|
+
),
|
|
247
|
+
}),
|
|
248
|
+
|
|
249
|
+
readTheDocs: t({
|
|
250
|
+
en: "Click on the Vite and React logos to learn more",
|
|
251
|
+
fr: "Cliquez sur les logos Vite et React pour en savoir plus",
|
|
252
|
+
es: "Haga clic en los logotipos de Vite y React para obtener más información",
|
|
253
|
+
}),
|
|
254
|
+
},
|
|
255
|
+
} satisfies Dictionary;
|
|
256
|
+
|
|
257
|
+
export default appContent;
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```javascript fileName="src/app.content.mjs" contentDeclarationFormat="esm"
|
|
261
|
+
import { t } from "intlayer";
|
|
262
|
+
|
|
263
|
+
/** @type {import('intlayer').Dictionary} */
|
|
264
|
+
const appContent = {
|
|
265
|
+
key: "app",
|
|
266
|
+
content: {
|
|
267
|
+
viteLogo: t({
|
|
268
|
+
en: "Vite logo",
|
|
269
|
+
fr: "Logo Vite",
|
|
270
|
+
es: "Logo Vite",
|
|
271
|
+
pl: "Logo Vite",
|
|
272
|
+
}),
|
|
273
|
+
reactLogo: t({
|
|
274
|
+
en: "React logo",
|
|
275
|
+
fr: "Logo React",
|
|
276
|
+
es: "Logo React",
|
|
277
|
+
pl: "Logo React",
|
|
278
|
+
}),
|
|
279
|
+
|
|
280
|
+
title: "Vite + React",
|
|
281
|
+
|
|
282
|
+
count: t({
|
|
283
|
+
en: "count is ",
|
|
284
|
+
fr: "le compte est ",
|
|
285
|
+
es: "el recuento es ",
|
|
286
|
+
pl: "licznik to ",
|
|
287
|
+
}),
|
|
288
|
+
|
|
289
|
+
edit:
|
|
290
|
+
t <
|
|
291
|
+
ReactNode >
|
|
292
|
+
{
|
|
293
|
+
// Nie zapomnij zaimportować React, jeśli używasz React node w swojej zawartości
|
|
294
|
+
en: (
|
|
295
|
+
<>
|
|
296
|
+
Edit <code>src/App.tsx</code> and save to test HMR
|
|
297
|
+
</>
|
|
298
|
+
),
|
|
299
|
+
pl: (
|
|
300
|
+
<>
|
|
301
|
+
Edytuj <code>src/App.tsx</code> i zapisz, aby przetestować HMR
|
|
302
|
+
</>
|
|
303
|
+
),
|
|
304
|
+
},
|
|
305
|
+
</>
|
|
306
|
+
),
|
|
307
|
+
fr: (
|
|
308
|
+
<>
|
|
309
|
+
Éditez <code>src/App.tsx</code> et enregistrez pour tester HMR
|
|
310
|
+
</>
|
|
311
|
+
),
|
|
312
|
+
es: (
|
|
313
|
+
<>
|
|
314
|
+
Edita <code>src/App.tsx</code> y guarda para probar HMR
|
|
315
|
+
</>
|
|
316
|
+
),
|
|
317
|
+
pl: (
|
|
318
|
+
<>
|
|
319
|
+
Edytuj <code>src/App.tsx</code> i zapisz, aby przetestować HMR
|
|
320
|
+
</>
|
|
321
|
+
),
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
readTheDocs: t({
|
|
325
|
+
en: "Click on the Vite and React logos to learn more",
|
|
326
|
+
fr: "Cliquez sur les logos Vite et React pour en savoir plus",
|
|
327
|
+
es: "Haga clic en los logotipos de Vite y React para obtener más información",
|
|
328
|
+
pl: "Kliknij na logotypy Vite i React, aby dowiedzieć się więcej",
|
|
329
|
+
}),
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
export default appContent;
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
```javascript fileName="src/app.content.cjs" contentDeclarationFormat="commonjs"
|
|
337
|
+
const { t } = require("intlayer");
|
|
338
|
+
|
|
339
|
+
/** @type {import('intlayer').Dictionary} */
|
|
340
|
+
const appContent = {
|
|
341
|
+
key: "app",
|
|
342
|
+
content: {
|
|
343
|
+
viteLogo: t({
|
|
344
|
+
en: "Vite logo",
|
|
345
|
+
pl: "Logo Vite",
|
|
346
|
+
fr: "Logo Vite",
|
|
347
|
+
es: "Logo Vite",
|
|
348
|
+
}),
|
|
349
|
+
reactLogo: t({
|
|
350
|
+
en: "React logo",
|
|
351
|
+
pl: "Logo React",
|
|
352
|
+
fr: "Logo React",
|
|
353
|
+
es: "Logo React",
|
|
354
|
+
}),
|
|
355
|
+
|
|
356
|
+
title: "Vite + React",
|
|
357
|
+
|
|
358
|
+
count: t({
|
|
359
|
+
en: "count is ",
|
|
360
|
+
pl: "licznik to ",
|
|
361
|
+
fr: "le compte est ",
|
|
362
|
+
es: "el recuento es ",
|
|
363
|
+
}),
|
|
364
|
+
|
|
365
|
+
edit:
|
|
366
|
+
t <
|
|
367
|
+
ReactNode >
|
|
368
|
+
{
|
|
369
|
+
// Nie zapomnij zaimportować React, jeśli używasz React node w swojej zawartości
|
|
370
|
+
en: (
|
|
371
|
+
<>
|
|
372
|
+
Edit <code>src/App.tsx</code> and save to test HMR
|
|
373
|
+
</>
|
|
374
|
+
),
|
|
375
|
+
fr: (
|
|
376
|
+
<>
|
|
377
|
+
Éditez <code>src/App.tsx</code> et enregistrez pour tester HMR
|
|
378
|
+
</>
|
|
379
|
+
),
|
|
380
|
+
es: (
|
|
381
|
+
<>
|
|
382
|
+
Edita <code>src/App.tsx</code> y guarda para probar HMR
|
|
383
|
+
</>
|
|
384
|
+
),
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
readTheDocs: t({
|
|
388
|
+
en: "Click on the Vite and React logos to learn more",
|
|
389
|
+
pl: "Kliknij na logotypy Vite i React, aby dowiedzieć się więcej",
|
|
390
|
+
fr: "Cliquez sur les logos Vite et React pour en savoir plus",
|
|
391
|
+
es: "Haga clic en los logotipos de Vite y React para obtener más información",
|
|
392
|
+
}),
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
module.exports = appContent;
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
```json fileName="src/app.content.json" contentDeclarationFormat="json"
|
|
400
|
+
{
|
|
401
|
+
"$schema": "https://intlayer.org/schema.json",
|
|
402
|
+
"key": "app",
|
|
403
|
+
"content": {
|
|
404
|
+
"viteLogo": {
|
|
405
|
+
"nodeType": "translation",
|
|
406
|
+
"translation": {
|
|
407
|
+
"en": "Vite logo",
|
|
408
|
+
"pl": "Logo Vite",
|
|
409
|
+
"fr": "Logo Vite",
|
|
410
|
+
"es": "Logo Vite"
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
"reactLogo": {
|
|
414
|
+
"nodeType": "translation",
|
|
415
|
+
"translation": {
|
|
416
|
+
"en": "React logo",
|
|
417
|
+
"pl": "Logo React",
|
|
418
|
+
"fr": "Logo React",
|
|
419
|
+
"es": "Logo React"
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
"title": {
|
|
423
|
+
"nodeType": "translation",
|
|
424
|
+
"translation": {
|
|
425
|
+
"en": "Vite + React",
|
|
426
|
+
"fr": "Vite + React",
|
|
427
|
+
"es": "Vite + React",
|
|
428
|
+
"pl": "Vite + React"
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
"count": {
|
|
432
|
+
"nodeType": "translation",
|
|
433
|
+
"translation": {
|
|
434
|
+
"en": "count is ",
|
|
435
|
+
"fr": "le compte est ",
|
|
436
|
+
"es": "el recuento es ",
|
|
437
|
+
"pl": "licznik to "
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
"edit": {
|
|
441
|
+
"nodeType": "translation",
|
|
442
|
+
"translation": {
|
|
443
|
+
"en": "Edit src/App.tsx and save to test HMR",
|
|
444
|
+
"fr": "Éditez src/App.tsx et enregistrez pour tester HMR",
|
|
445
|
+
"es": "Edita src/App.tsx y guarda para probar HMR",
|
|
446
|
+
"pl": "Edytuj src/App.tsx i zapisz, aby przetestować HMR"
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
"readTheDocs": {
|
|
450
|
+
"nodeType": "translation",
|
|
451
|
+
"translation": {
|
|
452
|
+
"en": "Click on the Vite and React logos to learn more",
|
|
453
|
+
"fr": "Cliquez sur les logos Vite et React pour en savoir plus",
|
|
454
|
+
"es": "Haga clic en los logotipos de Vite y React para obtener más información",
|
|
455
|
+
"pl": "Kliknij na logotypy Vite i React, aby dowiedzieć się więcej"
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
"fr": "Cliquez sur les logos Vite et React pour en savoir plus",
|
|
459
|
+
"es": "Haga clic en los logotipos de Vite y React para obtener más información",
|
|
460
|
+
"pl": "Kliknij na logotypy Vite i React, aby dowiedzieć się więcej"
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
> Twoje deklaracje zawartości mogą być definiowane w dowolnym miejscu w aplikacji, pod warunkiem, że zostaną umieszczone w katalogu `contentDir` (domyślnie `./src`). I będą miały rozszerzenie pliku deklaracji zawartości (domyślnie `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`).
|
|
468
|
+
|
|
469
|
+
> Aby uzyskać więcej szczegółów, zapoznaj się z [dokumentacją deklaracji zawartości](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/content_file.md).
|
|
470
|
+
|
|
471
|
+
> Jeśli Twój plik zawartości zawiera kod TSX, powinieneś rozważyć import `import React from "react";` w swoim pliku zawartości.
|
|
472
|
+
|
|
473
|
+
### Krok 5: Wykorzystaj Intlayer w swoim kodzie
|
|
474
|
+
|
|
475
|
+
Uzyskaj dostęp do swoich słowników treści w całej aplikacji:
|
|
476
|
+
|
|
477
|
+
```tsx {5,9} fileName="src/App.tsx" codeFormat="typescript"
|
|
478
|
+
import { useState, type FC } from "react";
|
|
479
|
+
import reactLogo from "./assets/react.svg";
|
|
480
|
+
import viteLogo from "/vite.svg";
|
|
481
|
+
import "./App.css";
|
|
482
|
+
import { IntlayerProvider, useIntlayer } from "react-intlayer";
|
|
483
|
+
|
|
484
|
+
const AppContent: FC = () => {
|
|
485
|
+
const [count, setCount] = useState(0);
|
|
486
|
+
const content = useIntlayer("app");
|
|
487
|
+
|
|
488
|
+
return (
|
|
489
|
+
<>
|
|
490
|
+
<div>
|
|
491
|
+
<a href="https://vitejs.dev" target="_blank">
|
|
492
|
+
<img src={viteLogo} className="logo" alt={content.viteLogo.value} />
|
|
493
|
+
</a>
|
|
494
|
+
<a href="https://react.dev" target="_blank">
|
|
495
|
+
<img
|
|
496
|
+
src={reactLogo}
|
|
497
|
+
className="logo react"
|
|
498
|
+
alt={content.reactLogo.value}
|
|
499
|
+
/>
|
|
500
|
+
</a>
|
|
501
|
+
</div>
|
|
502
|
+
<h1>{content.title}</h1>
|
|
503
|
+
<div className="card">
|
|
504
|
+
<button onClick={() => setCount((count) => count + 1)}>
|
|
505
|
+
{content.count}
|
|
506
|
+
{count}
|
|
507
|
+
</button>
|
|
508
|
+
<p>{content.edit}</p>
|
|
509
|
+
</div>
|
|
510
|
+
<p className="read-the-docs">{content.readTheDocs}</p>
|
|
511
|
+
</>
|
|
512
|
+
);
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
const App: FC = () => (
|
|
516
|
+
<IntlayerProvider>
|
|
517
|
+
<AppContent />
|
|
518
|
+
</IntlayerProvider>
|
|
519
|
+
);
|
|
520
|
+
|
|
521
|
+
export default App;
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
```tsx {5,9} fileName="src/App.msx" codeFormat="esm"
|
|
525
|
+
import { useState } from "react";
|
|
526
|
+
import reactLogo from "./assets/react.svg";
|
|
527
|
+
import viteLogo from "/vite.svg";
|
|
528
|
+
import "./App.css";
|
|
529
|
+
import { IntlayerProvider, useIntlayer } from "react-intlayer";
|
|
530
|
+
|
|
531
|
+
const AppContent = () => {
|
|
532
|
+
const [count, setCount] = useState(0);
|
|
533
|
+
const content = useIntlayer("app");
|
|
534
|
+
|
|
535
|
+
return (
|
|
536
|
+
<>
|
|
537
|
+
<div>
|
|
538
|
+
<a href="https://vitejs.dev" target="_blank">
|
|
539
|
+
<img src={viteLogo} className="logo" alt={content.viteLogo.value} />
|
|
540
|
+
</a>
|
|
541
|
+
<a href="https://react.dev" target="_blank">
|
|
542
|
+
<img
|
|
543
|
+
src={reactLogo}
|
|
544
|
+
className="logo react"
|
|
545
|
+
alt={content.reactLogo.value}
|
|
546
|
+
/>
|
|
547
|
+
</a>
|
|
548
|
+
</div>
|
|
549
|
+
<h1>{content.title}</h1>
|
|
550
|
+
<div className="card">
|
|
551
|
+
<button onClick={() => setCount((count) => count + 1)}>
|
|
552
|
+
{content.count}
|
|
553
|
+
{count}
|
|
554
|
+
</button>
|
|
555
|
+
<p>{content.edit}</p>
|
|
556
|
+
</div>
|
|
557
|
+
<p className="read-the-docs">{content.readTheDocs}</p>
|
|
558
|
+
</>
|
|
559
|
+
);
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
const App = () => (
|
|
563
|
+
<IntlayerProvider>
|
|
564
|
+
<AppContent />
|
|
565
|
+
</IntlayerProvider>
|
|
566
|
+
);
|
|
567
|
+
|
|
568
|
+
export default App;
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
```tsx {5,9} fileName="src/App.csx" codeFormat="commonjs"
|
|
572
|
+
const { useState } = require("react");
|
|
573
|
+
const reactLogo = require("./assets/react.svg");
|
|
574
|
+
const viteLogo = require("/vite.svg");
|
|
575
|
+
require("./App.css");
|
|
576
|
+
const { IntlayerProvider, useIntlayer } = require("react-intlayer");
|
|
577
|
+
|
|
578
|
+
const AppContent = () => {
|
|
579
|
+
const [count, setCount] = useState(0);
|
|
580
|
+
const content = useIntlayer("app");
|
|
581
|
+
|
|
582
|
+
return (
|
|
583
|
+
<>
|
|
584
|
+
<div>
|
|
585
|
+
<a href="https://vitejs.dev" target="_blank">
|
|
586
|
+
<img src={viteLogo} className="logo" alt={content.viteLogo.value} />
|
|
587
|
+
</a>
|
|
588
|
+
<a href="https://react.dev" target="_blank">
|
|
589
|
+
<img
|
|
590
|
+
src={reactLogo}
|
|
591
|
+
className="logo react"
|
|
592
|
+
alt={content.reactLogo.value}
|
|
593
|
+
/>
|
|
594
|
+
</a>
|
|
595
|
+
</div>
|
|
596
|
+
<h1>{content.title}</h1>
|
|
597
|
+
<div className="card">
|
|
598
|
+
<button onClick={() => setCount((count) => count + 1)}>
|
|
599
|
+
{content.count}
|
|
600
|
+
{count}
|
|
601
|
+
</button>
|
|
602
|
+
<p>{content.edit}</p>
|
|
603
|
+
</div>
|
|
604
|
+
<p className="read-the-docs">{content.readTheDocs}</p>
|
|
605
|
+
</>
|
|
606
|
+
);
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
const App = () => (
|
|
610
|
+
<IntlayerProvider>
|
|
611
|
+
<AppContent />
|
|
612
|
+
</IntlayerProvider>
|
|
613
|
+
);
|
|
614
|
+
|
|
615
|
+
module.exports = App;
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
> Jeśli chcesz użyć swojej zawartości w atrybucie typu `string`, takim jak `alt`, `title`, `href`, `aria-label` itp., musisz wywołać wartość funkcji, na przykład:
|
|
619
|
+
|
|
620
|
+
> ```jsx
|
|
621
|
+
> <img src={content.image.src.value} alt={content.image.value} />
|
|
622
|
+
> ```
|
|
623
|
+
|
|
624
|
+
> Aby dowiedzieć się więcej o hooku `useIntlayer`, zapoznaj się z [dokumentacją](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/react-intlayer/useIntlayer.md).
|
|
625
|
+
|
|
626
|
+
### (Opcjonalny) Krok 6: Zmień język swojej zawartości
|
|
627
|
+
|
|
628
|
+
Aby zmienić język swojej zawartości, możesz użyć funkcji `setLocale` dostarczonej przez hook `useLocale`. Funkcja ta pozwala ustawić lokalizację aplikacji i odpowiednio zaktualizować zawartość.
|
|
629
|
+
|
|
630
|
+
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
|
|
631
|
+
import type { FC } from "react";
|
|
632
|
+
import { Locales } from "intlayer";
|
|
633
|
+
import { useLocale } from "react-intlayer";
|
|
634
|
+
|
|
635
|
+
const LocaleSwitcher: FC = () => {
|
|
636
|
+
const { setLocale } = useLocale();
|
|
637
|
+
|
|
638
|
+
return (
|
|
639
|
+
<button onClick={() => setLocale(Locales.English)}>
|
|
640
|
+
Zmień język na angielski
|
|
641
|
+
</button>
|
|
642
|
+
);
|
|
643
|
+
};
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
```jsx fileName="src/components/LocaleSwitcher.msx" codeFormat="esm"
|
|
647
|
+
import { Locales } from "intlayer";
|
|
648
|
+
import { useLocale } from "react-intlayer";
|
|
649
|
+
|
|
650
|
+
const LocaleSwitcher = () => {
|
|
651
|
+
const { setLocale } = useLocale();
|
|
652
|
+
|
|
653
|
+
return (
|
|
654
|
+
<button onClick={() => setLocale(Locales.English)}>
|
|
655
|
+
Zmień język na angielski
|
|
656
|
+
</button>
|
|
657
|
+
);
|
|
658
|
+
};
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
```jsx fileName="src/components/LocaleSwitcher.csx" codeFormat="commonjs"
|
|
662
|
+
const { Locales } = require("intlayer");
|
|
663
|
+
const { useLocale } = require("react-intlayer");
|
|
664
|
+
|
|
665
|
+
const LocaleSwitcher = () => {
|
|
666
|
+
const { setLocale } = useLocale();
|
|
667
|
+
|
|
668
|
+
return (
|
|
669
|
+
<button onClick={() => setLocale(Locales.English)}>
|
|
670
|
+
Zmień język na angielski
|
|
671
|
+
</button>
|
|
672
|
+
);
|
|
673
|
+
};
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
> Aby dowiedzieć się więcej o hooku `useLocale`, zapoznaj się z [dokumentacją](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/react-intlayer/useLocale.md).
|
|
677
|
+
|
|
678
|
+
### (Opcjonalny) Krok 7: Dodaj lokalizowane routingi do swojej aplikacji
|
|
679
|
+
|
|
680
|
+
Celem tego kroku jest utworzenie unikalnych ścieżek dla każdego języka. Jest to przydatne dla SEO oraz przyjaznych dla SEO adresów URL.
|
|
681
|
+
Przykład:
|
|
682
|
+
|
|
683
|
+
```plaintext
|
|
684
|
+
- https://example.com/about
|
|
685
|
+
- https://example.com/es/about
|
|
686
|
+
- https://example.com/fr/about
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
> Domyślnie trasy nie mają prefiksu dla domyślnej lokalizacji. Jeśli chcesz dodać prefiks dla domyślnej lokalizacji, możesz ustawić opcję `middleware.prefixDefault` na `true` w swojej konfiguracji. Więcej informacji znajdziesz w [dokumentacji konfiguracji](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/configuration.md).
|
|
690
|
+
|
|
691
|
+
Aby dodać lokalizowane routingi do swojej aplikacji, możesz utworzyć komponent `LocaleRouter`, który opakuje trasy Twojej aplikacji i obsłuży routing oparty na lokalizacji. Oto przykład z użyciem [React Router](https://reactrouter.com/home):
|
|
692
|
+
|
|
693
|
+
```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
|
|
694
|
+
import { localeMap } from "intlayer"; // Funkcje narzędziowe i typy z 'intlayer'
|
|
695
|
+
import type { FC, PropsWithChildren } from "react"; // Typy React dla komponentów funkcyjnych i propsów
|
|
696
|
+
import { IntlayerProvider } from "react-intlayer"; // Provider dla kontekstu internacjonalizacji
|
|
697
|
+
import { BrowserRouter, Route, Routes } from "react-router-dom"; // Komponenty routera do zarządzania nawigacją
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Komponent routera, który ustawia trasy specyficzne dla lokalizacji.
|
|
701
|
+
* Używa React Router do zarządzania nawigacją i renderowania zlokalizowanych komponentów.
|
|
702
|
+
*/
|
|
703
|
+
export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
|
|
704
|
+
<BrowserRouter>
|
|
705
|
+
<Routes>
|
|
706
|
+
{localeMap(({ locale, urlPrefix }) => (
|
|
707
|
+
<Route
|
|
708
|
+
// Wzorzec trasy do przechwytywania lokalizacji (np. /en/, /fr/) i dopasowania wszystkich kolejnych ścieżek
|
|
709
|
+
path={`${urlPrefix}/*`}
|
|
710
|
+
key={locale}
|
|
711
|
+
element={
|
|
712
|
+
import { localeMap } from 'intlayer'; // Funkcje narzędziowe i typy z 'intlayer'
|
|
713
|
+
import type { FC, PropsWithChildren } from 'react'; // Typy React dla komponentów funkcyjnych i propsów
|
|
714
|
+
import { IntlayerProvider } from 'react-intlayer'; // Provider dla kontekstu internacjonalizacji
|
|
715
|
+
import { BrowserRouter, Route, Routes } from 'react-router-dom'; // Komponenty routera do zarządzania nawigacją
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Komponent routera, który ustawia trasy specyficzne dla lokalizacji.
|
|
719
|
+
* Używa React Router do zarządzania nawigacją i renderowania lokalizowanych komponentów.
|
|
720
|
+
*/
|
|
721
|
+
export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
|
|
722
|
+
<BrowserRouter>
|
|
723
|
+
<Routes>
|
|
724
|
+
{localeMap(({ locale, urlPrefix }) => (
|
|
725
|
+
<Route
|
|
726
|
+
// Wzorzec trasy do przechwytywania lokalizacji (np. /en/, /fr/) i dopasowania wszystkich kolejnych ścieżek
|
|
727
|
+
path={`${urlPrefix}/*`}
|
|
728
|
+
key={locale}
|
|
729
|
+
element={
|
|
730
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
731
|
+
} // Opakowuje dzieci zarządzaniem lokalizacją
|
|
732
|
+
/>
|
|
733
|
+
))}
|
|
734
|
+
</Routes>
|
|
735
|
+
</BrowserRouter>
|
|
736
|
+
);
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
```jsx fileName="src/components/LocaleRouter.cjx" codeFormat="commonjs"
|
|
740
|
+
const { localeMap } = require("intlayer"); // Funkcje narzędziowe i typy z 'intlayer'
|
|
741
|
+
const React = require("react"); // Import React
|
|
742
|
+
const { IntlayerProvider } = require("react-intlayer"); // Provider kontekstu internacjonalizacji
|
|
743
|
+
const { BrowserRouter, Route, Routes } = require("react-router-dom"); // Komponenty routera do zarządzania nawigacją
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Komponent routera, który ustawia trasy specyficzne dla lokalizacji.
|
|
747
|
+
* Używa React Router do zarządzania nawigacją i renderowania zlokalizowanych komponentów.
|
|
748
|
+
*/
|
|
749
|
+
const LocaleRouter = ({ children }) =>
|
|
750
|
+
React.createElement(
|
|
751
|
+
BrowserRouter,
|
|
752
|
+
{},
|
|
753
|
+
React.createElement(
|
|
754
|
+
Routes,
|
|
755
|
+
{},
|
|
756
|
+
localeMap(({ locale, urlPrefix }) =>
|
|
757
|
+
React.createElement(Route, {
|
|
758
|
+
path: `${urlPrefix}/*`,
|
|
759
|
+
key: locale,
|
|
760
|
+
element: React.createElement(IntlayerProvider, { locale }, children),
|
|
761
|
+
})
|
|
762
|
+
)
|
|
763
|
+
)
|
|
764
|
+
);
|
|
765
|
+
|
|
766
|
+
exports.LocaleRouter = LocaleRouter;
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
> Uwaga: Jeśli używasz `routing.mode: 'no-prefix' | 'search-params'`, prawdopodobnie nie musisz używać funkcji `localeMap`.
|
|
770
|
+
|
|
771
|
+
Następnie możesz użyć komponentu `LocaleRouter` w swojej aplikacji:
|
|
772
|
+
|
|
773
|
+
```tsx fileName="src/App.tsx" codeFormat="typescript"
|
|
774
|
+
import { LocaleRouter } from "./components/LocaleRouter";
|
|
775
|
+
import type { FC } from "react";
|
|
776
|
+
|
|
777
|
+
// ... Twój komponent AppContent
|
|
778
|
+
|
|
779
|
+
const App: FC = () => (
|
|
780
|
+
<LocaleRouter>
|
|
781
|
+
<AppContent />
|
|
782
|
+
</LocaleRouter>
|
|
783
|
+
);
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
```jsx fileName="src/App.mjx" codeFormat="esm"
|
|
787
|
+
import { LocaleRouter } from "./components/LocaleRouter";
|
|
788
|
+
|
|
789
|
+
// ... Twój komponent AppContent
|
|
790
|
+
|
|
791
|
+
const App = () => (
|
|
792
|
+
<LocaleRouter>
|
|
793
|
+
<AppContent />
|
|
794
|
+
</LocaleRouter>
|
|
795
|
+
);
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
```jsx fileName="src/App.cjx" codeFormat="commonjs"
|
|
799
|
+
const { LocaleRouter } = require("./components/LocaleRouter");
|
|
800
|
+
|
|
801
|
+
// ... Twój komponent AppContent
|
|
802
|
+
|
|
803
|
+
const App = () => (
|
|
804
|
+
<LocaleRouter>
|
|
805
|
+
<AppContent />
|
|
806
|
+
</LocaleRouter>
|
|
807
|
+
);
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
Równolegle możesz również użyć `intlayerMiddleware`, aby dodać routing po stronie serwera do swojej aplikacji. Ten plugin automatycznie wykryje bieżącą lokalizację na podstawie URL i ustawi odpowiedni cookie lokalizacji. Jeśli lokalizacja nie jest określona, plugin wybierze najbardziej odpowiednią lokalizację na podstawie preferencji językowych przeglądarki użytkownika. Jeśli żadna lokalizacja nie zostanie wykryta, nastąpi przekierowanie do domyślnej lokalizacji.
|
|
811
|
+
|
|
812
|
+
> Uwaga: aby używać `intlayerMiddleware` w produkcji, musisz przenieść pakiet `vite-intlayer` z `devDependencies` do `dependencies`.
|
|
813
|
+
|
|
814
|
+
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
815
|
+
import { defineConfig } from "vite";
|
|
816
|
+
import react from "@vitejs/plugin-react-swc";
|
|
817
|
+
import { intlayer, intlayerMiddleware } from "vite-intlayer";
|
|
818
|
+
|
|
819
|
+
// https://vitejs.dev/config/
|
|
820
|
+
export default defineConfig({
|
|
821
|
+
plugins: [react(), intlayer(), intlayerMiddleware()],
|
|
822
|
+
});
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
|
|
826
|
+
import { defineConfig } from "vite";
|
|
827
|
+
import react from "@vitejs/plugin-react-swc";
|
|
828
|
+
import { intlayer, intlayerMiddleware } from "vite-intlayer";
|
|
829
|
+
|
|
830
|
+
// https://vitejs.dev/config/
|
|
831
|
+
export default defineConfig({
|
|
832
|
+
plugins: [react(), intlayer(), intlayerMiddleware()],
|
|
833
|
+
});
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
|
|
837
|
+
const { defineConfig } = require("vite");
|
|
838
|
+
const react = require("@vitejs/plugin-react-swc");
|
|
839
|
+
const { intlayer, intlayerMiddleware } = require("vite-intlayer");
|
|
840
|
+
|
|
841
|
+
// https://vitejs.dev/config/
|
|
842
|
+
module.exports = defineConfig({
|
|
843
|
+
plugins: [react(), intlayer(), intlayerMiddleware()],
|
|
844
|
+
});
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
### (Opcjonalny) Krok 8: Zmiana URL po zmianie lokalizacji
|
|
848
|
+
|
|
849
|
+
Aby zmienić URL po zmianie lokalizacji, możesz użyć właściwości `onLocaleChange` dostarczanej przez hook `useLocale`. Równolegle możesz użyć hooków `useLocation` i `useNavigate` z `react-router-dom`, aby zaktualizować ścieżkę URL.
|
|
850
|
+
|
|
851
|
+
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
|
|
852
|
+
import { useLocation, useNavigate } from "react-router-dom";
|
|
853
|
+
import {
|
|
854
|
+
Locales,
|
|
855
|
+
getHTMLTextDir,
|
|
856
|
+
getLocaleName,
|
|
857
|
+
getLocalizedUrl,
|
|
858
|
+
} from "intlayer";
|
|
859
|
+
import { useLocale } from "react-intlayer";
|
|
860
|
+
import { type FC } from "react";
|
|
861
|
+
|
|
862
|
+
const LocaleSwitcher: FC = () => {
|
|
863
|
+
const { pathname, search } = useLocation(); // Pobierz aktualną ścieżkę URL. Przykład: /fr/about?foo=bar
|
|
864
|
+
const navigate = useNavigate();
|
|
865
|
+
|
|
866
|
+
const { locale, availableLocales, setLocale } = useLocale({
|
|
867
|
+
onLocaleChange: (locale) => {
|
|
868
|
+
// Zbuduj URL z zaktualizowanym locale
|
|
869
|
+
// Przykład: /es/about?foo=bar
|
|
870
|
+
const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
|
|
871
|
+
|
|
872
|
+
// Zaktualizuj ścieżkę URL
|
|
873
|
+
navigate(pathWithLocale);
|
|
874
|
+
},
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
return (
|
|
878
|
+
<div>
|
|
879
|
+
<button popoverTarget="localePopover">{getLocaleName(locale)}</button>
|
|
880
|
+
<div id="localePopover" popover="auto">
|
|
881
|
+
{availableLocales.map((localeItem) => (
|
|
882
|
+
<a
|
|
883
|
+
href={getLocalizedUrl(location.pathname, localeItem)}
|
|
884
|
+
hrefLang={localeItem}
|
|
885
|
+
aria-current={locale === localeItem ? "page" : undefined}
|
|
886
|
+
onClick={(e) => {
|
|
887
|
+
e.preventDefault();
|
|
888
|
+
setLocale(localeItem);
|
|
889
|
+
}}
|
|
890
|
+
key={localeItem}
|
|
891
|
+
>
|
|
892
|
+
<span>
|
|
893
|
+
{/* Lokalizacja - np. FR */}
|
|
894
|
+
{localeItem}
|
|
895
|
+
</span>
|
|
896
|
+
<span>
|
|
897
|
+
{/* Język w swojej własnej lokalizacji - np. Français */}
|
|
898
|
+
{getLocaleName(localeItem, locale)}
|
|
899
|
+
</span>
|
|
900
|
+
<span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
|
|
901
|
+
{/* Język w bieżącej lokalizacji - np. Francés przy ustawionej lokalizacji Locales.SPANISH */}
|
|
902
|
+
{getLocaleName(localeItem)}
|
|
903
|
+
</span>
|
|
904
|
+
<span dir="ltr" lang={Locales.ENGLISH}>
|
|
905
|
+
{/* Język po angielsku - np. French */}
|
|
906
|
+
{getLocaleName(localeItem, Locales.ENGLISH)}
|
|
907
|
+
</span>
|
|
908
|
+
</a>
|
|
909
|
+
))}
|
|
910
|
+
</div>
|
|
911
|
+
</div>
|
|
912
|
+
);
|
|
913
|
+
};
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
```jsx fileName="src/components/LocaleSwitcher.msx" codeFormat="esm"
|
|
917
|
+
import { useLocation, useNavigate } from "react-router-dom";
|
|
918
|
+
import {
|
|
919
|
+
Locales,
|
|
920
|
+
getHTMLTextDir,
|
|
921
|
+
getLocaleName,
|
|
922
|
+
getLocalizedUrl,
|
|
923
|
+
} from "intlayer";
|
|
924
|
+
import { useLocale } from "react-intlayer";
|
|
925
|
+
|
|
926
|
+
const LocaleSwitcher = () => {
|
|
927
|
+
const { pathname, search } = useLocation(); // Pobierz aktualną ścieżkę URL. Przykład: /fr/about?foo=bar
|
|
928
|
+
const navigate = useNavigate();
|
|
929
|
+
|
|
930
|
+
const { locale, availableLocales, setLocale } = useLocale({
|
|
931
|
+
onLocaleChange: (locale) => {
|
|
932
|
+
// Zbuduj URL z zaktualizowanym locale
|
|
933
|
+
// Przykład: /es/about?foo=bar
|
|
934
|
+
const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
|
|
935
|
+
|
|
936
|
+
// Aktualizacja ścieżki URL
|
|
937
|
+
navigate(pathWithLocale);
|
|
938
|
+
},
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
return (
|
|
942
|
+
<div>
|
|
943
|
+
<button popoverTarget="localePopover">{getLocaleName(locale)}</button>
|
|
944
|
+
<div id="localePopover" popover="auto">
|
|
945
|
+
{availableLocales.map((localeItem) => (
|
|
946
|
+
<a
|
|
947
|
+
href={getLocalizedUrl(location.pathname, localeItem)}
|
|
948
|
+
hrefLang={localeItem}
|
|
949
|
+
aria-current={locale === localeItem ? "page" : undefined}
|
|
950
|
+
onClick={(e) => {
|
|
951
|
+
e.preventDefault();
|
|
952
|
+
setLocale(localeItem);
|
|
953
|
+
}}
|
|
954
|
+
key={localeItem}
|
|
955
|
+
>
|
|
956
|
+
<span>
|
|
957
|
+
{/* Lokalizacja - np. FR */}
|
|
958
|
+
{localeItem}
|
|
959
|
+
</span>
|
|
960
|
+
<span>
|
|
961
|
+
{/* Język w jego własnej lokalizacji - np. Français */}
|
|
962
|
+
{getLocaleName(localeItem, locale)}
|
|
963
|
+
</span>
|
|
964
|
+
<span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
|
|
965
|
+
{/* Język w bieżącej lokalizacji - np. Francés przy ustawionej lokalizacji Locales.SPANISH */}
|
|
966
|
+
{getLocaleName(localeItem)}
|
|
967
|
+
</span>
|
|
968
|
+
<span dir="ltr" lang={Locales.ENGLISH}>
|
|
969
|
+
{/* Język po angielsku - np. French */}
|
|
970
|
+
{getLocaleName(localeItem, Locales.ENGLISH)}
|
|
971
|
+
</span>
|
|
972
|
+
</a>
|
|
973
|
+
))}
|
|
974
|
+
</div>
|
|
975
|
+
</div>
|
|
976
|
+
);
|
|
977
|
+
};
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
```jsx fileName="src/components/LocaleSwitcher.csx" codeFormat="commonjs"
|
|
981
|
+
const { useLocation, useNavigate } = require("react-router-dom");
|
|
982
|
+
const {
|
|
983
|
+
Locales,
|
|
984
|
+
getHTMLTextDir,
|
|
985
|
+
getLocaleName,
|
|
986
|
+
getLocalizedUrl,
|
|
987
|
+
} = require("intlayer");
|
|
988
|
+
const { useLocale } = require("react-intlayer");
|
|
989
|
+
|
|
990
|
+
const LocaleSwitcher = () => {
|
|
991
|
+
const { pathname, search } = useLocation(); // Pobierz aktualną ścieżkę URL. Przykład: /fr/about?foo=bar
|
|
992
|
+
const navigate = useNavigate();
|
|
993
|
+
|
|
994
|
+
const { locale, availableLocales, setLocale } = useLocale({
|
|
995
|
+
onLocaleChange: (locale) => {
|
|
996
|
+
// Utwórz URL z zaktualizowanym locale
|
|
997
|
+
// Przykład: /es/about?foo=bar
|
|
998
|
+
const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
|
|
999
|
+
|
|
1000
|
+
// Zaktualizuj ścieżkę URL
|
|
1001
|
+
navigate(pathWithLocale);
|
|
1002
|
+
},
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
return (
|
|
1006
|
+
<div>
|
|
1007
|
+
<button popoverTarget="localePopover">{getLocaleName(locale)}</button>
|
|
1008
|
+
<div id="localePopover" popover="auto">
|
|
1009
|
+
{availableLocales.map((localeItem) => (
|
|
1010
|
+
<a
|
|
1011
|
+
href={getLocalizedUrl(location.pathname, localeItem)}
|
|
1012
|
+
hrefLang={localeItem}
|
|
1013
|
+
aria-current={locale === localeItem ? "page" : undefined}
|
|
1014
|
+
onClick={(e) => {
|
|
1015
|
+
e.preventDefault();
|
|
1016
|
+
setLocale(localeItem);
|
|
1017
|
+
}}
|
|
1018
|
+
key={localeItem}
|
|
1019
|
+
>
|
|
1020
|
+
<span>
|
|
1021
|
+
{/* Lokalizacja - np. FR */}
|
|
1022
|
+
{localeItem}
|
|
1023
|
+
</span>
|
|
1024
|
+
<span>
|
|
1025
|
+
{/* Język w jego własnej lokalizacji - np. Français */}
|
|
1026
|
+
{getLocaleName(localeItem, locale)}
|
|
1027
|
+
</span>
|
|
1028
|
+
<span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
|
|
1029
|
+
{/* Język w bieżącej lokalizacji - np. Francés przy ustawionej lokalizacji Locales.SPANISH */}
|
|
1030
|
+
{getLocaleName(localeItem)}
|
|
1031
|
+
</span>
|
|
1032
|
+
<span dir="ltr" lang={Locales.ENGLISH}>
|
|
1033
|
+
{/* Język po angielsku - np. French */}
|
|
1034
|
+
{getLocaleName(localeItem, Locales.ENGLISH)}
|
|
1035
|
+
</span>
|
|
1036
|
+
</a>
|
|
1037
|
+
))}
|
|
1038
|
+
</div>
|
|
1039
|
+
</div>
|
|
1040
|
+
);
|
|
1041
|
+
};
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
> Odniesienia do dokumentacji:
|
|
1045
|
+
>
|
|
1046
|
+
> - [`useLocale` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/react-intlayer/useLocale.md)
|
|
1047
|
+
> - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/intlayer/getLocaleName.md)
|
|
1048
|
+
> - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/intlayer/getLocalizedUrl.md)
|
|
1049
|
+
> - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/intlayer/getHTMLTextDir.md)
|
|
1050
|
+
> - [`hrefLang` attribute](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
|
|
1051
|
+
> - [`lang` attribute](https://developer.mozilla.org/pl/docs/Web/HTML/Global_attributes/lang)
|
|
1052
|
+
> - [`dir` attribute`](https://developer.mozilla.org/pl/docs/Web/HTML/Global_attributes/dir)
|
|
1053
|
+
> - [`aria-current` attribute`](https://developer.mozilla.org/pl/docs/Web/Accessibility/ARIA/Attributes/aria-current)
|
|
1054
|
+
|
|
1055
|
+
Poniżej znajduje się zaktualizowany **Krok 9** z dodatkowymi wyjaśnieniami i dopracowanymi przykładami kodu:
|
|
1056
|
+
|
|
1057
|
+
---
|
|
1058
|
+
|
|
1059
|
+
### (Opcjonalny) Krok 9: Zmiana atrybutów języka i kierunku w elemencie HTML
|
|
1060
|
+
|
|
1061
|
+
Gdy Twoja aplikacja obsługuje wiele języków, kluczowe jest zaktualizowanie atrybutów `lang` i `dir` w tagu `<html>`, aby odpowiadały bieżącej lokalizacji. Zapewnia to:
|
|
1062
|
+
|
|
1063
|
+
- **Dostępność**: Czytniki ekranu i technologie wspomagające polegają na poprawnym atrybucie `lang`, aby prawidłowo wymawiać i interpretować zawartość.
|
|
1064
|
+
- **Renderowanie tekstu**: Atrybut `dir` (kierunek) zapewnia, że tekst jest wyświetlany w odpowiedniej kolejności (np. od lewej do prawej dla angielskiego, od prawej do lewej dla arabskiego lub hebrajskiego), co jest niezbędne dla czytelności.
|
|
1065
|
+
- **SEO**: Wyszukiwarki używają atrybutu `lang`, aby określić język Twojej strony, co pomaga w serwowaniu odpowiednio zlokalizowanych treści w wynikach wyszukiwania.
|
|
1066
|
+
|
|
1067
|
+
Aktualizując te atrybuty dynamicznie przy zmianie lokalizacji, zapewniasz spójne i dostępne doświadczenie dla użytkowników we wszystkich obsługiwanych językach.
|
|
1068
|
+
|
|
1069
|
+
#### Implementacja Hooka
|
|
1070
|
+
|
|
1071
|
+
Utwórz niestandardowy hook do zarządzania atrybutami HTML. Hook nasłuchuje zmian lokalizacji i odpowiednio aktualizuje atrybuty:
|
|
1072
|
+
|
|
1073
|
+
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat="typescript"
|
|
1074
|
+
import { useEffect } from "react";
|
|
1075
|
+
import { useLocale } from "react-intlayer";
|
|
1076
|
+
import { getHTMLTextDir } from "intlayer";
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* Aktualizuje atrybuty `lang` i `dir` elementu HTML <html> na podstawie bieżącej lokalizacji.
|
|
1080
|
+
* - `lang`: Informuje przeglądarki i wyszukiwarki o języku strony.
|
|
1081
|
+
* - `dir`: Zapewnia prawidłowy kierunek czytania (np. 'ltr' dla angielskiego, 'rtl' dla arabskiego).
|
|
1082
|
+
*
|
|
1083
|
+
* Ta dynamiczna aktualizacja jest niezbędna dla prawidłowego renderowania tekstu, dostępności oraz SEO.
|
|
1084
|
+
*/
|
|
1085
|
+
export const useI18nHTMLAttributes = () => {
|
|
1086
|
+
const { locale } = useLocale();
|
|
1087
|
+
|
|
1088
|
+
useEffect(() => {
|
|
1089
|
+
// Aktualizuj atrybut języka na bieżący locale.
|
|
1090
|
+
document.documentElement.lang = locale;
|
|
1091
|
+
|
|
1092
|
+
// Ustaw kierunek tekstu na podstawie bieżącego locale.
|
|
1093
|
+
document.documentElement.dir = getHTMLTextDir(locale);
|
|
1094
|
+
}, [locale]);
|
|
1095
|
+
};
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
```jsx fileName="src/hooks/useI18nHTMLAttributes.msx" codeFormat="esm"
|
|
1099
|
+
import { useEffect } from "react";
|
|
1100
|
+
import { useLocale } from "react-intlayer";
|
|
1101
|
+
import { getHTMLTextDir } from "intlayer";
|
|
1102
|
+
|
|
1103
|
+
/**
|
|
1104
|
+
* Aktualizuje atrybuty `lang` i `dir` elementu HTML <html> na podstawie bieżącego locale.
|
|
1105
|
+
* - `lang`: Informuje przeglądarki i wyszukiwarki o języku strony.
|
|
1106
|
+
* - `dir`: Zapewnia poprawny kierunek czytania (np. 'ltr' dla angielskiego, 'rtl' dla arabskiego).
|
|
1107
|
+
*
|
|
1108
|
+
* Ta dynamiczna aktualizacja jest niezbędna dla prawidłowego renderowania tekstu, dostępności i SEO.
|
|
1109
|
+
*/
|
|
1110
|
+
export const useI18nHTMLAttributes = () => {
|
|
1111
|
+
const { locale } = useLocale();
|
|
1112
|
+
|
|
1113
|
+
useEffect(() => {
|
|
1114
|
+
// Aktualizuj atrybut języka na bieżącą lokalizację.
|
|
1115
|
+
document.documentElement.lang = locale;
|
|
1116
|
+
|
|
1117
|
+
// Ustaw kierunek tekstu na podstawie bieżącej lokalizacji.
|
|
1118
|
+
document.documentElement.dir = getHTMLTextDir(locale);
|
|
1119
|
+
}, [locale]);
|
|
1120
|
+
};
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
```jsx fileName="src/hooks/useI18nHTMLAttributes.csx" codeFormat="commonjs"
|
|
1124
|
+
const { useEffect } = require("react");
|
|
1125
|
+
const { useLocale } = require("react-intlayer");
|
|
1126
|
+
const { getHTMLTextDir } = require("intlayer");
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* Aktualizuje atrybuty `lang` i `dir` elementu HTML <html> na podstawie aktualnej lokalizacji.
|
|
1130
|
+
* - `lang`: Informuje przeglądarki i wyszukiwarki o języku strony.
|
|
1131
|
+
* - `dir`: Zapewnia prawidłowy kierunek czytania (np. 'ltr' dla angielskiego, 'rtl' dla arabskiego).
|
|
1132
|
+
*
|
|
1133
|
+
* Ta dynamiczna aktualizacja jest niezbędna dla prawidłowego renderowania tekstu, dostępności oraz SEO.
|
|
1134
|
+
*/
|
|
1135
|
+
const useI18nHTMLAttributes = () => {
|
|
1136
|
+
const { locale } = useLocale();
|
|
1137
|
+
|
|
1138
|
+
useEffect(() => {
|
|
1139
|
+
// Aktualizuj atrybut języka na aktualną lokalizację.
|
|
1140
|
+
document.documentElement.lang = locale;
|
|
1141
|
+
|
|
1142
|
+
// Ustaw kierunek tekstu na podstawie aktualnej lokalizacji.
|
|
1143
|
+
document.documentElement.dir = getHTMLTextDir(locale);
|
|
1144
|
+
}, [locale]);
|
|
1145
|
+
};
|
|
1146
|
+
|
|
1147
|
+
module.exports = { useI18nHTMLAttributes };
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
#### Użycie Hooka w Twojej Aplikacji
|
|
1151
|
+
|
|
1152
|
+
Zintegruj hook w swoim głównym komponencie, aby atrybuty HTML były aktualizowane za każdym razem, gdy zmienia się locale:
|
|
1153
|
+
|
|
1154
|
+
```tsx fileName="src/App.tsx" codeFormat="typescript"
|
|
1155
|
+
import type { FC } from "react";
|
|
1156
|
+
import { IntlayerProvider, useIntlayer } from "react-intlayer";
|
|
1157
|
+
import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
|
|
1158
|
+
import "./App.css";
|
|
1159
|
+
|
|
1160
|
+
const AppContent: FC = () => {
|
|
1161
|
+
// Zastosuj hook, aby aktualizować atrybuty lang i dir tagu <html> na podstawie locale.
|
|
1162
|
+
useI18nHTMLAttributes();
|
|
1163
|
+
|
|
1164
|
+
// ... Reszta twojego komponentu
|
|
1165
|
+
};
|
|
1166
|
+
|
|
1167
|
+
const App: FC = () => (
|
|
1168
|
+
<IntlayerProvider>
|
|
1169
|
+
<AppContent />
|
|
1170
|
+
</IntlayerProvider>
|
|
1171
|
+
);
|
|
1172
|
+
|
|
1173
|
+
export default App;
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
```jsx fileName="src/App.msx" codeFormat="esm"
|
|
1177
|
+
import { IntlayerProvider, useIntlayer } from "react-intlayer";
|
|
1178
|
+
import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
|
|
1179
|
+
import "./App.css";
|
|
1180
|
+
|
|
1181
|
+
const AppContent = () => {
|
|
1182
|
+
// Zastosuj hook, aby aktualizować atrybuty lang i dir tagu <html> w zależności od lokalizacji.
|
|
1183
|
+
useI18nHTMLAttributes();
|
|
1184
|
+
|
|
1185
|
+
// ... Reszta twojego komponentu
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
const App = () => (
|
|
1189
|
+
<IntlayerProvider>
|
|
1190
|
+
<AppContent />
|
|
1191
|
+
</IntlayerProvider>
|
|
1192
|
+
);
|
|
1193
|
+
|
|
1194
|
+
export default App;
|
|
1195
|
+
```
|
|
1196
|
+
|
|
1197
|
+
```jsx fileName="src/App.csx" codeFormat="commonjs"
|
|
1198
|
+
const { FC } = require("react");
|
|
1199
|
+
const { IntlayerProvider, useIntlayer } = require("react-intlayer");
|
|
1200
|
+
const { useI18nHTMLAttributes } = require("./hooks/useI18nHTMLAttributes");
|
|
1201
|
+
require("./App.css");
|
|
1202
|
+
|
|
1203
|
+
const AppContent = () => {
|
|
1204
|
+
// Zastosuj hook, aby aktualizować atrybuty lang i dir tagu <html> w zależności od lokalizacji.
|
|
1205
|
+
useI18nHTMLAttributes();
|
|
1206
|
+
|
|
1207
|
+
// ... Reszta twojego komponentu
|
|
1208
|
+
};
|
|
1209
|
+
|
|
1210
|
+
const App = () => (
|
|
1211
|
+
<IntlayerProvider>
|
|
1212
|
+
<AppContent />
|
|
1213
|
+
</IntlayerProvider>
|
|
1214
|
+
);
|
|
1215
|
+
|
|
1216
|
+
module.exports = App;
|
|
1217
|
+
// Zastosuj hook, aby zaktualizować atrybuty lang i dir tagu <html> na podstawie lokalizacji.
|
|
1218
|
+
useI18nHTMLAttributes();
|
|
1219
|
+
|
|
1220
|
+
// ... Reszta twojego komponentu
|
|
1221
|
+
};
|
|
1222
|
+
|
|
1223
|
+
const App = () => (
|
|
1224
|
+
<IntlayerProvider>
|
|
1225
|
+
<AppContent />
|
|
1226
|
+
</IntlayerProvider>
|
|
1227
|
+
);
|
|
1228
|
+
|
|
1229
|
+
module.exports = App;
|
|
1230
|
+
```
|
|
1231
|
+
|
|
1232
|
+
Wprowadzając te zmiany, twoja aplikacja:
|
|
1233
|
+
|
|
1234
|
+
- Zapewni, że atrybut **language** (`lang`) poprawnie odzwierciedla aktualną lokalizację, co jest ważne dla SEO i zachowania przeglądarki.
|
|
1235
|
+
- Dostosuje **kierunek tekstu** (`dir`) zgodnie z lokalizacją, poprawiając czytelność i użyteczność dla języków o różnych kierunkach czytania.
|
|
1236
|
+
- Zapewni bardziej **dostępne** doświadczenie, ponieważ technologie wspomagające polegają na tych atrybutach, aby działać optymalnie.
|
|
1237
|
+
|
|
1238
|
+
### (Opcjonalny) Krok 10: Tworzenie lokalizowanego komponentu Link
|
|
1239
|
+
|
|
1240
|
+
Aby zapewnić, że nawigacja w Twojej aplikacji respektuje aktualny język, możesz stworzyć niestandardowy komponent `Link`. Komponent ten automatycznie dodaje prefiks z aktualnym językiem do wewnętrznych adresów URL. Na przykład, gdy użytkownik mówiący po francusku kliknie link do strony "About", zostanie przekierowany na `/fr/about` zamiast na `/about`.
|
|
1241
|
+
|
|
1242
|
+
To zachowanie jest przydatne z kilku powodów:
|
|
1243
|
+
|
|
1244
|
+
- **SEO i doświadczenie użytkownika**: Lokalizowane adresy URL pomagają wyszukiwarkom poprawnie indeksować strony specyficzne dla języka oraz dostarczać użytkownikom treści w ich preferowanym języku.
|
|
1245
|
+
- **Spójność**: Korzystając z lokalizowanego linku w całej aplikacji, zapewniasz, że nawigacja pozostaje w obrębie aktualnego języka, zapobiegając nieoczekiwanym zmianom języka.
|
|
1246
|
+
- **Utrzymanie**: Centralizacja logiki lokalizacji w jednym komponencie upraszcza zarządzanie adresami URL, co sprawia, że Twoja baza kodu jest łatwiejsza do utrzymania i rozbudowy wraz z rozwojem aplikacji.
|
|
1247
|
+
|
|
1248
|
+
Poniżej znajduje się implementacja lokalizowanego komponentu `Link` w TypeScript:
|
|
1249
|
+
|
|
1250
|
+
```tsx fileName="src/components/Link.tsx" codeFormat="typescript"
|
|
1251
|
+
import { getLocalizedUrl } from "intlayer";
|
|
1252
|
+
import {
|
|
1253
|
+
forwardRef,
|
|
1254
|
+
type DetailedHTMLProps,
|
|
1255
|
+
type AnchorHTMLAttributes,
|
|
1256
|
+
} from "react";
|
|
1257
|
+
import { useLocale } from "react-intlayer";
|
|
1258
|
+
|
|
1259
|
+
export interface LinkProps
|
|
1260
|
+
extends DetailedHTMLProps<
|
|
1261
|
+
AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
1262
|
+
HTMLAnchorElement
|
|
1263
|
+
> {}
|
|
1264
|
+
|
|
1265
|
+
/**
|
|
1266
|
+
* Funkcja pomocnicza do sprawdzania, czy dany URL jest zewnętrzny.
|
|
1267
|
+
* Jeśli URL zaczyna się od http:// lub https://, jest uznawany za zewnętrzny.
|
|
1268
|
+
*/
|
|
1269
|
+
export const checkIsExternalLink = (href?: string): boolean =>
|
|
1270
|
+
/^https?:\/\//.test(href ?? "");
|
|
1271
|
+
|
|
1272
|
+
/**
|
|
1273
|
+
* Niestandardowy komponent Link, który dostosowuje atrybut href na podstawie bieżącej lokalizacji.
|
|
1274
|
+
* Dla linków wewnętrznych używa `getLocalizedUrl`, aby poprzedzić URL lokalizacją (np. /fr/about).
|
|
1275
|
+
* Zapewnia to, że nawigacja pozostaje w tym samym kontekście lokalizacyjnym.
|
|
1276
|
+
*/
|
|
1277
|
+
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
1278
|
+
({ href, children, ...props }, ref) => {
|
|
1279
|
+
const { locale } = useLocale();
|
|
1280
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1281
|
+
|
|
1282
|
+
// Jeśli link jest wewnętrzny i podano prawidłowy href, pobierz zlokalizowany URL.
|
|
1283
|
+
const hrefI18n =
|
|
1284
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1285
|
+
|
|
1286
|
+
return (
|
|
1287
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1288
|
+
{children}
|
|
1289
|
+
</a>
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1292
|
+
);
|
|
1293
|
+
|
|
1294
|
+
Link.displayName = "Link";
|
|
1295
|
+
```
|
|
1296
|
+
|
|
1297
|
+
```jsx fileName="src/components/Link.mjx" codeFormat="esm"
|
|
1298
|
+
import { getLocalizedUrl } from "intlayer";
|
|
1299
|
+
import { useLocale } from "react-intlayer";
|
|
1300
|
+
import { forwardRef } from "react";
|
|
1301
|
+
|
|
1302
|
+
/**
|
|
1303
|
+
* Funkcja pomocnicza do sprawdzania, czy podany URL jest zewnętrzny.
|
|
1304
|
+
* Jeśli URL zaczyna się od http:// lub https://, jest uznawany za zewnętrzny.
|
|
1305
|
+
*/
|
|
1306
|
+
export const checkIsExternalLink = (href?: string): boolean =>
|
|
1307
|
+
/^https?:\/\//.test(href ?? "");
|
|
1308
|
+
|
|
1309
|
+
/**
|
|
1310
|
+
* Niestandardowy komponent Link, który dostosowuje atrybut href na podstawie aktualnego języka.
|
|
1311
|
+
* Dla linków wewnętrznych używa `getLocalizedUrl`, aby dodać prefiks języka do URL (np. /fr/about).
|
|
1312
|
+
* Zapewnia to, że nawigacja pozostaje w kontekście tego samego języka.
|
|
1313
|
+
*/
|
|
1314
|
+
export const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1315
|
+
const { locale } = useLocale();
|
|
1316
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1317
|
+
|
|
1318
|
+
// Jeśli link jest wewnętrzny i podano prawidłowy href, pobierz zlokalizowany URL.
|
|
1319
|
+
const hrefI18n =
|
|
1320
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1321
|
+
|
|
1322
|
+
return (
|
|
1323
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1324
|
+
{children}
|
|
1325
|
+
</a>
|
|
1326
|
+
);
|
|
1327
|
+
});
|
|
1328
|
+
|
|
1329
|
+
Link.displayName = "Link";
|
|
1330
|
+
```
|
|
1331
|
+
|
|
1332
|
+
```jsx fileName="src/components/Link.csx" codeFormat="commonjs"
|
|
1333
|
+
const { getLocalizedUrl } = require("intlayer");
|
|
1334
|
+
const { useLocale } = require("react-intlayer");
|
|
1335
|
+
const { forwardRef } = require("react");
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* Funkcja pomocnicza do sprawdzania, czy podany URL jest zewnętrzny.
|
|
1339
|
+
* Jeśli URL zaczyna się od http:// lub https://, jest uznawany za zewnętrzny.
|
|
1340
|
+
*/
|
|
1341
|
+
const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
|
|
1342
|
+
|
|
1343
|
+
/**
|
|
1344
|
+
* Niestandardowy komponent Link, który dostosowuje atrybut href na podstawie bieżącej lokalizacji.
|
|
1345
|
+
* Dla linków wewnętrznych używa `getLocalizedUrl`, aby poprzedzić URL lokalizacją (np. /fr/about).
|
|
1346
|
+
* Zapewnia to, że nawigacja pozostaje w tym samym kontekście lokalizacji.
|
|
1347
|
+
*/
|
|
1348
|
+
const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1349
|
+
const { locale } = useLocale();
|
|
1350
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1351
|
+
|
|
1352
|
+
// Jeśli link jest wewnętrzny i podano prawidłowy href, pobierz zlokalizowany URL.
|
|
1353
|
+
const localizedHref = isExternalLink ? href : getLocalizedUrl(href, locale);
|
|
1354
|
+
|
|
1355
|
+
return (
|
|
1356
|
+
<a
|
|
1357
|
+
href={localizedHref}
|
|
1358
|
+
ref={ref}
|
|
1359
|
+
{...props}
|
|
1360
|
+
aria-current={isExternalLink ? "external" : undefined}
|
|
1361
|
+
>
|
|
1362
|
+
{children}
|
|
1363
|
+
</a>
|
|
1364
|
+
);
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
Link.displayName = "Link";
|
|
1368
|
+
```
|
|
1369
|
+
|
|
1370
|
+
#### Jak to działa
|
|
1371
|
+
|
|
1372
|
+
- **Wykrywanie linków zewnętrznych**:
|
|
1373
|
+
Funkcja pomocnicza `checkIsExternalLink` określa, czy URL jest zewnętrzny. Linki zewnętrzne pozostają niezmienione, ponieważ nie wymagają lokalizacji.
|
|
1374
|
+
|
|
1375
|
+
- **Pobieranie bieżącej lokalizacji**:
|
|
1376
|
+
Hook `useLocale` dostarcza aktualną lokalizację (np. `fr` dla języka francuskiego).
|
|
1377
|
+
|
|
1378
|
+
- **Lokalizacja URL**:
|
|
1379
|
+
Dla linków wewnętrznych (czyli nie zewnętrznych) używana jest funkcja `getLocalizedUrl`, która automatycznie dodaje prefiks lokalizacji do URL. Oznacza to, że jeśli użytkownik korzysta z wersji francuskiej, podanie `/about` jako `href` zostanie przekształcone na `/fr/about`.
|
|
1380
|
+
|
|
1381
|
+
- **Zwracanie linku**:
|
|
1382
|
+
Komponent zwraca element `<a>` z zlokalizowanym URL, zapewniając, że nawigacja jest spójna z wybraną lokalizacją.
|
|
1383
|
+
|
|
1384
|
+
Integrując ten komponent `Link` w całej aplikacji, utrzymujesz spójne i świadome językowo doświadczenie użytkownika, jednocześnie korzystając z poprawy SEO i użyteczności.
|
|
1385
|
+
|
|
1386
|
+
### Konfiguracja TypeScript
|
|
1387
|
+
|
|
1388
|
+
Intlayer wykorzystuje rozszerzenie modułów (module augmentation), aby korzystać z zalet TypeScript i wzmocnić Twoją bazę kodu.
|
|
1389
|
+
|
|
1390
|
+

|
|
1391
|
+
|
|
1392
|
+

|
|
1393
|
+
|
|
1394
|
+
Upewnij się, że Twoja konfiguracja TypeScript zawiera automatycznie generowane typy.
|
|
1395
|
+
|
|
1396
|
+
```json5 fileName="tsconfig.json"
|
|
1397
|
+
{
|
|
1398
|
+
// ... Twoje istniejące konfiguracje TypeScript
|
|
1399
|
+
"include": [
|
|
1400
|
+
// ... Twoje istniejące konfiguracje TypeScript
|
|
1401
|
+
".intlayer/**/*.ts", // Dołącz automatycznie generowane typy
|
|
1402
|
+
],
|
|
1403
|
+
}
|
|
1404
|
+
```
|
|
1405
|
+
|
|
1406
|
+
### Konfiguracja Git
|
|
1407
|
+
|
|
1408
|
+
Zaleca się ignorowanie plików generowanych przez Intlayer. Pozwala to uniknąć ich zatwierdzania do repozytorium Git.
|
|
1409
|
+
|
|
1410
|
+
Aby to zrobić, możesz dodać następujące instrukcje do pliku `.gitignore`:
|
|
1411
|
+
|
|
1412
|
+
```plaintext
|
|
1413
|
+
# Ignoruj pliki generowane przez Intlayer
|
|
1414
|
+
.intlayer
|
|
1415
|
+
```
|
|
1416
|
+
|
|
1417
|
+
### Rozszerzenie VS Code
|
|
1418
|
+
|
|
1419
|
+
Aby poprawić swoje doświadczenie programistyczne z Intlayer, możesz zainstalować oficjalne **rozszerzenie Intlayer dla VS Code**.
|
|
1420
|
+
|
|
1421
|
+
[Zainstaluj z Marketplace VS Code](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
|
|
1422
|
+
|
|
1423
|
+
To rozszerzenie zapewnia:
|
|
1424
|
+
|
|
1425
|
+
- **Autouzupełnianie** kluczy tłumaczeń.
|
|
1426
|
+
- **Wykrywanie błędów w czasie rzeczywistym** dla brakujących tłumaczeń.
|
|
1427
|
+
- **Podglądy w linii** przetłumaczonej zawartości.
|
|
1428
|
+
- **Szybkie akcje** umożliwiające łatwe tworzenie i aktualizowanie tłumaczeń.
|
|
1429
|
+
|
|
1430
|
+
Aby uzyskać więcej informacji na temat korzystania z rozszerzenia, zapoznaj się z [dokumentacją rozszerzenia Intlayer VS Code](https://intlayer.org/doc/vs-code-extension).
|
|
1431
|
+
|
|
1432
|
+
---
|
|
1433
|
+
|
|
1434
|
+
### Idź dalej
|
|
1435
|
+
|
|
1436
|
+
Aby pójść dalej, możesz zaimplementować [edytor wizualny](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_visual_editor.md) lub wyodrębnić swoją zawartość, korzystając z [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_CMS.md).
|
|
1437
|
+
|
|
1438
|
+
---
|