@intlayer/docs 5.8.1 → 6.0.0-canary.1
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/rag_powered_documentation_assistant.md +282 -0
- package/blog/de/rag_powered_documentation_assistant.md +282 -0
- package/blog/en/rag_powered_documentation_assistant.md +289 -0
- package/blog/en-GB/rag_powered_documentation_assistant.md +284 -0
- package/blog/es/rag_powered_documentation_assistant.md +308 -0
- package/blog/fr/rag_powered_documentation_assistant.md +308 -0
- package/blog/hi/rag_powered_documentation_assistant.md +284 -0
- package/blog/it/rag_powered_documentation_assistant.md +284 -0
- package/blog/ja/rag_powered_documentation_assistant.md +284 -0
- package/blog/ko/rag_powered_documentation_assistant.md +283 -0
- package/blog/pt/rag_powered_documentation_assistant.md +284 -0
- package/blog/ru/rag_powered_documentation_assistant.md +284 -0
- package/blog/tr/index.md +69 -0
- package/blog/tr/internationalization_and_SEO.md +273 -0
- package/blog/tr/intlayer_with_i18next.md +162 -0
- package/blog/tr/intlayer_with_next-i18next.md +367 -0
- package/blog/tr/intlayer_with_next-intl.md +392 -0
- package/blog/tr/intlayer_with_react-i18next.md +346 -0
- package/blog/tr/intlayer_with_react-intl.md +345 -0
- package/blog/tr/list_i18n_technologies/CMS/drupal.md +143 -0
- package/blog/tr/list_i18n_technologies/CMS/wix.md +167 -0
- package/blog/tr/list_i18n_technologies/CMS/wordpress.md +188 -0
- package/blog/tr/list_i18n_technologies/frameworks/angular.md +125 -0
- package/blog/tr/list_i18n_technologies/frameworks/flutter.md +150 -0
- package/blog/tr/list_i18n_technologies/frameworks/react-native.md +217 -0
- package/blog/tr/list_i18n_technologies/frameworks/react.md +155 -0
- package/blog/tr/list_i18n_technologies/frameworks/svelte.md +129 -0
- package/blog/tr/list_i18n_technologies/frameworks/vue.md +130 -0
- package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +170 -0
- package/blog/tr/rag_powered_documentation_assistant.md +284 -0
- package/blog/tr/react-i18next_vs_react-intl_vs_intlayer.md +162 -0
- package/blog/tr/vue-i18n_vs_intlayer.md +276 -0
- package/blog/tr/what_is_internationalization.md +166 -0
- package/blog/zh/rag_powered_documentation_assistant.md +284 -0
- package/dist/cjs/generated/blog.entry.cjs +212 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +660 -132
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +84 -0
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +6 -0
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +212 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +660 -132
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +84 -0
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs +6 -0
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts +1 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +5 -2
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
- package/dist/types/generated/legal.entry.d.ts.map +1 -1
- package/docs/ar/autoFill.md +41 -40
- package/docs/ar/configuration.md +202 -199
- package/docs/ar/dictionary/content_file.md +1059 -0
- package/docs/ar/intlayer_CMS.md +4 -4
- package/docs/ar/intlayer_with_nestjs.md +271 -0
- package/docs/ar/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ar/intlayer_with_react_router_v7.md +533 -0
- package/docs/ar/intlayer_with_tanstack.md +465 -299
- package/docs/ar/intlayer_with_vite+preact.md +7 -7
- package/docs/ar/intlayer_with_vite+react.md +7 -7
- package/docs/ar/intlayer_with_vite+vue.md +9 -9
- package/docs/ar/packages/vite-intlayer/index.md +3 -3
- package/docs/ar/readme.md +261 -0
- package/docs/ar/testing.md +199 -0
- package/docs/de/autoFill.md +42 -19
- package/docs/de/configuration.md +155 -147
- package/docs/de/dictionary/content_file.md +1059 -0
- package/docs/de/intlayer_CMS.md +4 -5
- package/docs/de/intlayer_with_nestjs.md +270 -0
- package/docs/de/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/de/intlayer_with_react_router_v7.md +537 -0
- package/docs/de/intlayer_with_tanstack.md +469 -302
- package/docs/de/intlayer_with_vite+preact.md +7 -7
- package/docs/de/intlayer_with_vite+react.md +7 -7
- package/docs/de/intlayer_with_vite+vue.md +9 -9
- package/docs/de/packages/vite-intlayer/index.md +3 -3
- package/docs/de/readme.md +261 -0
- package/docs/de/testing.md +200 -0
- package/docs/en/CI_CD.md +4 -6
- package/docs/en/autoFill.md +25 -5
- package/docs/en/configuration.md +45 -54
- package/docs/en/dictionary/content_file.md +1054 -0
- package/docs/en/intlayer_CMS.md +8 -7
- package/docs/en/intlayer_cli.md +112 -5
- package/docs/en/intlayer_with_nestjs.md +268 -0
- package/docs/en/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en/intlayer_with_react_router_v7.md +531 -0
- package/docs/en/intlayer_with_tanstack.md +463 -294
- package/docs/en/intlayer_with_vite+preact.md +8 -8
- package/docs/en/intlayer_with_vite+react.md +8 -8
- package/docs/en/intlayer_with_vite+vue.md +8 -8
- package/docs/en/packages/intlayer/getLocalizedUrl.md +102 -25
- package/docs/en/packages/vite-intlayer/index.md +3 -3
- package/docs/en/readme.md +261 -0
- package/docs/en/testing.md +200 -0
- package/docs/en-GB/autoFill.md +29 -6
- package/docs/en-GB/configuration.md +79 -71
- package/docs/en-GB/dictionary/content_file.md +1084 -0
- package/docs/en-GB/intlayer_CMS.md +4 -5
- package/docs/en-GB/intlayer_with_nestjs.md +268 -0
- package/docs/en-GB/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en-GB/intlayer_with_react_router_v7.md +533 -0
- package/docs/en-GB/intlayer_with_tanstack.md +466 -299
- package/docs/en-GB/intlayer_with_vite+preact.md +7 -7
- package/docs/en-GB/intlayer_with_vite+react.md +7 -7
- package/docs/en-GB/intlayer_with_vite+vue.md +9 -9
- package/docs/en-GB/packages/vite-intlayer/index.md +3 -3
- package/docs/en-GB/readme.md +261 -0
- package/docs/en-GB/testing.md +200 -0
- package/docs/es/autoFill.md +45 -23
- package/docs/es/configuration.md +171 -167
- package/docs/es/dictionary/content_file.md +1088 -0
- package/docs/es/intlayer_CMS.md +4 -5
- package/docs/es/intlayer_with_nestjs.md +268 -0
- package/docs/es/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/es/intlayer_with_react_router_v7.md +533 -0
- package/docs/es/intlayer_with_tanstack.md +469 -280
- package/docs/es/intlayer_with_vite+preact.md +7 -7
- package/docs/es/intlayer_with_vite+react.md +7 -7
- package/docs/es/intlayer_with_vite+vue.md +9 -9
- package/docs/es/packages/vite-intlayer/index.md +3 -3
- package/docs/es/readme.md +261 -0
- package/docs/es/testing.md +200 -0
- package/docs/fr/autoFill.md +47 -24
- package/docs/fr/configuration.md +213 -198
- package/docs/fr/dictionary/content_file.md +1054 -0
- package/docs/fr/intlayer_CMS.md +4 -5
- package/docs/fr/intlayer_with_nestjs.md +268 -0
- package/docs/fr/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/fr/intlayer_with_react_router_v7.md +549 -0
- package/docs/fr/intlayer_with_tanstack.md +465 -279
- package/docs/fr/intlayer_with_vite+preact.md +7 -7
- package/docs/fr/intlayer_with_vite+react.md +7 -7
- package/docs/fr/intlayer_with_vite+vue.md +9 -9
- package/docs/fr/packages/vite-intlayer/index.md +3 -3
- package/docs/fr/readme.md +261 -0
- package/docs/fr/testing.md +200 -0
- package/docs/hi/autoFill.md +47 -25
- package/docs/hi/configuration.md +194 -189
- package/docs/hi/dictionary/content_file.md +1056 -0
- package/docs/hi/intlayer_CMS.md +4 -5
- package/docs/hi/intlayer_with_nestjs.md +269 -0
- package/docs/hi/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/hi/intlayer_with_react_router_v7.md +533 -0
- package/docs/hi/intlayer_with_tanstack.md +467 -282
- package/docs/hi/intlayer_with_vite+preact.md +7 -7
- package/docs/hi/intlayer_with_vite+react.md +7 -7
- package/docs/hi/intlayer_with_vite+vue.md +9 -9
- package/docs/hi/packages/vite-intlayer/index.md +3 -3
- package/docs/hi/readme.md +261 -0
- package/docs/hi/testing.md +200 -0
- package/docs/it/autoFill.md +46 -24
- package/docs/it/configuration.md +169 -161
- package/docs/it/dictionary/content_file.md +1061 -0
- package/docs/it/intlayer_CMS.md +4 -5
- package/docs/it/intlayer_with_nestjs.md +268 -0
- package/docs/it/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/it/intlayer_with_react_router_v7.md +535 -0
- package/docs/it/intlayer_with_tanstack.md +467 -301
- package/docs/it/intlayer_with_vite+preact.md +7 -7
- package/docs/it/intlayer_with_vite+react.md +7 -7
- package/docs/it/intlayer_with_vite+vue.md +9 -9
- package/docs/it/packages/vite-intlayer/index.md +3 -3
- package/docs/it/readme.md +261 -0
- package/docs/it/testing.md +200 -0
- package/docs/ja/autoFill.md +45 -23
- package/docs/ja/configuration.md +243 -204
- package/docs/ja/dictionary/content_file.md +1064 -0
- package/docs/ja/intlayer_CMS.md +4 -5
- package/docs/ja/intlayer_with_nestjs.md +268 -0
- package/docs/ja/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ja/intlayer_with_react_router_v7.md +534 -0
- package/docs/ja/intlayer_with_tanstack.md +467 -303
- package/docs/ja/intlayer_with_vite+preact.md +7 -7
- package/docs/ja/intlayer_with_vite+react.md +7 -7
- package/docs/ja/intlayer_with_vite+vue.md +9 -9
- package/docs/ja/packages/vite-intlayer/index.md +3 -3
- package/docs/ja/readme.md +263 -0
- package/docs/ja/testing.md +200 -0
- package/docs/ko/autoFill.md +39 -16
- package/docs/ko/configuration.md +217 -197
- package/docs/ko/dictionary/content_file.md +1060 -0
- package/docs/ko/intlayer_CMS.md +4 -5
- package/docs/ko/intlayer_with_nestjs.md +268 -0
- package/docs/ko/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ko/intlayer_with_react_router_v7.md +540 -0
- package/docs/ko/intlayer_with_tanstack.md +466 -302
- package/docs/ko/intlayer_with_vite+preact.md +7 -7
- package/docs/ko/intlayer_with_vite+react.md +7 -7
- package/docs/ko/intlayer_with_vite+vue.md +9 -9
- package/docs/ko/packages/vite-intlayer/index.md +3 -3
- package/docs/ko/readme.md +261 -0
- package/docs/ko/testing.md +200 -0
- package/docs/pt/autoFill.md +39 -15
- package/docs/pt/configuration.md +165 -147
- package/docs/pt/dictionary/content_file.md +1062 -0
- package/docs/pt/intlayer_CMS.md +4 -5
- package/docs/pt/intlayer_with_nestjs.md +271 -0
- package/docs/pt/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/pt/intlayer_with_react_router_v7.md +535 -0
- package/docs/pt/intlayer_with_tanstack.md +469 -300
- package/docs/pt/intlayer_with_vite+preact.md +7 -7
- package/docs/pt/intlayer_with_vite+react.md +7 -7
- package/docs/pt/intlayer_with_vite+vue.md +9 -9
- package/docs/pt/packages/vite-intlayer/index.md +3 -3
- package/docs/pt/readme.md +261 -0
- package/docs/pt/testing.md +200 -0
- package/docs/ru/autoFill.md +52 -30
- package/docs/ru/configuration.md +164 -117
- package/docs/ru/dictionary/content_file.md +1064 -0
- package/docs/ru/intlayer_CMS.md +4 -4
- package/docs/ru/intlayer_with_nestjs.md +270 -0
- package/docs/ru/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ru/intlayer_with_react_router_v7.md +534 -0
- package/docs/ru/intlayer_with_tanstack.md +470 -305
- package/docs/ru/intlayer_with_vite+preact.md +7 -7
- package/docs/ru/intlayer_with_vite+react.md +7 -7
- package/docs/ru/intlayer_with_vite+vue.md +9 -9
- package/docs/ru/packages/vite-intlayer/index.md +3 -3
- package/docs/ru/readme.md +261 -0
- package/docs/ru/testing.md +202 -0
- package/docs/tr/CI_CD.md +198 -0
- package/docs/tr/autoFill.md +201 -0
- package/docs/tr/configuration.md +585 -0
- package/docs/tr/dictionary/condition.md +243 -0
- package/docs/tr/dictionary/content_file.md +1055 -0
- package/docs/tr/dictionary/enumeration.md +251 -0
- package/docs/tr/dictionary/file.md +228 -0
- package/docs/tr/dictionary/function_fetching.md +218 -0
- package/docs/tr/dictionary/gender.md +279 -0
- package/docs/tr/dictionary/insertion.md +191 -0
- package/docs/tr/dictionary/markdown.md +385 -0
- package/docs/tr/dictionary/nesting.md +279 -0
- package/docs/tr/dictionary/translation.md +315 -0
- package/docs/tr/formatters.md +618 -0
- package/docs/tr/how_works_intlayer.md +254 -0
- package/docs/tr/index.md +168 -0
- package/docs/tr/interest_of_intlayer.md +288 -0
- package/docs/tr/intlayer_CMS.md +347 -0
- package/docs/tr/intlayer_cli.md +570 -0
- package/docs/tr/intlayer_visual_editor.md +269 -0
- package/docs/tr/intlayer_with_angular.md +694 -0
- package/docs/tr/intlayer_with_create_react_app.md +1218 -0
- package/docs/tr/intlayer_with_express.md +415 -0
- package/docs/tr/intlayer_with_lynx+react.md +511 -0
- package/docs/tr/intlayer_with_nestjs.md +268 -0
- package/docs/tr/intlayer_with_nextjs_14.md +1029 -0
- package/docs/tr/intlayer_with_nextjs_15.md +1506 -0
- package/docs/tr/intlayer_with_nextjs_page_router.md +1484 -0
- package/docs/tr/intlayer_with_nuxt.md +773 -0
- package/docs/tr/intlayer_with_react_native+expo.md +660 -0
- package/docs/tr/intlayer_with_react_router_v7.md +531 -0
- package/docs/tr/intlayer_with_tanstack.md +452 -0
- package/docs/tr/intlayer_with_vite+preact.md +1673 -0
- package/docs/tr/intlayer_with_vite+react.md +1632 -0
- package/docs/tr/intlayer_with_vite+solid.md +288 -0
- package/docs/tr/intlayer_with_vite+svelte.md +288 -0
- package/docs/tr/intlayer_with_vite+vue.md +1042 -0
- package/docs/tr/introduction.md +209 -0
- package/docs/tr/locale_mapper.md +244 -0
- package/docs/tr/mcp_server.md +207 -0
- package/docs/tr/packages/@intlayer/api/index.md +58 -0
- package/docs/tr/packages/@intlayer/chokidar/index.md +57 -0
- package/docs/tr/packages/@intlayer/cli/index.md +47 -0
- package/docs/tr/packages/@intlayer/config/index.md +142 -0
- package/docs/tr/packages/@intlayer/core/index.md +51 -0
- package/docs/tr/packages/@intlayer/design-system/index.md +47 -0
- package/docs/tr/packages/@intlayer/dictionary-entry/index.md +53 -0
- package/docs/tr/packages/@intlayer/editor/index.md +47 -0
- package/docs/tr/packages/@intlayer/editor-react/index.md +47 -0
- package/docs/tr/packages/@intlayer/webpack/index.md +61 -0
- package/docs/tr/packages/angular-intlayer/index.md +59 -0
- package/docs/tr/packages/express-intlayer/index.md +258 -0
- package/docs/tr/packages/express-intlayer/t.md +459 -0
- package/docs/tr/packages/intlayer/getConfiguration.md +151 -0
- package/docs/tr/packages/intlayer/getEnumeration.md +165 -0
- package/docs/tr/packages/intlayer/getHTMLTextDir.md +127 -0
- package/docs/tr/packages/intlayer/getLocaleLang.md +87 -0
- package/docs/tr/packages/intlayer/getLocaleName.md +124 -0
- package/docs/tr/packages/intlayer/getLocalizedUrl.md +324 -0
- package/docs/tr/packages/intlayer/getMultilingualUrls.md +225 -0
- package/docs/tr/packages/intlayer/getPathWithoutLocale.md +81 -0
- package/docs/tr/packages/intlayer/getTranslation.md +196 -0
- package/docs/tr/packages/intlayer/getTranslationContent.md +195 -0
- package/docs/tr/packages/intlayer/index.md +505 -0
- package/docs/tr/packages/intlayer-cli/index.md +71 -0
- package/docs/tr/packages/intlayer-editor/index.md +139 -0
- package/docs/tr/packages/lynx-intlayer/index.md +85 -0
- package/docs/tr/packages/next-intlayer/index.md +154 -0
- package/docs/tr/packages/next-intlayer/t.md +354 -0
- package/docs/tr/packages/next-intlayer/useDictionary.md +270 -0
- package/docs/tr/packages/next-intlayer/useIntlayer.md +265 -0
- package/docs/tr/packages/next-intlayer/useLocale.md +133 -0
- package/docs/tr/packages/nuxt-intlayer/index.md +59 -0
- package/docs/tr/packages/preact-intlayer/index.md +55 -0
- package/docs/tr/packages/react-intlayer/index.md +148 -0
- package/docs/tr/packages/react-intlayer/t.md +304 -0
- package/docs/tr/packages/react-intlayer/useDictionary.md +554 -0
- package/docs/tr/packages/react-intlayer/useI18n.md +478 -0
- package/docs/tr/packages/react-intlayer/useIntlayer.md +253 -0
- package/docs/tr/packages/react-intlayer/useLocale.md +212 -0
- package/docs/tr/packages/react-native-intlayer/index.md +85 -0
- package/docs/tr/packages/react-scripts-intlayer/index.md +82 -0
- package/docs/tr/packages/solid-intlayer/index.md +56 -0
- package/docs/tr/packages/svelte-intlayer/index.md +55 -0
- package/docs/tr/packages/vite-intlayer/index.md +82 -0
- package/docs/tr/packages/vue-intlayer/index.md +59 -0
- package/docs/tr/per_locale_file.md +321 -0
- package/docs/tr/readme.md +261 -0
- package/docs/tr/roadmap.md +338 -0
- package/docs/tr/testing.md +200 -0
- package/docs/tr/vs_code_extension.md +154 -0
- package/docs/zh/autoFill.md +40 -18
- package/docs/zh/configuration.md +245 -226
- package/docs/zh/dictionary/content_file.md +1064 -0
- package/docs/zh/intlayer_CMS.md +4 -5
- package/docs/zh/intlayer_with_nestjs.md +268 -0
- package/docs/zh/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/zh/intlayer_with_react_router_v7.md +535 -0
- package/docs/zh/intlayer_with_tanstack.md +468 -278
- package/docs/zh/intlayer_with_vite+preact.md +7 -7
- package/docs/zh/intlayer_with_vite+react.md +7 -7
- package/docs/zh/intlayer_with_vite+vue.md +7 -7
- package/docs/zh/packages/vite-intlayer/index.md +3 -3
- package/docs/zh/readme.md +261 -0
- package/docs/zh/testing.md +198 -0
- package/frequent_questions/tr/SSR_Next_no_[locale].md +105 -0
- package/frequent_questions/tr/array_as_content_declaration.md +72 -0
- package/frequent_questions/tr/build_dictionaries.md +59 -0
- package/frequent_questions/tr/build_error_CI_CD.md +75 -0
- package/frequent_questions/tr/customized_locale_list.md +65 -0
- package/frequent_questions/tr/domain_routing.md +114 -0
- package/frequent_questions/tr/esbuild_error.md +30 -0
- package/frequent_questions/tr/get_locale_cookie.md +142 -0
- package/frequent_questions/tr/intlayer_command_undefined.md +156 -0
- package/frequent_questions/tr/locale_incorect_in_url.md +74 -0
- package/frequent_questions/tr/static_rendering.md +45 -0
- package/frequent_questions/tr/translated_path_url.md +56 -0
- package/frequent_questions/tr/unknown_command.md +98 -0
- package/legal/tr/privacy_notice.md +83 -0
- package/legal/tr/terms_of_service.md +55 -0
- package/package.json +12 -12
- package/src/generated/blog.entry.ts +212 -0
- package/src/generated/docs.entry.ts +663 -135
- package/src/generated/frequentQuestions.entry.ts +85 -1
- package/src/generated/legal.entry.ts +7 -1
- package/docs/ar/dictionary/content_extention_customization.md +0 -100
- package/docs/ar/dictionary/get_started.md +0 -527
- package/docs/de/dictionary/content_extention_customization.md +0 -100
- package/docs/de/dictionary/get_started.md +0 -531
- package/docs/en/dictionary/content_extention_customization.md +0 -102
- package/docs/en/dictionary/get_started.md +0 -529
- package/docs/en-GB/dictionary/content_extention_customization.md +0 -100
- package/docs/en-GB/dictionary/get_started.md +0 -591
- package/docs/es/dictionary/content_extention_customization.md +0 -100
- package/docs/es/dictionary/get_started.md +0 -527
- package/docs/fr/dictionary/content_extention_customization.md +0 -100
- package/docs/fr/dictionary/get_started.md +0 -527
- package/docs/hi/dictionary/content_extention_customization.md +0 -100
- package/docs/hi/dictionary/get_started.md +0 -527
- package/docs/it/dictionary/content_extention_customization.md +0 -113
- package/docs/it/dictionary/get_started.md +0 -573
- package/docs/ja/dictionary/content_extention_customization.md +0 -113
- package/docs/ja/dictionary/get_started.md +0 -576
- package/docs/ko/dictionary/content_extention_customization.md +0 -100
- package/docs/ko/dictionary/get_started.md +0 -530
- package/docs/pt/dictionary/content_extention_customization.md +0 -100
- package/docs/pt/dictionary/get_started.md +0 -532
- package/docs/ru/dictionary/content_extention_customization.md +0 -100
- package/docs/ru/dictionary/get_started.md +0 -575
- package/docs/zh/dictionary/content_extention_customization.md +0 -117
- package/docs/zh/dictionary/get_started.md +0 -533
|
@@ -1,435 +1,625 @@
|
|
|
1
1
|
---
|
|
2
|
-
createdAt: 2025-
|
|
3
|
-
updatedAt: 2025-
|
|
4
|
-
title: 在
|
|
5
|
-
description:
|
|
2
|
+
createdAt: 2025-09-09
|
|
3
|
+
updatedAt: 2025-09-09
|
|
4
|
+
title: 在 Tanstack Start 中使用 Intlayer 入门
|
|
5
|
+
description: 学习如何使用 Intlayer 为您的 Tanstack Start 应用添加国际化 (i18n)。按照本综合指南,使您的应用支持多语言和基于区域设置的路由。
|
|
6
6
|
keywords:
|
|
7
7
|
- 国际化
|
|
8
8
|
- 文档
|
|
9
9
|
- Intlayer
|
|
10
|
-
-
|
|
11
|
-
- TanStack Router
|
|
10
|
+
- Tanstack Start
|
|
12
11
|
- React
|
|
13
12
|
- i18n
|
|
14
|
-
-
|
|
13
|
+
- TypeScript
|
|
14
|
+
- 区域路由
|
|
15
15
|
slugs:
|
|
16
16
|
- doc
|
|
17
17
|
- environment
|
|
18
|
+
- vite-and-react
|
|
18
19
|
- tanstack-start
|
|
20
|
+
applicationTemplate: https://github.com/AydinTheFirst/tanstack-start-intlayer
|
|
21
|
+
author: AydinTheFirst
|
|
19
22
|
---
|
|
20
23
|
|
|
21
|
-
# 使用 Intlayer 和
|
|
24
|
+
# 使用 Intlayer 和 Tanstack Start 开始国际化 (i18n)
|
|
25
|
+
|
|
26
|
+
本指南演示了如何在 Tanstack Start 项目中集成 **Intlayer**,实现无缝国际化,支持基于区域设置的路由、TypeScript 支持以及现代开发实践。
|
|
22
27
|
|
|
23
28
|
## 什么是 Intlayer?
|
|
24
29
|
|
|
25
|
-
**Intlayer**
|
|
30
|
+
**Intlayer** 是一个创新的开源国际化 (i18n) 库,旨在简化现代 Web 应用中的多语言支持。
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
- **动态元数据和路由**(支持 SEO)。
|
|
29
|
-
- **运行时语言切换**(以及用于检测/持久化语言的辅助工具)。
|
|
30
|
-
- **Vite 插件**,用于构建时转换和开发体验优化。
|
|
32
|
+
使用 Intlayer,您可以:
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
- **通过组件级声明式字典轻松管理翻译**。
|
|
35
|
+
- **动态本地化元数据、路由和内容**。
|
|
36
|
+
- **通过自动生成的类型确保 TypeScript 支持**,提升自动补全和错误检测能力。
|
|
37
|
+
- **享受高级功能**,如动态区域设置检测和切换。
|
|
38
|
+
- **通过 Tanstack Start 的基于文件的路由系统启用区域设置感知路由**。
|
|
33
39
|
|
|
34
40
|
---
|
|
35
41
|
|
|
36
|
-
##
|
|
42
|
+
## 在 Tanstack Start 应用中设置 Intlayer 的分步指南
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
# npm
|
|
40
|
-
npm i intlayer react-intlayer
|
|
41
|
-
npm i -D vite-intlayer
|
|
44
|
+
### 第一步:创建项目
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
首先,按照 TanStack Start 网站上的[创建新项目](https://tanstack.com/start/latest/docs/framework/react/quick-start)指南创建一个新的 TanStack Start 项目。
|
|
47
|
+
|
|
48
|
+
### 第二步:安装 Intlayer 包
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
使用您喜欢的包管理器安装所需的包:
|
|
51
|
+
|
|
52
|
+
```bash packageManager="npm"
|
|
53
|
+
npm install intlayer react-intlayer
|
|
54
|
+
npm install vite-intlayer --save-dev
|
|
50
55
|
```
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
```bash packageManager="pnpm"
|
|
58
|
+
pnpm add intlayer react-intlayer
|
|
59
|
+
pnpm add vite-intlayer --save-dev
|
|
60
|
+
```
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
- **intlayer**
|
|
63
|
+
|
|
64
|
+
- **intlayer**
|
|
65
|
+
|
|
66
|
+
核心包,提供用于配置管理、翻译、[内容声明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)、转译和[CLI命令](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_cli.md)的国际化工具。
|
|
67
|
+
|
|
68
|
+
- **react-intlayer**
|
|
69
|
+
|
|
70
|
+
将 Intlayer 集成到 React 应用中的包。它为 React 国际化提供上下文提供者和钩子。
|
|
57
71
|
|
|
58
|
-
|
|
72
|
+
- **vite-intlayer**
|
|
59
73
|
|
|
60
|
-
|
|
74
|
+
包含用于将 Intlayer 集成到[Vite 打包器](https://vite.dev/guide/why.html#why-bundle-for-production)的 Vite 插件,以及用于检测用户首选语言环境、管理 Cookie 和处理 URL 重定向的中间件。
|
|
61
75
|
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
### 第三步:项目配置
|
|
77
|
+
|
|
78
|
+
创建一个配置文件来配置您的应用程序语言:
|
|
79
|
+
|
|
80
|
+
```typescript fileName="intlayer.config.ts" codeFormat="typescript"
|
|
81
|
+
import type { IntlayerConfig } from "intlayer";
|
|
82
|
+
|
|
83
|
+
import { Locales } from "intlayer";
|
|
64
84
|
|
|
65
85
|
const config: IntlayerConfig = {
|
|
66
86
|
internationalization: {
|
|
67
|
-
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], // 支持的语言列表
|
|
68
87
|
defaultLocale: Locales.ENGLISH, // 默认语言
|
|
88
|
+
locales: [
|
|
89
|
+
Locales.ENGLISH, // 英语
|
|
90
|
+
Locales.FRENCH, // 法语
|
|
91
|
+
Locales.SPANISH, // 西班牙语
|
|
92
|
+
// 您的其他语言
|
|
93
|
+
],
|
|
69
94
|
},
|
|
70
|
-
// 你也可以调整:contentDir、contentFileExtensions、中间件选项等。
|
|
71
95
|
};
|
|
72
96
|
|
|
73
97
|
export default config;
|
|
74
98
|
```
|
|
75
99
|
|
|
76
|
-
|
|
100
|
+
```javascript fileName="intlayer.config.mjs" codeFormat="esm"
|
|
101
|
+
import { Locales } from "intlayer";
|
|
77
102
|
|
|
78
|
-
|
|
103
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
104
|
+
const config = {
|
|
105
|
+
internationalization: {
|
|
106
|
+
defaultLocale: Locales.ENGLISH, // 默认语言
|
|
107
|
+
locales: [
|
|
108
|
+
Locales.ENGLISH, // 英语
|
|
109
|
+
Locales.FRENCH, // 法语
|
|
110
|
+
Locales.SPANISH, // 西班牙语
|
|
111
|
+
// 你的其他语言
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
};
|
|
79
115
|
|
|
80
|
-
|
|
116
|
+
export default config;
|
|
117
|
+
```
|
|
81
118
|
|
|
82
|
-
|
|
119
|
+
```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
|
|
120
|
+
const { Locales } = require("intlayer");
|
|
83
121
|
|
|
84
|
-
|
|
122
|
+
/** @type {import('intlayer').IntlayerConfig} */
|
|
123
|
+
const config = {
|
|
124
|
+
internationalization: {
|
|
125
|
+
defaultLocale: Locales.ENGLISH,
|
|
126
|
+
locales: [
|
|
127
|
+
Locales.ENGLISH,
|
|
128
|
+
Locales.FRENCH,
|
|
129
|
+
Locales.SPANISH,
|
|
130
|
+
// 你的其他语言
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
};
|
|
85
134
|
|
|
86
|
-
|
|
135
|
+
module.exports = config;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> 通过此配置文件,您可以设置本地化的 URL、中间件重定向、Cookie 名称、内容声明的位置和扩展名,禁用控制台中的 Intlayer 日志等。有关可用参数的完整列表,请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
|
|
139
|
+
|
|
140
|
+
### 第4步:在您的 Vite 配置中集成 Intlayer
|
|
141
|
+
|
|
142
|
+
将 intlayer 插件添加到您的配置中:
|
|
143
|
+
|
|
144
|
+
```typescript fileName="vite.config.ts" codeFormat="typescript"
|
|
145
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
87
146
|
import { defineConfig } from "vite";
|
|
88
|
-
import
|
|
89
|
-
import
|
|
147
|
+
import { intlayerMiddlewarePlugin, intlayerPlugin } from "vite-intlayer";
|
|
148
|
+
import tsconfigPaths from "vite-tsconfig-paths";
|
|
90
149
|
|
|
91
150
|
export default defineConfig({
|
|
92
151
|
plugins: [
|
|
93
|
-
|
|
152
|
+
reactRouter(),
|
|
153
|
+
tsconfigPaths(),
|
|
94
154
|
intlayerPlugin(),
|
|
95
|
-
|
|
96
|
-
intLayerMiddlewarePlugin(),
|
|
155
|
+
intlayerMiddlewarePlugin(),
|
|
97
156
|
],
|
|
98
157
|
});
|
|
99
158
|
```
|
|
100
159
|
|
|
101
|
-
>
|
|
160
|
+
> `intlayerPlugin()` 是用于将 Intlayer 集成到 Vite 的插件。它确保内容声明文件的构建,并在开发模式下监控这些文件。它在 Vite 应用中定义了 Intlayer 的环境变量。此外,它还提供别名以优化性能。
|
|
102
161
|
|
|
103
|
-
|
|
162
|
+
### 第五步:创建布局组件
|
|
104
163
|
|
|
105
|
-
|
|
164
|
+
设置你的根布局和特定语言环境的布局:
|
|
106
165
|
|
|
107
|
-
|
|
166
|
+
#### 根布局
|
|
108
167
|
|
|
109
|
-
```tsx fileName="src/
|
|
110
|
-
|
|
111
|
-
import
|
|
168
|
+
```tsx fileName="src/routes/{-$locale}/route.tsx" codeFormat="typescript"
|
|
169
|
+
// src/routes/{-$locale}/route.tsx
|
|
170
|
+
import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";
|
|
171
|
+
import { configuration } from "intlayer";
|
|
172
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
173
|
+
|
|
174
|
+
import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes";
|
|
175
|
+
|
|
176
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
177
|
+
component: LayoutComponent,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
function LayoutComponent() {
|
|
181
|
+
const { locale } = Route.useParams();
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<IntlayerProvider locale={locale}>
|
|
185
|
+
<Outlet />
|
|
186
|
+
</IntlayerProvider>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 第6步:声明您的内容
|
|
192
|
+
|
|
193
|
+
创建并管理您的内容声明以存储翻译:
|
|
194
|
+
|
|
195
|
+
```tsx fileName="src/contents/page.content.ts" contentDeclarationFormat="typescript"
|
|
196
|
+
import type { Dictionary } from "intlayer";
|
|
197
|
+
|
|
198
|
+
import { t } from "intlayer";
|
|
112
199
|
|
|
113
200
|
const appContent = {
|
|
114
|
-
key: "app",
|
|
115
201
|
content: {
|
|
116
|
-
|
|
117
|
-
|
|
202
|
+
links: {
|
|
203
|
+
about: t({
|
|
204
|
+
en: "About",
|
|
205
|
+
es: "Acerca de",
|
|
206
|
+
fr: "À propos",
|
|
207
|
+
}),
|
|
208
|
+
home: t({
|
|
209
|
+
en: "首页",
|
|
210
|
+
es: "Inicio",
|
|
211
|
+
fr: "Accueil",
|
|
212
|
+
}),
|
|
213
|
+
},
|
|
214
|
+
meta: {
|
|
215
|
+
description: t({
|
|
216
|
+
en: "这是一个使用 Intlayer 与 TanStack Router 的示例",
|
|
217
|
+
es: "Este es un ejemplo de uso de Intlayer con TanStack Router",
|
|
218
|
+
fr: "Ceci est un exemple d'utilisation d'Intlayer avec TanStack Router",
|
|
219
|
+
}),
|
|
220
|
+
},
|
|
118
221
|
title: t({
|
|
119
|
-
en: "
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}),
|
|
123
|
-
count: t({ en: "count is ", fr: "le compte est ", es: "el recuento es " }),
|
|
124
|
-
edit: t<ReactNode>({
|
|
125
|
-
en: (
|
|
126
|
-
<>
|
|
127
|
-
编辑 <code>src/routes/index.tsx</code> 并保存以测试 HMR
|
|
128
|
-
</>
|
|
129
|
-
),
|
|
130
|
-
fr: (
|
|
131
|
-
<>
|
|
132
|
-
Éditez <code>src/routes/index.tsx</code> et enregistrez pour tester
|
|
133
|
-
HMR
|
|
134
|
-
</>
|
|
135
|
-
),
|
|
136
|
-
es: (
|
|
137
|
-
<>
|
|
138
|
-
Edita <code>src/routes/index.tsx</code> y guarda para probar HMR
|
|
139
|
-
</>
|
|
140
|
-
),
|
|
141
|
-
}),
|
|
142
|
-
readTheDocs: t({
|
|
143
|
-
en: "点击标志以了解更多",
|
|
144
|
-
fr: "Cliquez sur les logos pour en savoir plus",
|
|
145
|
-
es: "Haz clic en los logotipos para saber más",
|
|
222
|
+
en: "欢迎使用 Intlayer + TanStack Router",
|
|
223
|
+
es: "Bienvenido a Intlayer + TanStack Router",
|
|
224
|
+
fr: "Bienvenue à Intlayer + TanStack Router",
|
|
146
225
|
}),
|
|
147
226
|
},
|
|
227
|
+
key: "app",
|
|
148
228
|
} satisfies Dictionary;
|
|
149
229
|
|
|
150
230
|
export default appContent;
|
|
151
231
|
```
|
|
152
232
|
|
|
153
|
-
|
|
233
|
+
> 您的内容声明可以在应用程序中的任何位置定义,只要它们被包含在 `contentDir` 目录中(默认是 `./app`)。并且文件扩展名需匹配内容声明的文件扩展名(默认是 `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`)。
|
|
154
234
|
|
|
155
|
-
>
|
|
235
|
+
> 更多详情,请参阅[内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)。
|
|
156
236
|
|
|
157
|
-
|
|
237
|
+
### 第7步:创建支持多语言环境的组件和钩子
|
|
158
238
|
|
|
159
|
-
|
|
239
|
+
创建一个用于多语言环境导航的 `LocalizedLink` 组件:
|
|
160
240
|
|
|
161
|
-
|
|
241
|
+
```tsx fileName="src/components/localized-link.tsx" codeFormat="typescript"
|
|
242
|
+
// src/components/localized-link.tsx
|
|
243
|
+
// eslint-disable-next-line no-restricted-imports
|
|
244
|
+
import { Link, type LinkProps } from "@tanstack/react-router";
|
|
245
|
+
import { getLocalizedUrl } from "intlayer";
|
|
246
|
+
import { useLocale } from "react-intlayer";
|
|
162
247
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
createRootRoute,
|
|
167
|
-
Link as RouterLink,
|
|
168
|
-
} from "@tanstack/react-router";
|
|
169
|
-
import { IntlayerProvider, useIntlayer } from "react-intlayer";
|
|
170
|
-
|
|
171
|
-
function AppShell() {
|
|
172
|
-
// 在顶层使用字典的示例:
|
|
173
|
-
const content = useIntlayer("app");
|
|
248
|
+
type LocalizedLinkProps = {
|
|
249
|
+
to: string;
|
|
250
|
+
} & Omit<LinkProps, "to">;
|
|
174
251
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
<nav className="flex gap-3 p-3">
|
|
178
|
-
<RouterLink to="/">首页</RouterLink>
|
|
179
|
-
<RouterLink to="/about">关于</RouterLink>
|
|
180
|
-
</nav>
|
|
181
|
-
<main className="p-6">
|
|
182
|
-
<h1>{content.title}</h1>
|
|
183
|
-
<Outlet />
|
|
184
|
-
</main>
|
|
185
|
-
</div>
|
|
186
|
-
);
|
|
187
|
-
}
|
|
252
|
+
export function LocalizedLink(props: LocalizedLinkProps) {
|
|
253
|
+
const { locale } = useLocale();
|
|
188
254
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
<AppShell />
|
|
193
|
-
</IntlayerProvider>
|
|
194
|
-
),
|
|
195
|
-
});
|
|
196
|
-
```
|
|
255
|
+
const isExternal = (to: string) => {
|
|
256
|
+
return /^(https?:)?\/\//.test(to);
|
|
257
|
+
};
|
|
197
258
|
|
|
198
|
-
|
|
259
|
+
const to = isExternal(props.to)
|
|
260
|
+
? props.to
|
|
261
|
+
: getLocalizedUrl(props.to, locale);
|
|
199
262
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
import { useIntlayer } from "react-intlayer";
|
|
203
|
-
import reactLogo from "../assets/react.svg";
|
|
204
|
-
|
|
205
|
-
export const Route = createFileRoute("/")({
|
|
206
|
-
component: () => {
|
|
207
|
-
const content = useIntlayer("app");
|
|
208
|
-
return (
|
|
209
|
-
<>
|
|
210
|
-
<button>{content.count}0</button>
|
|
211
|
-
<p>{content.edit}</p>
|
|
212
|
-
<img
|
|
213
|
-
src={reactLogo}
|
|
214
|
-
alt={content.reactLogo.value}
|
|
215
|
-
width={48}
|
|
216
|
-
height={48}
|
|
217
|
-
/>
|
|
218
|
-
<p className="opacity-70">{content.readTheDocs}</p>
|
|
219
|
-
</>
|
|
220
|
-
);
|
|
221
|
-
},
|
|
222
|
-
});
|
|
263
|
+
return <Link {...props} to={to as LinkProps["to"]} />;
|
|
264
|
+
}
|
|
223
265
|
```
|
|
224
266
|
|
|
225
|
-
|
|
226
|
-
>
|
|
227
|
-
> ```jsx
|
|
228
|
-
> <img alt={c.reactLogo.value} />
|
|
229
|
-
> ```
|
|
267
|
+
创建一个用于编程式导航的 `useLocalizedNavigate` 钩子:
|
|
230
268
|
|
|
231
|
-
|
|
269
|
+
```tsx fileName="src/hooks/useLocalizedNavigate.tsx" codeFormat="typescript"
|
|
270
|
+
// src/hooks/useLocalizedNavigate.tsx
|
|
271
|
+
// eslint-disable-next-line no-restricted-imports
|
|
272
|
+
import { NavigateOptions, useNavigate } from "@tanstack/react-router";
|
|
273
|
+
import { getLocalizedUrl } from "intlayer";
|
|
274
|
+
import { useLocale } from "react-intlayer";
|
|
232
275
|
|
|
233
|
-
|
|
276
|
+
type LocalizedNavigateOptions = {
|
|
277
|
+
to: string;
|
|
278
|
+
} & Omit<NavigateOptions, "to">;
|
|
234
279
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
280
|
+
export const useLocalizedNavigate = () => {
|
|
281
|
+
const navigate = useNavigate();
|
|
282
|
+
const { locale } = useLocale();
|
|
238
283
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
284
|
+
const isExternal = (to: string) => {
|
|
285
|
+
return /^(https?:)?\/\//.test(to);
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const localizedNavigate = (options: LocalizedNavigateOptions) => {
|
|
289
|
+
const to = isExternal(options.to)
|
|
290
|
+
? options.to
|
|
291
|
+
: getLocalizedUrl(options.to, locale);
|
|
292
|
+
|
|
293
|
+
navigate({ ...options, to: to as NavigateOptions["to"] });
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
return localizedNavigate;
|
|
297
|
+
};
|
|
249
298
|
```
|
|
250
299
|
|
|
251
|
-
|
|
300
|
+
### 第8步:在您的页面中使用 Intlayer
|
|
252
301
|
|
|
253
|
-
|
|
302
|
+
在整个应用程序中访问您的内容字典:
|
|
254
303
|
|
|
255
|
-
|
|
304
|
+
#### 根重定向页面
|
|
256
305
|
|
|
257
|
-
|
|
306
|
+
```tsx fileName="src/routes/page.tsx" codeFormat="typescript"
|
|
307
|
+
// src/routes/page.tsx
|
|
308
|
+
import { useLocale } from "react-intlayer";
|
|
309
|
+
import { Navigate } from "react-router";
|
|
258
310
|
|
|
259
|
-
|
|
311
|
+
export default function Page() {
|
|
312
|
+
const { locale } = useLocale();
|
|
260
313
|
|
|
261
|
-
|
|
314
|
+
return <Navigate replace to={locale} />;
|
|
315
|
+
}
|
|
316
|
+
```
|
|
262
317
|
|
|
263
|
-
|
|
318
|
+
#### 本地化首页
|
|
264
319
|
|
|
265
|
-
```tsx fileName="src/
|
|
266
|
-
import {
|
|
267
|
-
import {
|
|
268
|
-
import {
|
|
320
|
+
```tsx fileName="src/routes/{-$locale}/index.tsx" codeFormat="typescript"
|
|
321
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
322
|
+
import { getIntlayer } from "intlayer";
|
|
323
|
+
import { useIntlayer } from "react-intlayer";
|
|
269
324
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
325
|
+
import LocaleSwitcher from "@/components/locale-switcher";
|
|
326
|
+
import { LocalizedLink } from "@/components/localized-link";
|
|
327
|
+
import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";
|
|
328
|
+
|
|
329
|
+
export const Route = createFileRoute("/{-$locale}/")({
|
|
330
|
+
component: RouteComponent,
|
|
331
|
+
head: ({ params }) => {
|
|
332
|
+
const { locale } = params;
|
|
333
|
+
const metaContent = getIntlayer("app", locale);
|
|
334
|
+
|
|
335
|
+
return {
|
|
336
|
+
meta: [
|
|
337
|
+
{ title: metaContent.title },
|
|
338
|
+
{ content: metaContent.meta.description, name: "description" },
|
|
339
|
+
],
|
|
340
|
+
};
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
function RouteComponent() {
|
|
345
|
+
const content = useIntlayer("app");
|
|
346
|
+
const navigate = useLocalizedNavigate();
|
|
283
347
|
|
|
284
348
|
return (
|
|
285
|
-
<div className="
|
|
286
|
-
<
|
|
287
|
-
|
|
288
|
-
|
|
349
|
+
<div className="grid place-items-center h-screen">
|
|
350
|
+
<div className="flex flex-col gap-4 items-center text-center">
|
|
351
|
+
{content.title}
|
|
352
|
+
<LocaleSwitcher />
|
|
353
|
+
<div className="flex gap-4">
|
|
354
|
+
<a href="/">索引</a>
|
|
355
|
+
<LocalizedLink to="/">{content.links.home}</LocalizedLink>
|
|
356
|
+
<LocalizedLink to="/about">{content.links.about}</LocalizedLink>
|
|
357
|
+
</div>
|
|
358
|
+
<div className="flex gap-4">
|
|
359
|
+
<button onClick={() => navigate({ to: "/" })}>
|
|
360
|
+
{content.links.home}
|
|
361
|
+
</button>
|
|
362
|
+
<button onClick={() => navigate({ to: "/about" })}>
|
|
363
|
+
{content.links.about}
|
|
364
|
+
</button>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
289
367
|
</div>
|
|
290
368
|
);
|
|
291
369
|
}
|
|
292
370
|
```
|
|
293
371
|
|
|
294
|
-
|
|
372
|
+
> 想了解更多关于 `useIntlayer` 钩子的内容,请参阅[文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useIntlayer.md)。
|
|
295
373
|
|
|
296
|
-
|
|
374
|
+
### 第9步:创建语言切换组件
|
|
297
375
|
|
|
298
|
-
|
|
376
|
+
创建一个组件,允许用户切换语言:
|
|
299
377
|
|
|
300
|
-
```tsx fileName="src/
|
|
301
|
-
import {
|
|
302
|
-
import {
|
|
303
|
-
|
|
378
|
+
```tsx fileName="src/components/locale-switcher.tsx" codeFormat="typescript"
|
|
379
|
+
import { useLocation } from "@tanstack/react-router";
|
|
380
|
+
import {
|
|
381
|
+
getHTMLTextDir,
|
|
382
|
+
getLocaleName,
|
|
383
|
+
getLocalizedUrl,
|
|
384
|
+
Locales,
|
|
385
|
+
} from "intlayer";
|
|
386
|
+
import { useIntlayer, useLocale } from "react-intlayer";
|
|
387
|
+
|
|
388
|
+
export default function LocaleSwitcher() {
|
|
389
|
+
const { pathname, searchStr } = useLocation();
|
|
390
|
+
const content = useIntlayer("locale-switcher");
|
|
391
|
+
|
|
392
|
+
const { availableLocales, locale, setLocale } = useLocale({
|
|
393
|
+
onLocaleChange: (newLocale) => {
|
|
394
|
+
const pathWithLocale = getLocalizedUrl(pathname + searchStr, newLocale);
|
|
395
|
+
location.replace(pathWithLocale);
|
|
396
|
+
},
|
|
397
|
+
});
|
|
304
398
|
|
|
305
|
-
function Document({
|
|
306
|
-
locale,
|
|
307
|
-
children,
|
|
308
|
-
}: {
|
|
309
|
-
locale: string;
|
|
310
|
-
children: React.ReactNode;
|
|
311
|
-
}) {
|
|
312
399
|
return (
|
|
313
|
-
<
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
400
|
+
<select
|
|
401
|
+
aria-label={content.label.toString()}
|
|
402
|
+
onChange={(e) => setLocale(e.target.value)}
|
|
403
|
+
value={locale}
|
|
404
|
+
>
|
|
405
|
+
{availableLocales.map((localeItem) => (
|
|
406
|
+
<option
|
|
407
|
+
dir={getHTMLTextDir(localeItem)}
|
|
408
|
+
key={localeItem}
|
|
409
|
+
lang={localeItem}
|
|
410
|
+
value={localeItem}
|
|
411
|
+
>
|
|
412
|
+
{/* 示例:Français(法语) */}
|
|
413
|
+
{getLocaleName(localeItem, locale)} (
|
|
414
|
+
{getLocaleName(localeItem, Locales.ENGLISH)})
|
|
415
|
+
</option>
|
|
416
|
+
))}
|
|
417
|
+
</select>
|
|
321
418
|
);
|
|
322
419
|
}
|
|
323
|
-
|
|
324
|
-
export const Route = createRootRoute({
|
|
325
|
-
component: () => (
|
|
326
|
-
<IntlayerProvider>
|
|
327
|
-
{/* 如果您在服务器端计算 locale,请将其传递给 Document;否则客户端将在水合后进行修正 */}
|
|
328
|
-
<Document locale={document?.documentElement?.lang || "en"}>
|
|
329
|
-
<Outlet />
|
|
330
|
-
</Document>
|
|
331
|
-
</IntlayerProvider>
|
|
332
|
-
),
|
|
333
|
-
});
|
|
334
420
|
```
|
|
335
421
|
|
|
336
|
-
|
|
422
|
+
> 想了解更多关于 `useLocale` 钩子的内容,请参考[文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)。
|
|
423
|
+
|
|
424
|
+
### 第10步:添加HTML属性管理(可选)
|
|
425
|
+
|
|
426
|
+
创建一个钩子来管理HTML的lang和dir属性:
|
|
337
427
|
|
|
338
|
-
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx"
|
|
428
|
+
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat="typescript"
|
|
429
|
+
// src/hooks/useI18nHTMLAttributes.tsx
|
|
430
|
+
import { getHTMLTextDir } from "intlayer";
|
|
339
431
|
import { useEffect } from "react";
|
|
340
432
|
import { useLocale } from "react-intlayer";
|
|
341
|
-
import { getHTMLTextDir } from "intlayer";
|
|
342
433
|
|
|
343
434
|
export const useI18nHTMLAttributes = () => {
|
|
344
435
|
const { locale } = useLocale();
|
|
436
|
+
|
|
345
437
|
useEffect(() => {
|
|
346
438
|
document.documentElement.lang = locale;
|
|
347
|
-
document.documentElement.dir = getHTMLTextDir(locale);
|
|
439
|
+
document.documentElement.dir = getHTMLTextDir(locale); // 设置HTML的文本方向属性
|
|
348
440
|
}, [locale]);
|
|
349
441
|
};
|
|
350
442
|
```
|
|
351
443
|
|
|
352
|
-
|
|
444
|
+
然后在你的根组件中使用它:
|
|
353
445
|
|
|
354
|
-
|
|
446
|
+
```tsx fileName="src/routes/{-$locale}/index.tsx" codeFormat="typescript"
|
|
447
|
+
import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";
|
|
448
|
+
import { configuration } from "intlayer";
|
|
449
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
355
450
|
|
|
356
|
-
|
|
451
|
+
import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes"; // 导入该hook
|
|
357
452
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
forwardRef,
|
|
362
|
-
type AnchorHTMLAttributes,
|
|
363
|
-
type DetailedHTMLProps,
|
|
364
|
-
} from "react";
|
|
365
|
-
import { useLocale } from "react-intlayer";
|
|
453
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
454
|
+
component: LayoutComponent,
|
|
455
|
+
});
|
|
366
456
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const hrefI18n =
|
|
379
|
-
href && !isExternal(href) ? getLocalizedUrl(href, locale) : href;
|
|
380
|
-
return (
|
|
381
|
-
<a href={hrefI18n} ref={ref} {...props}>
|
|
382
|
-
{children}
|
|
383
|
-
</a>
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
);
|
|
387
|
-
Link.displayName = "Link";
|
|
457
|
+
function LayoutComponent() {
|
|
458
|
+
useI18nHTMLAttributes(); // 添加此行
|
|
459
|
+
|
|
460
|
+
const { locale } = Route.useParams();
|
|
461
|
+
|
|
462
|
+
return (
|
|
463
|
+
<IntlayerProvider locale={locale}>
|
|
464
|
+
<Outlet />
|
|
465
|
+
</IntlayerProvider>
|
|
466
|
+
);
|
|
467
|
+
}
|
|
388
468
|
```
|
|
389
469
|
|
|
390
|
-
|
|
470
|
+
### 第11步:构建并运行您的应用程序
|
|
391
471
|
|
|
392
|
-
|
|
472
|
+
构建内容字典并运行您的应用程序:
|
|
473
|
+
|
|
474
|
+
```bash packageManager="npm"
|
|
475
|
+
# 构建 Intlayer 字典
|
|
476
|
+
npm run intlayer:build
|
|
393
477
|
|
|
394
|
-
|
|
478
|
+
# 启动开发服务器
|
|
479
|
+
npm run dev
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
```bash packageManager="pnpm"
|
|
483
|
+
# 构建 Intlayer 字典
|
|
484
|
+
pnpm intlayer:build
|
|
485
|
+
|
|
486
|
+
# 启动开发服务器
|
|
487
|
+
pnpm dev
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
```bash packageManager="yarn"
|
|
491
|
+
# 构建 Intlayer 字典
|
|
492
|
+
yarn intlayer:build
|
|
395
493
|
|
|
396
|
-
|
|
494
|
+
# 启动开发服务器
|
|
495
|
+
yarn dev
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### 第12步:配置 TypeScript(可选)
|
|
499
|
+
|
|
500
|
+
Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库更强大。
|
|
501
|
+
|
|
502
|
+
确保您的 TypeScript 配置包含自动生成的类型:
|
|
397
503
|
|
|
398
504
|
```json5 fileName="tsconfig.json"
|
|
399
505
|
{
|
|
400
|
-
|
|
506
|
+
compilerOptions: {
|
|
507
|
+
// ... 您现有的 TypeScript 配置
|
|
508
|
+
},
|
|
509
|
+
include: [
|
|
510
|
+
// ... 您现有的包含项
|
|
511
|
+
".intlayer/**/*.ts", // 包含自动生成的类型
|
|
512
|
+
],
|
|
401
513
|
}
|
|
402
514
|
```
|
|
403
515
|
|
|
404
|
-
|
|
516
|
+
### Git 配置
|
|
405
517
|
|
|
406
|
-
|
|
518
|
+
建议忽略 Intlayer 生成的文件。这样可以避免将它们提交到您的 Git 仓库。
|
|
407
519
|
|
|
408
|
-
|
|
520
|
+
为此,您可以将以下指令添加到您的 `.gitignore` 文件中:
|
|
409
521
|
|
|
410
|
-
```gitignore
|
|
522
|
+
```plaintext fileName=".gitignore"
|
|
523
|
+
# 忽略 Intlayer 生成的文件
|
|
411
524
|
.intlayer
|
|
412
525
|
```
|
|
413
526
|
|
|
414
527
|
---
|
|
415
528
|
|
|
529
|
+
### 第 13 步:创建重定向(可选)
|
|
530
|
+
|
|
531
|
+
```typescript fileName="src/routes/{-$locale}/rotue.tsx" codeFormat="typescript"
|
|
532
|
+
function LayoutComponent() {
|
|
533
|
+
useI18nHTMLAttributes();
|
|
534
|
+
|
|
535
|
+
const { locale } = Route.useParams();
|
|
536
|
+
const { locale: selectedLocale } = useLocale();
|
|
537
|
+
const { defaultLocale } = configuration.internationalization;
|
|
538
|
+
const { prefixDefault } = configuration.middleware;
|
|
539
|
+
|
|
540
|
+
// 如果 prefixDefault 为 true 且 URL 中没有 locale,则重定向到默认语言
|
|
541
|
+
if (selectedLocale === defaultLocale && !locale && prefixDefault) {
|
|
542
|
+
return <Navigate replace to={defaultLocale} />;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// 如果 URL 中的 locale 与选定的 locale 不匹配,则重定向到选定的 locale
|
|
546
|
+
if (selectedLocale !== defaultLocale && !locale) {
|
|
547
|
+
return <Navigate replace to={selectedLocale} />;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return (
|
|
551
|
+
<IntlayerProvider locale={locale}>
|
|
552
|
+
<Outlet />
|
|
553
|
+
</IntlayerProvider>
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
## 生产部署
|
|
559
|
+
|
|
560
|
+
部署您的应用程序时:
|
|
561
|
+
|
|
562
|
+
1. **构建您的应用程序:**
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
npm run build
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
2. **构建 Intlayer 词典:**
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
npm run intlayer:build
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
3. **如果在生产环境中使用中间件,请将 `vite-intlayer` 移动到依赖项:**
|
|
575
|
+
```bash
|
|
576
|
+
npm install vite-intlayer --save
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
您的应用程序现在将支持:
|
|
580
|
+
|
|
581
|
+
- **URL 结构**:`/en`、`/en/about`、`/tr`、`/tr/about`
|
|
582
|
+
- **基于浏览器偏好的自动语言环境检测**
|
|
583
|
+
- **基于 Tanstack Start 的语言环境感知路由**
|
|
584
|
+
- **带有自动生成类型的 TypeScript 支持**
|
|
585
|
+
- **具有正确语言环境处理的服务器端渲染**
|
|
586
|
+
|
|
416
587
|
## VS Code 扩展
|
|
417
588
|
|
|
418
|
-
|
|
419
|
-
|
|
589
|
+
为了提升您使用 Intlayer 的开发体验,您可以安装官方的 **Intlayer VS Code 扩展**。
|
|
590
|
+
|
|
591
|
+
[从 VS Code 市场安装](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
|
|
592
|
+
|
|
593
|
+
该扩展提供:
|
|
594
|
+
|
|
595
|
+
- 翻译键的 **自动补全**。
|
|
596
|
+
- 缺失翻译的 **实时错误检测**。
|
|
597
|
+
- 翻译内容的 **内联预览**。
|
|
598
|
+
- 轻松创建和更新翻译的 **快速操作**。
|
|
599
|
+
|
|
600
|
+
有关如何使用该扩展的更多详细信息,请参阅 [Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
|
|
420
601
|
|
|
421
602
|
---
|
|
422
603
|
|
|
423
604
|
## 深入了解
|
|
424
605
|
|
|
425
|
-
|
|
426
|
-
- CMS 模式
|
|
427
|
-
- 边缘/适配器上的语言环境检测
|
|
606
|
+
要进一步提升,您可以实现[可视化编辑器](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_visual_editor.md)或使用[CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_CMS.md)将内容外部化。
|
|
428
607
|
|
|
429
608
|
---
|
|
430
609
|
|
|
610
|
+
## 文档参考
|
|
611
|
+
|
|
612
|
+
- [Intlayer 文档](https://intlayer.org)
|
|
613
|
+
- [Tanstack Start 文档](https://reactrouter.com/)
|
|
614
|
+
- [useIntlayer 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useIntlayer.md)
|
|
615
|
+
- [useLocale 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)
|
|
616
|
+
- [内容声明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)
|
|
617
|
+
- [配置](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)
|
|
618
|
+
|
|
619
|
+
本综合指南提供了将 Intlayer 与 Tanstack Start 集成所需的一切,支持完全国际化的应用程序,具备区域感知路由和 TypeScript 支持。
|
|
620
|
+
|
|
431
621
|
## 文档历史
|
|
432
622
|
|
|
433
|
-
| 版本 | 日期 | 变更内容
|
|
434
|
-
| ----- | ---------- |
|
|
435
|
-
|
|
|
623
|
+
| 版本 | 日期 | 变更内容 |
|
|
624
|
+
| ----- | ---------- | ---------------------- |
|
|
625
|
+
| 5.8.1 | 2025-09-09 | 为 Tanstack Start 添加 |
|