@intlayer/docs 9.1.3 → 9.3.0
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/index.md +1 -1
- package/blog/ar/rag_powered_documentation_assistant.md +7 -0
- package/blog/de/index.md +1 -1
- package/blog/de/rag_powered_documentation_assistant.md +6 -0
- package/blog/en/index.md +1 -1
- package/blog/en-GB/index.md +1 -1
- package/blog/en-GB/rag_powered_documentation_assistant.md +6 -0
- package/blog/es/index.md +1 -1
- package/blog/es/rag_powered_documentation_assistant.md +7 -0
- package/blog/fr/i18n_meaning.md +7 -1
- package/blog/fr/index.md +1 -1
- package/blog/fr/list_i18n_technologies/frameworks/angular.md +5 -1
- package/blog/fr/rag_powered_documentation_assistant.md +6 -0
- package/blog/hi/index.md +1 -1
- package/blog/hi/next-i18next_vs_next-intl_vs_intlayer.md +119 -42
- package/blog/hi/rag_powered_documentation_assistant.md +7 -0
- package/blog/id/index.md +1 -1
- package/blog/id/rag_powered_documentation_assistant.md +6 -0
- package/blog/it/index.md +1 -1
- package/blog/it/rag_powered_documentation_assistant.md +6 -0
- package/blog/ja/index.md +1 -1
- package/blog/ja/rag_powered_documentation_assistant.md +7 -0
- package/blog/ko/index.md +1 -1
- package/blog/ko/list_i18n_technologies/frameworks/react.md +7 -7
- package/blog/ko/rag_powered_documentation_assistant.md +6 -0
- package/blog/pl/index.md +1 -1
- package/blog/pl/rag_powered_documentation_assistant.md +6 -0
- package/blog/pt/index.md +1 -1
- package/blog/pt/rag_powered_documentation_assistant.md +6 -0
- package/blog/ru/index.md +1 -1
- package/blog/ru/rag_powered_documentation_assistant.md +7 -0
- package/blog/tr/intlayer_with_react-intl.md +3 -1
- package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +175 -42
- package/blog/tr/rag_powered_documentation_assistant.md +6 -0
- package/blog/uk/index.md +1 -1
- package/blog/uk/rag_powered_documentation_assistant.md +6 -0
- package/blog/vi/index.md +1 -1
- package/blog/vi/rag_powered_documentation_assistant.md +6 -0
- package/blog/zh/index.md +1 -1
- package/blog/zh/intlayer_with_i18next.md +87 -28
- package/blog/zh/intlayer_with_next-i18next.md +86 -29
- package/blog/zh/intlayer_with_next-intl.md +88 -28
- package/blog/zh/intlayer_with_react-i18next.md +87 -28
- package/blog/zh/intlayer_with_react-intl.md +88 -27
- package/blog/zh/intlayer_with_vue-i18n.md +117 -8
- package/blog/zh/rag_powered_documentation_assistant.md +6 -0
- package/dist/cjs/common.cjs +24 -1
- package/dist/cjs/common.cjs.map +1 -1
- package/dist/cjs/generated/blog.entry.cjs +58 -31
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +265 -218
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +48 -21
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +33 -6
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/common.mjs +24 -1
- package/dist/esm/common.mjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +58 -31
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +265 -218
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +48 -21
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs +33 -6
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
- package/dist/types/generated/legal.entry.d.ts.map +1 -1
- package/docs/ar/analytics.md +222 -0
- package/docs/ar/autoFill.md +28 -9
- package/docs/ar/bundle_optimization.md +58 -25
- package/docs/ar/configuration.md +25 -8
- package/docs/ar/dictionary/file.md +3 -1
- package/docs/ar/dictionary/nesting.md +47 -30
- package/docs/ar/formatters.md +148 -193
- package/docs/ar/intlayer_CMS.md +152 -0
- package/docs/ar/intlayer_with_angular_21.md +9 -9
- package/docs/ar/intlayer_with_nextjs_14.md +1 -28
- package/docs/ar/intlayer_with_nextjs_15.md +1 -33
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +40 -83
- package/docs/ar/intlayer_with_solid_start.md +1078 -0
- package/docs/ar/intlayer_with_vite+vue.md +1 -3
- package/docs/ar/live-sync.md +4 -0
- package/docs/ar/packages/intlayer/getLocalizedUrl.md +26 -24
- package/docs/ar/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/ar/packages/react-intlayer/useDictionary.md +4 -21
- package/docs/ar/packages/react-intlayer/useIntlayer.md +2 -2
- package/docs/ar/packages/vite-intlayer/exports.md +15 -0
- package/docs/ar/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/ar/packages/vite-intlayer/intlayerPrune.md +70 -3
- package/docs/ar/releases/v9.md +0 -37
- package/docs/ar/self_hosting.md +46 -49
- package/docs/bn/bundle_optimization.md +58 -25
- package/docs/bn/configuration.md +25 -8
- package/docs/bn/intlayer_with_angular_21.md +9 -9
- package/docs/cs/bundle_optimization.md +58 -25
- package/docs/cs/configuration.md +25 -8
- package/docs/cs/intlayer_with_angular_21.md +9 -9
- package/docs/de/analytics.md +222 -0
- package/docs/de/autoFill.md +28 -9
- package/docs/de/bundle_optimization.md +58 -25
- package/docs/de/configuration.md +25 -8
- package/docs/de/dictionary/file.md +3 -1
- package/docs/de/dictionary/nesting.md +47 -31
- package/docs/de/formatters.md +208 -334
- package/docs/de/intlayer_CMS.md +66 -15
- package/docs/de/intlayer_with_angular_21.md +9 -9
- package/docs/de/intlayer_with_nestjs.md +11 -7
- package/docs/de/intlayer_with_nextjs_14.md +1 -28
- package/docs/de/intlayer_with_nextjs_15.md +1 -33
- package/docs/de/intlayer_with_solid_start.md +1078 -0
- package/docs/de/intlayer_with_vite+vue.md +1 -3
- package/docs/de/live-sync.md +4 -0
- package/docs/de/packages/intlayer/getLocalizedUrl.md +33 -25
- package/docs/de/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/de/packages/react-intlayer/useDictionary.md +2 -5
- package/docs/de/packages/vite-intlayer/exports.md +15 -0
- package/docs/de/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/de/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/de/releases/v9.md +0 -15
- package/docs/de/self_hosting.md +46 -50
- package/docs/en/bundle_optimization.md +51 -23
- package/docs/en/cli/doc-review.md +13 -2
- package/docs/en/configuration.md +24 -15
- package/docs/en/intlayer_with_angular_21.md +9 -9
- package/docs/en/intlayer_with_solid_start.md +1091 -0
- package/docs/en/intlayer_with_vite+solid.md +12 -0
- package/docs/en/live-sync.md +4 -0
- package/docs/en-GB/analytics.md +222 -0
- package/docs/en-GB/autoFill.md +26 -7
- package/docs/en-GB/bundle_optimization.md +58 -25
- package/docs/en-GB/configuration.md +25 -8
- package/docs/en-GB/dictionary/file.md +2 -0
- package/docs/en-GB/dictionary/nesting.md +64 -205
- package/docs/en-GB/formatters.md +146 -181
- package/docs/en-GB/intlayer_CMS.md +152 -0
- package/docs/en-GB/intlayer_with_angular_21.md +9 -9
- package/docs/en-GB/intlayer_with_nestjs.md +6 -2
- package/docs/en-GB/intlayer_with_nextjs_14.md +0 -27
- package/docs/en-GB/intlayer_with_nextjs_15.md +1 -33
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +40 -82
- package/docs/en-GB/intlayer_with_solid_start.md +1078 -0
- package/docs/en-GB/intlayer_with_vite+vue.md +1 -3
- package/docs/en-GB/live-sync.md +4 -0
- package/docs/en-GB/packages/intlayer/getLocalizedUrl.md +30 -22
- package/docs/en-GB/packages/intlayer/getMultilingualUrls.md +16 -48
- package/docs/en-GB/packages/vite-intlayer/exports.md +15 -0
- package/docs/en-GB/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/en-GB/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/en-GB/self_hosting.md +60 -49
- package/docs/es/analytics.md +222 -0
- package/docs/es/autoFill.md +28 -9
- package/docs/es/bundle_optimization.md +58 -25
- package/docs/es/configuration.md +24 -7
- package/docs/es/dictionary/file.md +3 -1
- package/docs/es/dictionary/nesting.md +47 -30
- package/docs/es/formatters.md +114 -168
- package/docs/es/intlayer_CMS.md +35 -10
- package/docs/es/intlayer_with_angular_21.md +9 -9
- package/docs/es/intlayer_with_nextjs_14.md +1 -28
- package/docs/es/intlayer_with_nextjs_15.md +1 -33
- package/docs/es/intlayer_with_solid_start.md +1078 -0
- package/docs/es/live-sync.md +4 -0
- package/docs/es/packages/intlayer/getLocalizedUrl.md +31 -23
- package/docs/es/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/es/packages/vite-intlayer/exports.md +15 -0
- package/docs/es/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/es/packages/vite-intlayer/intlayerPrune.md +69 -2
- package/docs/es/releases/v9.md +0 -15
- package/docs/es/self_hosting.md +46 -49
- package/docs/fr/analytics.md +222 -0
- package/docs/fr/autoFill.md +27 -8
- package/docs/fr/bundle_optimization.md +58 -25
- package/docs/fr/configuration.md +25 -8
- package/docs/fr/dictionary/file.md +2 -0
- package/docs/fr/dictionary/nesting.md +37 -184
- package/docs/fr/formatters.md +95 -236
- package/docs/fr/intlayer_CMS.md +66 -15
- package/docs/fr/intlayer_with_angular_21.md +9 -9
- package/docs/fr/intlayer_with_nextjs_14.md +1 -28
- package/docs/fr/intlayer_with_nextjs_15.md +1 -33
- package/docs/fr/intlayer_with_solid_start.md +1078 -0
- package/docs/fr/live-sync.md +4 -0
- package/docs/fr/packages/intlayer/getLocalizedUrl.md +37 -27
- package/docs/fr/packages/intlayer/getMultilingualUrls.md +18 -20
- package/docs/fr/packages/vite-intlayer/exports.md +15 -0
- package/docs/fr/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/fr/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/fr/releases/v9.md +0 -15
- package/docs/fr/self_hosting.md +46 -49
- package/docs/hi/analytics.md +222 -0
- package/docs/hi/autoFill.md +28 -9
- package/docs/hi/bundle_optimization.md +58 -25
- package/docs/hi/configuration.md +25 -8
- package/docs/hi/dictionary/file.md +3 -1
- package/docs/hi/dictionary/nesting.md +47 -30
- package/docs/hi/formatters.md +233 -334
- package/docs/hi/how_works_intlayer.md +3 -1
- package/docs/hi/intlayer_CMS.md +152 -0
- package/docs/hi/intlayer_with_angular_21.md +9 -9
- package/docs/hi/intlayer_with_nestjs.md +11 -7
- package/docs/hi/intlayer_with_nextjs_14.md +1 -28
- package/docs/hi/intlayer_with_nextjs_15.md +1 -33
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +40 -83
- package/docs/hi/intlayer_with_solid_start.md +1077 -0
- package/docs/hi/intlayer_with_vite+preact.md +56 -49
- package/docs/hi/intlayer_with_vite+react.md +48 -41
- package/docs/hi/intlayer_with_vite+solid.md +32 -41
- package/docs/hi/intlayer_with_vite+vue.md +49 -44
- package/docs/hi/live-sync.md +4 -0
- package/docs/hi/packages/intlayer/getLocalizedUrl.md +26 -24
- package/docs/hi/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/hi/packages/next-intlayer/t.md +33 -1
- package/docs/hi/packages/react-intlayer/useDictionary.md +4 -21
- package/docs/hi/packages/vite-intlayer/exports.md +15 -0
- package/docs/hi/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/hi/packages/vite-intlayer/intlayerPrune.md +78 -5
- package/docs/hi/plugins/sync-json.md +9 -9
- package/docs/hi/releases/v9.md +0 -15
- package/docs/hi/self_hosting.md +38 -51
- package/docs/id/analytics.md +223 -0
- package/docs/id/bundle_optimization.md +58 -25
- package/docs/id/configuration.md +25 -8
- package/docs/id/dictionary/nesting.md +37 -184
- package/docs/id/formatters.md +208 -305
- package/docs/id/intlayer_CMS.md +164 -0
- package/docs/id/intlayer_with_angular_21.md +9 -9
- package/docs/id/intlayer_with_nextjs_14.md +1 -26
- package/docs/id/intlayer_with_react_router_v7_fs_routes.md +70 -63
- package/docs/id/intlayer_with_solid_start.md +1078 -0
- package/docs/id/live-sync.md +4 -0
- package/docs/id/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/id/packages/react-intlayer/useIntlayer.md +2 -2
- package/docs/id/packages/vite-intlayer/exports.md +15 -0
- package/docs/id/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/id/packages/vite-intlayer/intlayerPrune.md +78 -5
- package/docs/id/releases/v9.md +12 -0
- package/docs/id/self_hosting.md +61 -50
- package/docs/it/analytics.md +222 -0
- package/docs/it/autoFill.md +27 -8
- package/docs/it/bundle_optimization.md +58 -25
- package/docs/it/configuration.md +25 -8
- package/docs/it/dictionary/file.md +3 -1
- package/docs/it/dictionary/nesting.md +47 -30
- package/docs/it/formatters.md +114 -168
- package/docs/it/intlayer_CMS.md +66 -15
- package/docs/it/intlayer_with_angular_21.md +9 -9
- package/docs/it/intlayer_with_nestjs.md +11 -7
- package/docs/it/intlayer_with_nextjs_14.md +1 -28
- package/docs/it/intlayer_with_nextjs_15.md +1 -33
- package/docs/it/intlayer_with_solid_start.md +1078 -0
- package/docs/it/intlayer_with_vite+vue.md +1 -3
- package/docs/it/live-sync.md +4 -0
- package/docs/it/packages/intlayer/getLocalizedUrl.md +34 -26
- package/docs/it/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/it/packages/react-intlayer/useDictionary.md +4 -21
- package/docs/it/packages/vite-intlayer/exports.md +15 -0
- package/docs/it/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/it/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/it/releases/v9.md +0 -15
- package/docs/it/self_hosting.md +60 -49
- package/docs/ja/analytics.md +222 -0
- package/docs/ja/autoFill.md +28 -9
- package/docs/ja/bundle_optimization.md +58 -25
- package/docs/ja/configuration.md +25 -8
- package/docs/ja/dictionary/content_file.md +15 -7
- package/docs/ja/dictionary/file.md +3 -1
- package/docs/ja/dictionary/nesting.md +47 -30
- package/docs/ja/formatters.md +133 -187
- package/docs/ja/intlayer_visual_editor.md +3 -1
- package/docs/ja/intlayer_with_angular_21.md +6 -6
- package/docs/ja/intlayer_with_nestjs.md +2 -12
- package/docs/ja/intlayer_with_nextjs_14.md +1 -28
- package/docs/ja/intlayer_with_nextjs_15.md +1 -33
- package/docs/ja/intlayer_with_react_router_v7.md +456 -20
- package/docs/ja/intlayer_with_solid_start.md +1078 -0
- package/docs/ja/intlayer_with_vite+preact.md +73 -41
- package/docs/ja/intlayer_with_vite+vue.md +1 -3
- package/docs/ja/live-sync.md +4 -0
- package/docs/ja/mcp_server.md +3 -9
- package/docs/ja/packages/intlayer/getLocalizedUrl.md +26 -24
- package/docs/ja/packages/intlayer/getMultilingualUrls.md +3 -17
- package/docs/ja/packages/vite-intlayer/exports.md +15 -0
- package/docs/ja/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/ja/packages/vite-intlayer/intlayerPrune.md +79 -6
- package/docs/ja/releases/v9.md +12 -0
- package/docs/ja/self_hosting.md +46 -50
- package/docs/ko/analytics.md +222 -0
- package/docs/ko/autoFill.md +28 -9
- package/docs/ko/bundle_optimization.md +58 -25
- package/docs/ko/configuration.md +25 -8
- package/docs/ko/dictionary/file.md +3 -1
- package/docs/ko/dictionary/nesting.md +47 -30
- package/docs/ko/formatters.md +133 -187
- package/docs/ko/intlayer_with_angular_21.md +9 -9
- package/docs/ko/intlayer_with_lynx+react.md +133 -39
- package/docs/ko/intlayer_with_nextjs_14.md +1 -28
- package/docs/ko/intlayer_with_nextjs_15.md +1 -33
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +40 -188
- package/docs/ko/intlayer_with_solid_start.md +1078 -0
- package/docs/ko/intlayer_with_vite+preact.md +57 -23
- package/docs/ko/intlayer_with_vite+vue.md +1 -3
- package/docs/ko/live-sync.md +4 -0
- package/docs/ko/packages/intlayer/getLocalizedUrl.md +26 -24
- package/docs/ko/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/ko/packages/vite-intlayer/exports.md +15 -0
- package/docs/ko/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/ko/packages/vite-intlayer/intlayerPrune.md +79 -6
- package/docs/ko/releases/v9.md +12 -0
- package/docs/ko/self_hosting.md +60 -49
- package/docs/nl/bundle_optimization.md +58 -25
- package/docs/nl/configuration.md +25 -8
- package/docs/nl/intlayer_with_angular_21.md +9 -9
- package/docs/pl/analytics.md +220 -0
- package/docs/pl/bundle_optimization.md +58 -25
- package/docs/pl/configuration.md +25 -8
- package/docs/pl/dictionary/nesting.md +47 -30
- package/docs/pl/formatters.md +208 -305
- package/docs/pl/intlayer_CMS.md +152 -0
- package/docs/pl/intlayer_with_angular_21.md +9 -9
- package/docs/pl/intlayer_with_nextjs_14.md +1 -26
- package/docs/pl/intlayer_with_solid_start.md +1078 -0
- package/docs/pl/live-sync.md +4 -0
- package/docs/pl/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/pl/packages/react-intlayer/useDictionary.md +2 -19
- package/docs/pl/packages/vite-intlayer/exports.md +15 -0
- package/docs/pl/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/pl/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/pl/releases/v9.md +0 -15
- package/docs/pl/self_hosting.md +60 -49
- package/docs/pt/analytics.md +222 -0
- package/docs/pt/bundle_optimization.md +58 -24
- package/docs/pt/configuration.md +25 -8
- package/docs/pt/dictionary/file.md +3 -1
- package/docs/pt/dictionary/nesting.md +47 -30
- package/docs/pt/formatters.md +112 -168
- package/docs/pt/intlayer_CMS.md +66 -15
- package/docs/pt/intlayer_with_angular_21.md +9 -9
- package/docs/pt/intlayer_with_astro_lit.md +26 -1
- package/docs/pt/intlayer_with_nextjs_14.md +1 -28
- package/docs/pt/intlayer_with_nextjs_15.md +1 -33
- package/docs/pt/intlayer_with_solid_start.md +1078 -0
- package/docs/pt/intlayer_with_vite+vue.md +1 -3
- package/docs/pt/live-sync.md +4 -0
- package/docs/pt/packages/intlayer/getLocalizedUrl.md +34 -26
- package/docs/pt/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/pt/packages/vite-intlayer/exports.md +15 -0
- package/docs/pt/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/pt/packages/vite-intlayer/intlayerPrune.md +78 -6
- package/docs/pt/releases/v9.md +0 -15
- package/docs/pt/self_hosting.md +60 -49
- package/docs/ru/analytics.md +222 -0
- package/docs/ru/autoFill.md +27 -8
- package/docs/ru/bundle_optimization.md +58 -25
- package/docs/ru/configuration.md +25 -8
- package/docs/ru/dictionary/file.md +3 -1
- package/docs/ru/dictionary/nesting.md +64 -205
- package/docs/ru/formatters.md +108 -128
- package/docs/ru/intlayer_with_angular_21.md +9 -9
- package/docs/ru/intlayer_with_nextjs_14.md +1 -28
- package/docs/ru/intlayer_with_nextjs_15.md +1 -33
- package/docs/ru/intlayer_with_solid_start.md +1078 -0
- package/docs/ru/intlayer_with_vite+vue.md +1 -3
- package/docs/ru/live-sync.md +4 -0
- package/docs/ru/packages/intlayer/getLocalizedUrl.md +34 -26
- package/docs/ru/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/ru/packages/react-intlayer/useDictionary.md +4 -21
- package/docs/ru/packages/vite-intlayer/exports.md +15 -0
- package/docs/ru/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/ru/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/ru/releases/v9.md +0 -15
- package/docs/ru/self_hosting.md +60 -49
- package/docs/tr/analytics.md +222 -0
- package/docs/tr/autoFill.md +28 -9
- package/docs/tr/bundle_optimization.md +58 -25
- package/docs/tr/configuration.md +25 -8
- package/docs/tr/dictionary/file.md +2 -0
- package/docs/tr/dictionary/nesting.md +47 -30
- package/docs/tr/formatters.md +144 -190
- package/docs/tr/intlayer_CMS.md +152 -0
- package/docs/tr/intlayer_with_angular_21.md +9 -9
- package/docs/tr/intlayer_with_nestjs.md +2 -12
- package/docs/tr/intlayer_with_nextjs_15.md +1 -33
- package/docs/tr/intlayer_with_solid_start.md +1078 -0
- package/docs/tr/intlayer_with_vite+vue.md +1 -3
- package/docs/tr/live-sync.md +4 -0
- package/docs/tr/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/tr/packages/vite-intlayer/exports.md +15 -0
- package/docs/tr/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/tr/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/tr/self_hosting.md +47 -50
- package/docs/uk/analytics.md +222 -0
- package/docs/uk/bundle_optimization.md +58 -25
- package/docs/uk/configuration.md +25 -8
- package/docs/uk/dictionary/nesting.md +47 -30
- package/docs/uk/formatters.md +128 -185
- package/docs/uk/intlayer_CMS.md +152 -0
- package/docs/uk/intlayer_with_angular_21.md +9 -9
- package/docs/uk/intlayer_with_nextjs_14.md +1 -26
- package/docs/uk/intlayer_with_solid_start.md +1078 -0
- package/docs/uk/live-sync.md +4 -0
- package/docs/uk/packages/react-intlayer/useDictionary.md +2 -19
- package/docs/uk/packages/vite-intlayer/exports.md +15 -0
- package/docs/uk/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/uk/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/uk/releases/v9.md +0 -15
- package/docs/uk/self_hosting.md +60 -50
- package/docs/ur/bundle_optimization.md +58 -25
- package/docs/ur/configuration.md +25 -8
- package/docs/ur/intlayer_with_angular_21.md +9 -9
- package/docs/vi/analytics.md +222 -0
- package/docs/vi/bundle_optimization.md +58 -25
- package/docs/vi/configuration.md +24 -8
- package/docs/vi/dictionary/nesting.md +37 -184
- package/docs/vi/formatters.md +208 -309
- package/docs/vi/intlayer_CMS.md +164 -0
- package/docs/vi/intlayer_with_angular_21.md +9 -9
- package/docs/vi/intlayer_with_nextjs_14.md +0 -25
- package/docs/vi/intlayer_with_react_router_v7_fs_routes.md +70 -63
- package/docs/vi/intlayer_with_solid_start.md +1078 -0
- package/docs/vi/live-sync.md +4 -0
- package/docs/vi/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/vi/packages/react-intlayer/useIntlayer.md +2 -2
- package/docs/vi/packages/vite-intlayer/exports.md +15 -0
- package/docs/vi/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/vi/packages/vite-intlayer/intlayerPrune.md +77 -4
- package/docs/vi/plugins/sync-json.md +6 -6
- package/docs/vi/releases/v9.md +12 -0
- package/docs/vi/self_hosting.md +61 -50
- package/docs/zh/CI_CD.md +4 -0
- package/docs/zh/analytics.md +222 -0
- package/docs/zh/autoFill.md +28 -9
- package/docs/zh/bundle_optimization.md +58 -25
- package/docs/zh/configuration.md +24 -8
- package/docs/zh/dictionary/file.md +2 -0
- package/docs/zh/dictionary/nesting.md +47 -30
- package/docs/zh/formatters.md +140 -188
- package/docs/zh/intlayer_CMS.md +164 -0
- package/docs/zh/intlayer_with_analog.md +193 -3
- package/docs/zh/intlayer_with_angular_19.md +272 -3
- package/docs/zh/intlayer_with_angular_21.md +7 -7
- package/docs/zh/intlayer_with_create_react_app.md +348 -26
- package/docs/zh/intlayer_with_lynx+react.md +263 -4
- package/docs/zh/intlayer_with_nextjs_14.md +1 -28
- package/docs/zh/intlayer_with_nextjs_15.md +1 -33
- package/docs/zh/intlayer_with_nextjs_no_locale_path.md +558 -1
- package/docs/zh/intlayer_with_nuxt.md +182 -7
- package/docs/zh/intlayer_with_react_router_v7.md +183 -25
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +306 -42
- package/docs/zh/intlayer_with_solid_start.md +1077 -0
- package/docs/zh/intlayer_with_storybook.md +260 -3
- package/docs/zh/intlayer_with_svelte_kit.md +428 -48
- package/docs/zh/intlayer_with_tanstack+solid.md +713 -13
- package/docs/zh/intlayer_with_tanstack.md +731 -20
- package/docs/zh/intlayer_with_vanilla.md +314 -4
- package/docs/zh/intlayer_with_vite+lit.md +465 -4
- package/docs/zh/intlayer_with_vite+preact.md +422 -116
- package/docs/zh/intlayer_with_vite+react.md +324 -45
- package/docs/zh/intlayer_with_vite+react_compiler.md +228 -13
- package/docs/zh/intlayer_with_vite+solid.md +462 -32
- package/docs/zh/intlayer_with_vite+vanilla.md +497 -4
- package/docs/zh/live-sync.md +4 -0
- package/docs/zh/mcp_server.md +3 -9
- package/docs/zh/packages/intlayer/getLocalizedUrl.md +26 -24
- package/docs/zh/packages/intlayer/getMultilingualUrls.md +4 -18
- package/docs/zh/packages/vite-intlayer/exports.md +29 -0
- package/docs/zh/packages/vite-intlayer/intlayer.md +121 -6
- package/docs/zh/packages/vite-intlayer/intlayerPrune.md +79 -6
- package/docs/zh/releases/v9.md +12 -0
- package/docs/zh/self_hosting.md +60 -50
- package/docs/zh-TW/bundle_optimization.md +58 -25
- package/docs/zh-TW/intlayer_with_angular_21.md +7 -7
- package/package.json +7 -7
- package/src/common.ts +39 -2
- package/src/generated/blog.entry.ts +66 -34
- package/src/generated/docs.entry.ts +273 -221
- package/src/generated/frequentQuestions.entry.ts +56 -24
- package/src/generated/legal.entry.ts +41 -9
|
@@ -33,7 +33,7 @@ author: aymericzip
|
|
|
33
33
|
|
|
34
34
|
<Tabs defaultTab="video">
|
|
35
35
|
<Tab label="视频" value="video">
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
<iframe title="The best i18n solution for Vite and Preact? Discover 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"/>
|
|
38
38
|
|
|
39
39
|
</Tab>
|
|
@@ -99,7 +99,69 @@ Intlayer 不仅仅是一个 i18n 解决方案,还提供了一个**自托管的
|
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
## 在 Vite 和 Preact 应用中设置 Intlayer 的分步指南
|
|
103
|
+
|
|
104
|
+
查看 GitHub 上的[应用模板](https://github.com/aymericzip/intlayer-vite-preact-template)。
|
|
105
|
+
|
|
106
|
+
<Steps>
|
|
107
|
+
|
|
108
|
+
<Step number={1} title="安装依赖">
|
|
109
|
+
|
|
110
|
+
使用 npm 安装必要的包:
|
|
111
|
+
|
|
112
|
+
```bash packageManager="npm"
|
|
113
|
+
npx intlayer init --interactive
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```bash packageManager="pnpm"
|
|
117
|
+
pnpm dlx intlayer@canary init --interactive
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```bash packageManager="yarn"
|
|
121
|
+
yarn dlx intlayer@canary init --interactive
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```bash packageManager="bun"
|
|
125
|
+
bunx intlayer@canary init --interactive
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
> `--interactive` 标志是可选的。如果您是 AI 代理,请使用 `intlayer-cli init`。
|
|
129
|
+
|
|
130
|
+
> 此命令将检测您的环境并安装所需的包。例如:
|
|
131
|
+
|
|
132
|
+
```bash packageManager="npm"
|
|
133
|
+
npm install intlayer preact-intlayer
|
|
134
|
+
npm install vite-intlayer --save-dev
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```bash packageManager="pnpm"
|
|
138
|
+
pnpm add intlayer preact-intlayer
|
|
139
|
+
pnpm add vite-intlayer --save-dev
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```bash packageManager="yarn"
|
|
143
|
+
yarn add intlayer preact-intlayer
|
|
144
|
+
yarn add vite-intlayer --save-dev
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```bash packageManager="bun"
|
|
148
|
+
bun add intlayer preact-intlayer
|
|
149
|
+
bun add vite-intlayer --dev
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- **intlayer**
|
|
153
|
+
|
|
154
|
+
核心包,为配置管理、翻译、[内容声明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/content_file.md)、转译和 [CLI 命令](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/cli/index.md)提供国际化工具。
|
|
155
|
+
|
|
156
|
+
- **preact-intlayer**
|
|
157
|
+
将 Intlayer 与 Preact 应用集成的包。它为 Preact 国际化提供上下文提供程序和钩子。
|
|
158
|
+
|
|
159
|
+
- **vite-intlayer**
|
|
160
|
+
包含用于将 Intlayer 与 [Vite 打包器](https://vite.dev/guide/why.html#why-bundle-for-production)集成的 Vite 插件,以及用于检测用户首选语言、管理 Cookie 和处理 URL 重定向的中间件。
|
|
161
|
+
|
|
162
|
+
</Step>
|
|
163
|
+
|
|
164
|
+
<Step number={2} title="配置您的项目">
|
|
103
165
|
|
|
104
166
|
创建一个配置文件来配置应用程序的语言:
|
|
105
167
|
|
|
@@ -117,17 +179,19 @@ const config: IntlayerConfig = {
|
|
|
117
179
|
defaultLocale: Locales.ENGLISH,
|
|
118
180
|
},
|
|
119
181
|
routing: {
|
|
120
|
-
mode: "prefix-no-default", //
|
|
121
|
-
storage: ["cookie", "header"], //
|
|
182
|
+
mode: "prefix-no-default", // 默认:为除默认语言外的所有语言添加前缀
|
|
183
|
+
storage: ["cookie", "header"], // 默认:将语言存储在 Cookie 中并从标头检测
|
|
122
184
|
},
|
|
123
185
|
};
|
|
124
186
|
|
|
125
187
|
export default config;
|
|
126
188
|
```
|
|
127
189
|
|
|
128
|
-
> 通过此配置文件,您可以设置本地化 URL、路由模式、存储选项、
|
|
190
|
+
> 通过此配置文件,您可以设置本地化 URL、路由模式、存储选项、Cookie 名称、内容声明的位置和扩展名、禁用控制台中的 Intlayer 日志等。有关可用参数的完整列表,请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
|
|
191
|
+
|
|
192
|
+
</Step>
|
|
129
193
|
|
|
130
|
-
|
|
194
|
+
<Step number={3} title="在您的 Vite 配置中集成 Intlayer">
|
|
131
195
|
|
|
132
196
|
将 intlayer 插件添加到您的配置中。
|
|
133
197
|
|
|
@@ -142,11 +206,13 @@ export default defineConfig({
|
|
|
142
206
|
});
|
|
143
207
|
```
|
|
144
208
|
|
|
145
|
-
> `intlayer()` Vite 插件用于将 Intlayer 与 Vite
|
|
209
|
+
> `intlayer()` Vite 插件用于将 Intlayer 与 Vite 集成。它确保内容声明文件的构建,并在开发模式下监视它们。它在 Vite 应用中定义 Intlayer 环境变量。此外,它还提供别名以优化性能。
|
|
146
210
|
|
|
147
|
-
|
|
211
|
+
</Step>
|
|
212
|
+
|
|
213
|
+
<Step number={4} title="声明您的内容">
|
|
148
214
|
|
|
149
|
-
|
|
215
|
+
创建和管理您的内容声明以存储翻译:
|
|
150
216
|
|
|
151
217
|
```tsx fileName="src/app.content.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
152
218
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -156,11 +222,13 @@ const appContent = {
|
|
|
156
222
|
key: "app",
|
|
157
223
|
content: {
|
|
158
224
|
viteLogo: t({
|
|
225
|
+
zh: "Vite 徽标",
|
|
159
226
|
en: "Vite logo",
|
|
160
227
|
fr: "Logo Vite",
|
|
161
228
|
es: "Logo Vite",
|
|
162
229
|
}),
|
|
163
230
|
preactLogo: t({
|
|
231
|
+
zh: "Preact 徽标",
|
|
164
232
|
en: "Preact logo",
|
|
165
233
|
fr: "Logo Preact",
|
|
166
234
|
es: "Logo Preact",
|
|
@@ -169,12 +237,18 @@ const appContent = {
|
|
|
169
237
|
title: "Vite + Preact",
|
|
170
238
|
|
|
171
239
|
count: t({
|
|
240
|
+
zh: "计数是 ",
|
|
172
241
|
en: "count is ",
|
|
173
242
|
fr: "le compte est ",
|
|
174
243
|
es: "el recuento es ",
|
|
175
244
|
}),
|
|
176
245
|
|
|
177
246
|
edit: t<ComponentChildren>({
|
|
247
|
+
zh: (
|
|
248
|
+
<>
|
|
249
|
+
编辑 <code>src/app.tsx</code> 并保存以测试 HMR
|
|
250
|
+
</>
|
|
251
|
+
),
|
|
178
252
|
en: (
|
|
179
253
|
<>
|
|
180
254
|
Edit <code>src/app.tsx</code> and save to test HMR
|
|
@@ -193,6 +267,7 @@ const appContent = {
|
|
|
193
267
|
}),
|
|
194
268
|
|
|
195
269
|
readTheDocs: t({
|
|
270
|
+
zh: "点击 Vite 和 Preact 徽标了解更多",
|
|
196
271
|
en: "Click on the Vite and Preact logos to learn more",
|
|
197
272
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
198
273
|
es: "Haga clic en los logotipos de Vite y Preact para obtener más información",
|
|
@@ -211,6 +286,7 @@ export default appContent;
|
|
|
211
286
|
"viteLogo": {
|
|
212
287
|
"nodeType": "translation",
|
|
213
288
|
"translation": {
|
|
289
|
+
"zh": "Vite 徽标",
|
|
214
290
|
"en": "Vite logo",
|
|
215
291
|
"fr": "Logo Vite",
|
|
216
292
|
"es": "Logo Vite"
|
|
@@ -219,6 +295,7 @@ export default appContent;
|
|
|
219
295
|
"preactLogo": {
|
|
220
296
|
"nodeType": "translation",
|
|
221
297
|
"translation": {
|
|
298
|
+
"zh": "Preact 徽标",
|
|
222
299
|
"en": "Preact logo",
|
|
223
300
|
"fr": "Logo Preact",
|
|
224
301
|
"es": "Logo Preact"
|
|
@@ -227,6 +304,7 @@ export default appContent;
|
|
|
227
304
|
"title": {
|
|
228
305
|
"nodeType": "translation",
|
|
229
306
|
"translation": {
|
|
307
|
+
"zh": "Vite + Preact",
|
|
230
308
|
"en": "Vite + Preact",
|
|
231
309
|
"fr": "Vite + Preact",
|
|
232
310
|
"es": "Vite + Preact"
|
|
@@ -235,6 +313,7 @@ export default appContent;
|
|
|
235
313
|
"count": {
|
|
236
314
|
"nodeType": "translation",
|
|
237
315
|
"translation": {
|
|
316
|
+
"zh": "计数是 ",
|
|
238
317
|
"en": "count is ",
|
|
239
318
|
"fr": "le compte est ",
|
|
240
319
|
"es": "el recuento es "
|
|
@@ -243,6 +322,7 @@ export default appContent;
|
|
|
243
322
|
"edit": {
|
|
244
323
|
"nodeType": "translation",
|
|
245
324
|
"translation": {
|
|
325
|
+
"zh": "编辑 src/app.tsx 并保存以测试 HMR",
|
|
246
326
|
"en": "Edit src/app.tsx and save to test HMR",
|
|
247
327
|
"fr": "Éditez src/app.tsx et enregistrez pour tester HMR",
|
|
248
328
|
"es": "Edita src/app.tsx y guarda para probar HMR"
|
|
@@ -251,6 +331,7 @@ export default appContent;
|
|
|
251
331
|
"readTheDocs": {
|
|
252
332
|
"nodeType": "translation",
|
|
253
333
|
"translation": {
|
|
334
|
+
"zh": "点击 Vite 和 Preact 徽标了解更多",
|
|
254
335
|
"en": "Click on the Vite and Preact logos to learn more",
|
|
255
336
|
"fr": "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
256
337
|
"es": "Haga clic en los logotipos de Vite y Preact para obtener más información"
|
|
@@ -260,15 +341,91 @@ export default appContent;
|
|
|
260
341
|
}
|
|
261
342
|
```
|
|
262
343
|
|
|
263
|
-
>
|
|
344
|
+
> 您的内容声明可以在应用程序中的任何位置定义,只要它们包含在 `contentDir` 目录中(默认为 `./src`),并且匹配内容声明文件扩展名(默认为 `.content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}`)。
|
|
345
|
+
|
|
346
|
+
> 有关更多详情,请参阅[内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/content_file.md)。
|
|
347
|
+
|
|
348
|
+
> 如果您的内容文件包含 TSX 代码,您可能需要导入 `import { h } from "preact";` 或确保您的 JSX pragma 为 Preact 正确设置。
|
|
349
|
+
|
|
350
|
+
</Step>
|
|
351
|
+
|
|
352
|
+
<Step number={5} title="在您的代码中使用 Intlayer">
|
|
353
|
+
|
|
354
|
+
在整个应用程序中访问您的内容字典:
|
|
355
|
+
|
|
356
|
+
```tsx {6,10} fileName="src/app.tsx" codeFormat={["typescript", "esm"]}
|
|
357
|
+
import { useState } from "preact/hooks";
|
|
358
|
+
import type { FunctionalComponent } from "preact";
|
|
359
|
+
import preactLogo from "./assets/preact.svg"; // 假设您有 preact.svg
|
|
360
|
+
import viteLogo from "/vite.svg";
|
|
361
|
+
import "./app.css"; // 假设您的 CSS 文件名为 app.css
|
|
362
|
+
import { IntlayerProvider, useIntlayer } from "preact-intlayer";
|
|
363
|
+
|
|
364
|
+
const AppContent: FunctionalComponent = () => {
|
|
365
|
+
const [count, setCount] = useState(0);
|
|
366
|
+
const content = useIntlayer("app");
|
|
367
|
+
|
|
368
|
+
return (
|
|
369
|
+
<>
|
|
370
|
+
<div>
|
|
371
|
+
<a href="https://vitejs.dev" target="_blank">
|
|
372
|
+
<img src={viteLogo} class="logo" alt={content.viteLogo.value} />
|
|
373
|
+
</a>
|
|
374
|
+
<a href="https://preactjs.com" target="_blank">
|
|
375
|
+
<img
|
|
376
|
+
src={preactLogo}
|
|
377
|
+
class="logo preact"
|
|
378
|
+
alt={content.preactLogo.value}
|
|
379
|
+
/>
|
|
380
|
+
</a>
|
|
381
|
+
</div>
|
|
382
|
+
<h1>{content.title}</h1>
|
|
383
|
+
<div class="card">
|
|
384
|
+
<button onClick={() => setCount((count) => count + 1)}>
|
|
385
|
+
{content.count}
|
|
386
|
+
{count}
|
|
387
|
+
</button>
|
|
388
|
+
<p>{content.edit}</p>
|
|
389
|
+
</div>
|
|
390
|
+
{/* Markdown 内容 */}
|
|
391
|
+
<div>{content.myMarkdownContent}</div>
|
|
392
|
+
|
|
393
|
+
{/* HTML 内容 */}
|
|
394
|
+
<div>{content.myHtmlContent}</div>
|
|
395
|
+
|
|
396
|
+
<p class="read-the-docs">{content.readTheDocs}</p>
|
|
397
|
+
</>
|
|
398
|
+
);
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const App: FunctionalComponent = () => (
|
|
402
|
+
<IntlayerProvider>
|
|
403
|
+
<AppContent />
|
|
404
|
+
</IntlayerProvider>
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
export default App;
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
> 如果您想在 `string` 属性中使用您的内容,例如 `alt`、`title`、`href`、`aria-label` 等,您可以使用函数的值,如:
|
|
264
411
|
|
|
265
|
-
>
|
|
412
|
+
> ```html
|
|
413
|
+
> <img src="{content.image.src.value}" alt="{content.image.value}" />
|
|
414
|
+
> <img src="{content.image.src.toString()}" alt="{content.image.toString()}" />
|
|
415
|
+
> <img src="{String(content.image.src)}" alt="{String(content.image)}" />
|
|
416
|
+
> ```
|
|
266
417
|
|
|
267
|
-
>
|
|
418
|
+
> 注意:在 Preact 中,`className` 通常写成 `class`。
|
|
268
419
|
|
|
269
|
-
|
|
420
|
+
> 要了解更多关于 `useIntlayer` 钩子的信息,请参阅[文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useIntlayer.md)(对于 `preact-intlayer` 的 API 类似)。
|
|
270
421
|
|
|
271
|
-
|
|
422
|
+
> 如果您的应用程序已经存在,您可以使用 [Intlayer Compiler](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/compiler.md) 以及[提取命令](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/cli/extract.md)在一秒内转换数千个组件。
|
|
423
|
+
|
|
424
|
+
</Step>
|
|
425
|
+
|
|
426
|
+
<Step number={6} title="更改您的内容语言" isOptional={true}>
|
|
427
|
+
|
|
428
|
+
要更改您的内容语言,您可以使用 `useLocale` 钩子提供的 `setLocale` 函数。此函数允许您设置应用程序的语言环境并相应地更新内容。
|
|
272
429
|
|
|
273
430
|
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat={["typescript", "esm"]}
|
|
274
431
|
import type { FunctionalComponent } from "preact";
|
|
@@ -279,22 +436,20 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
279
436
|
const { setLocale } = useLocale();
|
|
280
437
|
|
|
281
438
|
return (
|
|
282
|
-
<button onClick={() => setLocale(Locales.ENGLISH)}>
|
|
283
|
-
Change Language to English
|
|
284
|
-
</button>
|
|
439
|
+
<button onClick={() => setLocale(Locales.ENGLISH)}>更改语言为英文</button>
|
|
285
440
|
);
|
|
286
441
|
};
|
|
287
442
|
|
|
288
443
|
export default LocaleSwitcher;
|
|
289
444
|
```
|
|
290
445
|
|
|
291
|
-
>
|
|
446
|
+
> 要了解更多关于 `useLocale` 钩子的信息,请参阅[文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)(对于 `preact-intlayer` 的 API 类似)。
|
|
292
447
|
|
|
293
|
-
|
|
448
|
+
</Step>
|
|
294
449
|
|
|
295
|
-
<Step number={7} title="
|
|
450
|
+
<Step number={7} title="向您的应用程序添加本地化路由" isOptional={true}>
|
|
296
451
|
|
|
297
|
-
|
|
452
|
+
此步骤的目的是为每种语言创建唯一的路由。这对 SEO 和 SEO 友好的 URL 很有用。
|
|
298
453
|
示例:
|
|
299
454
|
|
|
300
455
|
```plaintext
|
|
@@ -303,9 +458,9 @@ export default LocaleSwitcher;
|
|
|
303
458
|
- https://example.com/fr/about
|
|
304
459
|
```
|
|
305
460
|
|
|
306
|
-
>
|
|
461
|
+
> 默认情况下,默认语言的路由不带前缀。如果您想为默认语言添加前缀,可以在配置中将 `routing.mode` 选项设置为 `"prefix-all"`。有关更多信息,请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
|
|
307
462
|
|
|
308
|
-
|
|
463
|
+
要向您的应用程序添加本地化路由,您可以创建一个 `LocaleRouter` 组件来包装您的应用程序的路由并处理基于语言的路由。这是一个使用 [preact-iso](https://github.com/preactjs/preact-iso) 的示例:
|
|
309
464
|
|
|
310
465
|
```tsx fileName="src/components/LocaleRouter.tsx" codeFormat={["typescript", "esm"]}
|
|
311
466
|
import { localeMap } from "intlayer";
|
|
@@ -314,8 +469,8 @@ import { LocationProvider, Router, Route } from "preact-iso";
|
|
|
314
469
|
import type { ComponentChildren, FunctionalComponent } from "preact";
|
|
315
470
|
|
|
316
471
|
/**
|
|
317
|
-
*
|
|
318
|
-
* 它使用 preact-iso
|
|
472
|
+
* 设置特定于语言的路由的路由器组件。
|
|
473
|
+
* 它使用 preact-iso 来管理导航和呈现本地化的组件。
|
|
319
474
|
*/
|
|
320
475
|
export const LocaleRouter: FunctionalComponent<{
|
|
321
476
|
children: ComponentChildren;
|
|
@@ -338,7 +493,7 @@ export const LocaleRouter: FunctionalComponent<{
|
|
|
338
493
|
);
|
|
339
494
|
```
|
|
340
495
|
|
|
341
|
-
|
|
496
|
+
然后,您可以在您的应用程序中使用 `LocaleRouter` 组件:
|
|
342
497
|
|
|
343
498
|
```tsx fileName="src/app.tsx" codeFormat={["typescript", "esm"]}
|
|
344
499
|
import { LocaleRouter } from "./components/LocaleRouter";
|
|
@@ -355,11 +510,35 @@ const App: FunctionalComponent = () => (
|
|
|
355
510
|
export default App;
|
|
356
511
|
```
|
|
357
512
|
|
|
513
|
+
同时,您也可以使用 `intlayerProxy` 向您的应用程序添加服务器端路由。此插件将根据 URL 自动检测当前的语言环境并设置适当的语言 Cookie。如果未指定语言环境,该插件将根据用户的浏览器语言偏好确定最合适的语言环境。如果未检测到任何语言环境,它将重定向到默认语言环境。
|
|
514
|
+
|
|
515
|
+
> 注意,要在生产中使用 `intlayerProxy`,您需要将 `vite-intlayer` 包从 `devDependencies` 切换到 `dependencies`。
|
|
516
|
+
|
|
517
|
+
> 自 Intlayer v9 起,`intlayerProxy()` 直接捆绑到 `intlayer()` 插件中,并通过 `routing.enableProxy` 选项默认启用(默认为 `true`)。如下所示单独注册它现在是可选的——为了向后兼容和需要控制插件顺序的设置而保留。设置 `routing.enableProxy: false` 以选择退出。查看 [v9 发布说明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/releases/v9.md)。
|
|
518
|
+
|
|
519
|
+
```typescript {3,7} fileName="vite.config.ts"
|
|
520
|
+
import { defineConfig } from "vite";
|
|
521
|
+
import { intlayer } from "vite-intlayer";
|
|
522
|
+
import preact from "@preact/preset-vite";
|
|
523
|
+
|
|
524
|
+
// https://vitejs.dev/config/
|
|
525
|
+
export default defineConfig({
|
|
526
|
+
plugins: [
|
|
527
|
+
preact(),
|
|
528
|
+
intlayer({
|
|
529
|
+
proxy: {
|
|
530
|
+
ignore: (req) => req.url?.startsWith("/api"),
|
|
531
|
+
},
|
|
532
|
+
}),
|
|
533
|
+
],
|
|
534
|
+
});
|
|
535
|
+
```
|
|
536
|
+
|
|
358
537
|
</Step>
|
|
359
538
|
|
|
360
|
-
<Step number={8} title="
|
|
539
|
+
<Step number={8} title="当语言环境更改时更改 URL" isOptional={true}>
|
|
361
540
|
|
|
362
|
-
要在语言环境更改时更改 URL
|
|
541
|
+
要在语言环境更改时更改 URL,您可以使用 `useLocale` 钩子提供的 `onLocaleChange` 属性。同时,您可以使用 `preact-iso` 中 `useLocation` 的 `route` 方法来更新 URL 路径。
|
|
363
542
|
|
|
364
543
|
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat={["typescript", "esm"]}
|
|
365
544
|
import { useLocation } from "preact-iso";
|
|
@@ -376,12 +555,12 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
376
555
|
const { url, route } = useLocation();
|
|
377
556
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
378
557
|
onLocaleChange: (newLocale) => {
|
|
379
|
-
//
|
|
558
|
+
// 使用更新的语言环境构造 URL
|
|
380
559
|
// 示例:/es/about?foo=bar
|
|
381
560
|
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
382
561
|
|
|
383
562
|
// 更新 URL 路径
|
|
384
|
-
route(pathWithLocale, true); // true
|
|
563
|
+
route(pathWithLocale, true); // true 用于替换
|
|
385
564
|
},
|
|
386
565
|
});
|
|
387
566
|
|
|
@@ -397,7 +576,7 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
397
576
|
onClick={(e) => {
|
|
398
577
|
e.preventDefault();
|
|
399
578
|
setLocale(localeItem);
|
|
400
|
-
//
|
|
579
|
+
// 设置语言环境后的编程导航将由 onLocaleChange 处理
|
|
401
580
|
}}
|
|
402
581
|
key={localeItem}
|
|
403
582
|
>
|
|
@@ -406,15 +585,15 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
406
585
|
{localeItem}
|
|
407
586
|
</span>
|
|
408
587
|
<span>
|
|
409
|
-
{/*
|
|
588
|
+
{/* 其自身语言环境中的语言 - 例如 Français */}
|
|
410
589
|
{getLocaleName(localeItem, localeItem)}
|
|
411
590
|
</span>
|
|
412
591
|
<span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
|
|
413
|
-
{/*
|
|
592
|
+
{/* 当前语言环境中的语言 - 例如 Francés(当前语言环境设置为 Locales.SPANISH 时) */}
|
|
414
593
|
{getLocaleName(localeItem, locale)}
|
|
415
594
|
</span>
|
|
416
595
|
<span dir="ltr" lang={Locales.ENGLISH}>
|
|
417
|
-
{/*
|
|
596
|
+
{/* 英文中的语言 - 例如 French */}
|
|
418
597
|
{getLocaleName(localeItem, Locales.ENGLISH)}
|
|
419
598
|
</span>
|
|
420
599
|
</a>
|
|
@@ -429,25 +608,154 @@ export default LocaleSwitcher;
|
|
|
429
608
|
|
|
430
609
|
> 文档参考:
|
|
431
610
|
>
|
|
432
|
-
> > - [`useLocale` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)
|
|
433
|
-
> >
|
|
611
|
+
> > - [`useLocale` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)(对于 `preact-intlayer` 的 API 类似)
|
|
612
|
+
> > - [`getLocaleName` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocaleName.md)
|
|
613
|
+
> > - [`getLocalizedUrl` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocalizedUrl.md)
|
|
614
|
+
> > - [`getHTMLTextDir` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getHTMLTextDir.md)
|
|
615
|
+
> > - [`hreflang` 属性](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
|
|
616
|
+
> > - [`lang` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/lang)
|
|
617
|
+
> > - [`dir` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/dir)
|
|
618
|
+
> > - [`aria-current` 属性](https://developer.mozilla.org/zh-CN/docs/Web/Accessibility/ARIA/Attributes/aria-current)
|
|
619
|
+
> > - [Popover API](https://developer.mozilla.org/zh-CN/docs/Web/API/Popover_API)
|
|
620
|
+
|
|
621
|
+
以下是更新的**步骤 9**,包含添加的解释和精制的代码示例:
|
|
622
|
+
|
|
623
|
+
---
|
|
624
|
+
|
|
625
|
+
</Step>
|
|
626
|
+
|
|
627
|
+
<Step number={9} title="切换 HTML 语言和方向属性" isOptional={true}>
|
|
628
|
+
|
|
629
|
+
当您的应用程序支持多种语言时,关键是要更新 `<html>` 标签的 `lang` 和 `dir` 属性以匹配当前的语言环境。这样做可以确保:
|
|
630
|
+
|
|
631
|
+
- **可访问性**:屏幕阅读器和辅助技术依赖正确的 `lang` 属性来准确地发音和解释内容。
|
|
632
|
+
- **文本渲染**:`dir`(方向)属性确保文本以适当的顺序呈现(例如,英文为从左到右,阿拉伯语或希伯来语为从右到左),这对可读性至关重要。
|
|
633
|
+
- **SEO**:搜索引擎使用 `lang` 属性来确定您页面的语言,帮助在搜索结果中提供正确的本地化内容。
|
|
634
|
+
|
|
635
|
+
通过在语言环境更改时动态更新这些属性,您可以为所有支持的语言的用户保证一致和可访问的体验。
|
|
636
|
+
|
|
637
|
+
#### 实现钩子
|
|
638
|
+
|
|
639
|
+
创建一个自定义钩子来管理 HTML 属性。该钩子监听语言环境更改并相应地更新属性:
|
|
640
|
+
|
|
641
|
+
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat={["typescript", "esm"]}
|
|
642
|
+
import { useEffect } from "preact/hooks";
|
|
643
|
+
import { useLocale } from "preact-intlayer";
|
|
644
|
+
import { getHTMLTextDir } from "intlayer";
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* 根据当前语言环境更新 HTML <html> 元素的 `lang` 和 `dir` 属性。
|
|
648
|
+
* - `lang`: 通知浏览器和搜索引擎页面的语言。
|
|
649
|
+
* - `dir`: 确保正确的阅读顺序(例如,英语为 'ltr',阿拉伯语为 'rtl')。
|
|
650
|
+
*
|
|
651
|
+
* 这种动态更新对于正确的文本渲染、无障碍访问和 SEO 至关重要。
|
|
652
|
+
*/
|
|
653
|
+
export const useI18nHTMLAttributes = () => {
|
|
654
|
+
const { locale } = useLocale();
|
|
655
|
+
|
|
656
|
+
useEffect(() => {
|
|
657
|
+
// 将语言属性更新为当前语言环境。
|
|
658
|
+
document.documentElement.lang = locale;
|
|
659
|
+
|
|
660
|
+
// 根据当前语言环境设置文本方向。
|
|
661
|
+
document.documentElement.dir = getHTMLTextDir(locale);
|
|
662
|
+
}, [locale]);
|
|
663
|
+
};
|
|
664
|
+
```
|
|
434
665
|
|
|
435
|
-
|
|
666
|
+
#### 在应用程序中使用钩子
|
|
667
|
+
|
|
668
|
+
将钩子集成到您的主组件中,以便在语言环境更改时更新 HTML 属性:
|
|
436
669
|
|
|
437
|
-
|
|
670
|
+
```tsx fileName="src/app.tsx" codeFormat={["typescript", "esm"]}
|
|
671
|
+
import type { FunctionalComponent } from "preact";
|
|
672
|
+
import { IntlayerProvider } from "preact-intlayer"; // 如果 AppContent 需要,useIntlayer 已导入
|
|
673
|
+
import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
|
|
674
|
+
import "./app.css";
|
|
675
|
+
// 第 5 步中的 AppContent 定义
|
|
676
|
+
|
|
677
|
+
const AppWithHooks: FunctionalComponent = () => {
|
|
678
|
+
// 应用钩子以根据语言环境更新 <html> 标签的 lang 和 dir 属性。
|
|
679
|
+
useI18nHTMLAttributes();
|
|
680
|
+
|
|
681
|
+
// 假设 AppContent 是您在第 5 步中的主要内容显示组件
|
|
682
|
+
return <AppContent />;
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
const App: FunctionalComponent = () => (
|
|
686
|
+
<IntlayerProvider>
|
|
687
|
+
<AppWithHooks />
|
|
688
|
+
</IntlayerProvider>
|
|
689
|
+
);
|
|
690
|
+
|
|
691
|
+
export default App;
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
#### 工作原理
|
|
695
|
+
|
|
696
|
+
- **检测外部链接**:
|
|
697
|
+
辅助函数 `checkIsExternalLink` 用于判断 URL 是否为外部链接。外部链接保持不变,因为它们不需要本地化。
|
|
698
|
+
- **获取当前语言环境**:
|
|
699
|
+
`useLocale` hook 提供当前的语言环境(例如,`fr` 代表法语)。
|
|
700
|
+
- **本地化 URL**:
|
|
701
|
+
对于内部链接(即非外部链接),使用 `getLocalizedUrl` 自动为 URL 添加当前语言环境前缀。这意味着如果用户处于法语环境,传递 `/about` 作为 `href` 将被转换为 `/fr/about`。
|
|
702
|
+
- **返回链接**:
|
|
703
|
+
该组件返回一个 `<a>` 元素,其 URL 已本地化,确保导航与语言环境一致。
|
|
704
|
+
|
|
705
|
+
</Step>
|
|
438
706
|
|
|
439
|
-
|
|
707
|
+
<Step number={11} title="渲染 Markdown 和 HTML" isOptional={true}>
|
|
440
708
|
|
|
441
|
-
|
|
709
|
+
Intlayer 支持在 Preact 中渲染 Markdown 和 HTML 内容。
|
|
710
|
+
|
|
711
|
+
您可以使用 `.use()` 方法自定义 Markdown 和 HTML 内容的渲染方式。该方法允许您覆盖特定标签的默认渲染。
|
|
712
|
+
|
|
713
|
+
```tsx
|
|
714
|
+
import { useIntlayer } from "preact-intlayer";
|
|
715
|
+
|
|
716
|
+
const { myMarkdownContent, myHtmlContent } = useIntlayer("my-component");
|
|
717
|
+
|
|
718
|
+
// ...
|
|
719
|
+
|
|
720
|
+
return (
|
|
721
|
+
<div>
|
|
722
|
+
{/* 基础渲染 */}
|
|
723
|
+
{myMarkdownContent}
|
|
724
|
+
|
|
725
|
+
{/* Markdown 自定义渲染 */}
|
|
726
|
+
{myMarkdownContent.use({
|
|
727
|
+
h1: (props) => <h1 style={{ color: "red" }} {...props} />,
|
|
728
|
+
})}
|
|
729
|
+
|
|
730
|
+
{/* HTML 基础渲染 */}
|
|
731
|
+
{myHtmlContent}
|
|
732
|
+
|
|
733
|
+
{/* HTML 自定义渲染 */}
|
|
734
|
+
{myHtmlContent.use({
|
|
735
|
+
b: (props) => <strong style={{ color: "blue" }} {...props} />,
|
|
736
|
+
})}
|
|
737
|
+
</div>
|
|
738
|
+
);
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
</Step>
|
|
742
|
+
|
|
743
|
+
<Step number={12} title="提取组件内容" isOptional={true}>
|
|
744
|
+
|
|
745
|
+
如果您有现有的 codebase,转换数千个文件可能很耗时。
|
|
746
|
+
|
|
747
|
+
为了简化此过程,Intlayer 提供了一个 [compiler](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/compiler.md) / [extractor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/cli/extract.md) 来转换您的组件并提取内容。
|
|
748
|
+
|
|
749
|
+
要设置它,您可以在 `intlayer.config.ts` 文件中添加一个 `compiler` 部分:
|
|
442
750
|
|
|
443
751
|
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
444
752
|
import { type IntlayerConfig } from "intlayer";
|
|
445
753
|
|
|
446
754
|
const config: IntlayerConfig = {
|
|
447
|
-
// ...
|
|
755
|
+
// ... 其余配置
|
|
448
756
|
compiler: {
|
|
449
757
|
/**
|
|
450
|
-
*
|
|
758
|
+
* 指示编译器是否应启用。
|
|
451
759
|
*/
|
|
452
760
|
enabled: true,
|
|
453
761
|
|
|
@@ -457,7 +765,11 @@ const config: IntlayerConfig = {
|
|
|
457
765
|
output: ({ fileName, extension }) => `./${fileName}${extension}`,
|
|
458
766
|
|
|
459
767
|
/**
|
|
460
|
-
*
|
|
768
|
+
* 指示转换后是否应保存组件。
|
|
769
|
+
*
|
|
770
|
+
* - 如果为 `true`,编译器将重写磁盘上的组件文件。所以转换将是永久的,编译器将在下一个过程中跳过转换。这样,编译器可以转换应用程序,然后可以被删除。
|
|
771
|
+
*
|
|
772
|
+
* - 如果为 `false`,编译器仅在构建输出中注入 `useIntlayer()` 函数调用,并保持基础 codebase 完整。转换仅在内存中完成。
|
|
461
773
|
*/
|
|
462
774
|
saveComponents: false,
|
|
463
775
|
|
|
@@ -472,9 +784,9 @@ export default config;
|
|
|
472
784
|
```
|
|
473
785
|
|
|
474
786
|
<Tabs>
|
|
475
|
-
<Tab value='
|
|
787
|
+
<Tab value='Extract command'>
|
|
476
788
|
|
|
477
|
-
|
|
789
|
+
运行提取器来转换您的组件并提取内容
|
|
478
790
|
|
|
479
791
|
```bash packageManager="npm"
|
|
480
792
|
npx intlayer extract
|
|
@@ -493,9 +805,9 @@ bun x intlayer extract
|
|
|
493
805
|
```
|
|
494
806
|
|
|
495
807
|
</Tab>
|
|
496
|
-
<Tab value='Babel
|
|
808
|
+
<Tab value='Babel compiler'>
|
|
497
809
|
|
|
498
|
-
>
|
|
810
|
+
> 从 v9 起,`intlayerCompiler` 已包含在 `intlayer` 插件中。所以您不需要手动添加它。
|
|
499
811
|
|
|
500
812
|
更新您的 `vite.config.ts` 以包含 `intlayerCompiler` 插件:
|
|
501
813
|
|
|
@@ -506,7 +818,7 @@ import { intlayer, intlayerCompiler } from "vite-intlayer";
|
|
|
506
818
|
export default defineConfig({
|
|
507
819
|
plugins: [
|
|
508
820
|
intlayer(),
|
|
509
|
-
intlayerCompiler(), //
|
|
821
|
+
intlayerCompiler(), // 添加编译器插件
|
|
510
822
|
],
|
|
511
823
|
});
|
|
512
824
|
```
|
|
@@ -524,7 +836,7 @@ yarn build # 或 yarn dev
|
|
|
524
836
|
```
|
|
525
837
|
|
|
526
838
|
```bash packageManager="bun"
|
|
527
|
-
bun run build #
|
|
839
|
+
bun run build # 或 bun run dev
|
|
528
840
|
```
|
|
529
841
|
|
|
530
842
|
</Tab>
|
|
@@ -533,73 +845,6 @@ bun run build # Or bun run dev
|
|
|
533
845
|
|
|
534
846
|
</Steps>
|
|
535
847
|
|
|
536
|
-
### (可选)第 9 步:切换 HTML 语言和方向属性
|
|
537
|
-
|
|
538
|
-
当您的应用程序支持多种语言时,更新 `<html>` 标签的 `lang` 和 `dir` 属性以匹配当前语言环境至关重要。这样做可以确保:
|
|
539
|
-
|
|
540
|
-
- **无障碍性**:屏幕阅读器和辅助技术依靠正确的 `lang` 属性来准确发音和解释内容。
|
|
541
|
-
- **文本渲染**:`dir`(方向)属性确保文本以正确的顺序呈现(例如,英语从左到右,阿拉伯语或希伯来语从右到左),这对于可读性至关重要。
|
|
542
|
-
- **SEO**:搜索引擎使用 `lang` 属性来确定页面的语言,有助于在搜索结果中提供正确的本地化内容。
|
|
543
|
-
|
|
544
|
-
通过在语言环境更改时动态更新这些属性,您可以确保所有支持语言的用户都能获得一致且无障碍的体验。
|
|
545
|
-
|
|
546
|
-
#### 实现钩子
|
|
547
|
-
|
|
548
|
-
创建一个自定义钩子来管理 HTML 属性。该钩子监听语言环境更改并相应地更新属性:
|
|
549
|
-
|
|
550
|
-
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat={["typescript", "esm"]}
|
|
551
|
-
import { useEffect } from "preact/hooks";
|
|
552
|
-
import { useLocale } from "preact-intlayer";
|
|
553
|
-
import { getHTMLTextDir } from "intlayer";
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* 根据当前语言环境更新 HTML <html> 元素的 `lang` 和 `dir` 属性。
|
|
557
|
-
* - `lang`: 通知浏览器和搜索引擎页面的语言。
|
|
558
|
-
* - `dir`: 确保正确的阅读顺序(例如,英语为 'ltr',阿拉伯语为 'rtl')。
|
|
559
|
-
*
|
|
560
|
-
* 这种动态更新对于正确的文本渲染、无障碍访问和 SEO 至关重要。
|
|
561
|
-
*/
|
|
562
|
-
export const useI18nHTMLAttributes = () => {
|
|
563
|
-
const { locale } = useLocale();
|
|
564
|
-
|
|
565
|
-
useEffect(() => {
|
|
566
|
-
// 将语言属性更新为当前语言环境。
|
|
567
|
-
document.documentElement.lang = locale;
|
|
568
|
-
|
|
569
|
-
// 根据当前语言环境设置文本方向。
|
|
570
|
-
document.documentElement.dir = getHTMLTextDir(locale);
|
|
571
|
-
}, [locale]);
|
|
572
|
-
};
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
#### 在应用程序中使用钩子
|
|
576
|
-
|
|
577
|
-
将钩子集成到您的主组件中,以便在语言环境更改时更新 HTML 属性:
|
|
578
|
-
|
|
579
|
-
```tsx fileName="src/app.tsx" codeFormat={["typescript", "esm"]}
|
|
580
|
-
import type { FunctionalComponent } from "preact";
|
|
581
|
-
import { IntlayerProvider } from "preact-intlayer"; // 如果 AppContent 需要,useIntlayer 已导入
|
|
582
|
-
import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
|
|
583
|
-
import "./app.css";
|
|
584
|
-
// 第 5 步中的 AppContent 定义
|
|
585
|
-
|
|
586
|
-
const AppWithHooks: FunctionalComponent = () => {
|
|
587
|
-
// 应用钩子以根据语言环境更新 <html> 标签的 lang 和 dir 属性。
|
|
588
|
-
useI18nHTMLAttributes();
|
|
589
|
-
|
|
590
|
-
// 假设 AppContent 是您在第 5 步中的主要内容显示组件
|
|
591
|
-
return <AppContent />;
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
const App: FunctionalComponent = () => (
|
|
595
|
-
<IntlayerProvider>
|
|
596
|
-
<AppWithHooks />
|
|
597
|
-
</IntlayerProvider>
|
|
598
|
-
);
|
|
599
|
-
|
|
600
|
-
export default App;
|
|
601
|
-
```
|
|
602
|
-
|
|
603
848
|
### (可选)第 10 步:创建本地化链接组件
|
|
604
849
|
|
|
605
850
|
为了确保您的应用程序导航尊重当前语言环境,您可以创建一个自定义 `Link` 组件。此组件会自动为内部 URL 添加当前语言前缀。
|
|
@@ -654,6 +899,67 @@ export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
|
654
899
|
Link.displayName = "Link";
|
|
655
900
|
```
|
|
656
901
|
|
|
902
|
+
#### Sitemap
|
|
903
|
+
|
|
904
|
+
Intlayer 的 sitemap 生成器遵守你的本地化设置,并包括用于爬虫的常见元数据。
|
|
905
|
+
|
|
906
|
+
> 生成的 sitemap 支持 `xhtml:link` 命名空间(hreflang XML 扩展)。与只生成平面 URL 的基本生成器不同,Intlayer 在每个页面的所有本地化变体之间连接双向链接(例如 `/about`、`/fr/about` 或 `/about?lang=fr`,具体取决于你的路由模式),这有助于搜索引擎关联本地化 URL。
|
|
907
|
+
|
|
908
|
+
#### Robots.txt
|
|
909
|
+
|
|
910
|
+
使用 `getMultilingualUrls` 以便 `Disallow` 条目涵盖敏感路径的每个本地化拼写。
|
|
911
|
+
|
|
912
|
+
#### 1. 在项目根目录添加 `generate-seo.mjs`
|
|
913
|
+
|
|
914
|
+
```javascript fileName="generate-seo.mjs"
|
|
915
|
+
import fs from "fs";
|
|
916
|
+
import path from "path";
|
|
917
|
+
import { fileURLToPath } from "url";
|
|
918
|
+
import { generateSitemap, getMultilingualUrls } from "intlayer";
|
|
919
|
+
|
|
920
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
921
|
+
|
|
922
|
+
// 站点 URL,默认为本地开发环境
|
|
923
|
+
const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(
|
|
924
|
+
/\/$/,
|
|
925
|
+
""
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
// 定义需要生成的路径列表
|
|
929
|
+
const pathList = [
|
|
930
|
+
{ path: "/", changefreq: "daily", priority: 1.0 },
|
|
931
|
+
{ path: "/about", changefreq: "monthly", priority: 0.7 },
|
|
932
|
+
];
|
|
933
|
+
|
|
934
|
+
// 生成 sitemap.xml
|
|
935
|
+
const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });
|
|
936
|
+
fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);
|
|
937
|
+
|
|
938
|
+
// 获取所有多语言 URL
|
|
939
|
+
const getAllMultilingualUrls = (urls) =>
|
|
940
|
+
urls.flatMap((url) => Object.values(getMultilingualUrls(url)));
|
|
941
|
+
|
|
942
|
+
// 定义禁止访问的路径
|
|
943
|
+
const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);
|
|
944
|
+
|
|
945
|
+
// 生成 robots.txt
|
|
946
|
+
const robotsTxt = [
|
|
947
|
+
"User-agent: *",
|
|
948
|
+
"Allow: /",
|
|
949
|
+
...disallowedPaths.map((path) => `Disallow: ${path}`),
|
|
950
|
+
"",
|
|
951
|
+
`Sitemap: ${SITE_URL}/sitemap.xml`,
|
|
952
|
+
].join("\n");
|
|
953
|
+
|
|
954
|
+
fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);
|
|
955
|
+
|
|
956
|
+
console.log("SEO files generated successfully.");
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
必须安装 `intlayer` 以便脚本能够导入它。在生产环境中设置环境变量 `SITE_URL`(例如在 CI 中)。
|
|
960
|
+
|
|
961
|
+
> 对于 Node ESM,建议使用 `generate-seo.mjs`。如果改用 `generate-seo.js`,请确保在 `package.json` 中设置 `"type": "module"`,或以 ESM 模式运行 Node。
|
|
962
|
+
|
|
657
963
|
#### 工作原理
|
|
658
964
|
|
|
659
965
|
- **检测外部链接**:
|