@intlayer/docs 7.3.10 → 7.3.12
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/dist/cjs/generated/docs.entry.cjs +19 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +19 -0
- package/dist/esm/generated/docs.entry.mjs.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/docs/ar/intlayer_with_nuxt.md +305 -421
- package/docs/ar/intlayer_with_react_router_v7.md +33 -4
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +516 -0
- package/docs/ar/intlayer_with_tanstack.md +2 -12
- package/docs/ar/intlayer_with_vite+vue.md +1 -0
- package/docs/de/intlayer_with_nuxt.md +296 -394
- package/docs/de/intlayer_with_react_router_v7.md +33 -4
- package/docs/de/intlayer_with_react_router_v7_fs_routes.md +573 -0
- package/docs/de/intlayer_with_tanstack.md +1 -0
- package/docs/de/intlayer_with_vite+vue.md +1 -0
- package/docs/en/intlayer_with_nuxt.md +242 -321
- package/docs/en/intlayer_with_react_router_v7.md +24 -0
- package/docs/en/intlayer_with_react_router_v7_fs_routes.md +570 -0
- package/docs/en/intlayer_with_tanstack.md +2 -12
- package/docs/en/intlayer_with_vite+vue.md +49 -48
- package/docs/en-GB/intlayer_with_nuxt.md +262 -358
- package/docs/en-GB/intlayer_with_react_router_v7.md +33 -4
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +513 -0
- package/docs/en-GB/intlayer_with_tanstack.md +2 -12
- package/docs/en-GB/intlayer_with_vite+vue.md +1 -0
- package/docs/es/intlayer_with_nuxt.md +284 -375
- package/docs/es/intlayer_with_react_router_v7.md +33 -4
- package/docs/es/intlayer_with_react_router_v7_fs_routes.md +575 -0
- package/docs/es/intlayer_with_tanstack.md +1 -0
- package/docs/es/intlayer_with_vite+vue.md +1 -2
- package/docs/fr/intlayer_with_nuxt.md +288 -387
- package/docs/fr/intlayer_with_react_router_v7.md +34 -5
- package/docs/fr/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/fr/intlayer_with_tanstack.md +1 -0
- package/docs/fr/intlayer_with_vite+vue.md +1 -0
- package/docs/hi/intlayer_with_nuxt.md +318 -434
- package/docs/hi/intlayer_with_react_router_v7.md +33 -4
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +518 -0
- package/docs/hi/intlayer_with_tanstack.md +2 -12
- package/docs/hi/intlayer_with_vite+vue.md +1 -0
- package/docs/id/intlayer_with_nuxt.md +275 -376
- package/docs/id/intlayer_with_react_router_v7.md +29 -4
- package/docs/id/intlayer_with_react_router_v7_fs_routes.md +521 -0
- package/docs/id/intlayer_with_tanstack.md +2 -12
- package/docs/id/intlayer_with_vite+vue.md +1 -0
- package/docs/it/intlayer_with_nuxt.md +312 -408
- package/docs/it/intlayer_with_react_router_v7.md +33 -4
- package/docs/it/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/it/intlayer_with_tanstack.md +1 -0
- package/docs/ja/intlayer_with_nuxt.md +319 -414
- package/docs/ja/intlayer_with_react_router_v7.md +33 -4
- package/docs/ja/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/ja/intlayer_with_tanstack.md +2 -12
- package/docs/ja/intlayer_with_vite+vue.md +1 -0
- package/docs/ko/intlayer_with_nuxt.md +307 -406
- package/docs/ko/intlayer_with_react_router_v7.md +33 -4
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +515 -0
- package/docs/ko/intlayer_with_tanstack.md +2 -12
- package/docs/ko/intlayer_with_vite+vue.md +1 -0
- package/docs/pl/intlayer_with_nuxt.md +282 -457
- package/docs/pl/intlayer_with_react_router_v7.md +32 -5
- package/docs/pl/intlayer_with_react_router_v7_fs_routes.md +615 -0
- package/docs/pl/intlayer_with_tanstack.md +2 -12
- package/docs/pl/intlayer_with_vite+vue.md +1 -0
- package/docs/pt/intlayer_with_nuxt.md +288 -403
- package/docs/pt/intlayer_with_react_router_v7.md +28 -0
- package/docs/pt/intlayer_with_tanstack.md +1 -0
- package/docs/ru/intlayer_with_nuxt.md +300 -410
- package/docs/ru/intlayer_with_react_router_v7.md +33 -4
- package/docs/ru/intlayer_with_react_router_v7_fs_routes.md +574 -0
- package/docs/ru/intlayer_with_tanstack.md +1 -0
- package/docs/ru/intlayer_with_vite+vue.md +1 -0
- package/docs/tr/intlayer_with_nuxt.md +327 -392
- package/docs/tr/intlayer_with_react_router_v7.md +33 -4
- package/docs/tr/intlayer_with_react_router_v7_fs_routes.md +572 -0
- package/docs/tr/intlayer_with_tanstack.md +2 -12
- package/docs/tr/intlayer_with_vite+vue.md +1 -0
- package/docs/vi/intlayer_with_nuxt.md +282 -399
- package/docs/vi/intlayer_with_react_router_v7.md +29 -4
- package/docs/vi/intlayer_with_react_router_v7_fs_routes.md +523 -0
- package/docs/vi/intlayer_with_tanstack.md +2 -12
- package/docs/vi/intlayer_with_vite+vue.md +1 -0
- package/docs/zh/intlayer_with_nuxt.md +311 -444
- package/docs/zh/intlayer_with_react_router_v7.md +33 -4
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +516 -0
- package/docs/zh/intlayer_with_tanstack.md +2 -12
- package/docs/zh/intlayer_with_vite+vue.md +1 -0
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +19 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-06-18
|
|
3
|
-
updatedAt: 2025-
|
|
4
|
-
title: 如何翻译您的Nuxt
|
|
3
|
+
updatedAt: 2025-12-07
|
|
4
|
+
title: 如何翻译您的 Nuxt 和 Vue 应用 – 2025 年 i18n 指南
|
|
5
5
|
description: 了解如何使您的 Nuxt 和 Vue 网站支持多语言。按照文档进行国际化(i18n)和翻译。
|
|
6
6
|
keywords:
|
|
7
7
|
- 国际化
|
|
@@ -14,16 +14,22 @@ slugs:
|
|
|
14
14
|
- doc
|
|
15
15
|
- environment
|
|
16
16
|
- nuxt-and-vue
|
|
17
|
-
applicationTemplate: https://github.com/aymericzip/intlayer-nuxt-template
|
|
17
|
+
applicationTemplate: https://github.com/aymericzip/intlayer-nuxt-4-template
|
|
18
|
+
youtubeVideo: https://www.youtube.com/watch?v=IE3XWkZ6a5U
|
|
18
19
|
history:
|
|
20
|
+
- version: 7.3.11
|
|
21
|
+
date: 2025-12-07
|
|
22
|
+
changes: 更新 LocaleSwitcher、SEO、元数据
|
|
19
23
|
- version: 5.5.10
|
|
20
24
|
date: 2025-06-29
|
|
21
|
-
changes:
|
|
25
|
+
changes: 初始化历史记录
|
|
22
26
|
---
|
|
23
27
|
|
|
24
|
-
# 使用Intlayer翻译您的Nuxt
|
|
28
|
+
# 使用 Intlayer 翻译您的 Nuxt 和 Vue 网站 | 国际化 (i18n)
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
## 目录
|
|
31
|
+
|
|
32
|
+
<TOC/>
|
|
27
33
|
|
|
28
34
|
## 什么是 Intlayer?
|
|
29
35
|
|
|
@@ -33,16 +39,45 @@ history:
|
|
|
33
39
|
|
|
34
40
|
- **通过组件级声明式字典轻松管理翻译**。
|
|
35
41
|
- **动态本地化元数据、路由和内容**。
|
|
36
|
-
- **确保 TypeScript
|
|
42
|
+
- **确保 TypeScript 支持**,通过自动生成类型,提升自动补全和错误检测能力。
|
|
37
43
|
- **享受高级功能**,如动态语言环境检测和切换。
|
|
38
44
|
|
|
39
45
|
---
|
|
40
46
|
|
|
41
47
|
## 在 Nuxt 应用中设置 Intlayer 的分步指南
|
|
42
48
|
|
|
49
|
+
<iframe
|
|
50
|
+
src="https://stackblitz.com/github/aymericzip/intlayer-nuxt-4-template?embed=1&ctl=1&file=intlayer.config.ts"
|
|
51
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
52
|
+
title="演示 CodeSandbox - 如何使用 Intlayer 实现应用国际化"
|
|
53
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
54
|
+
loading="lazy"
|
|
55
|
+
/>
|
|
56
|
+
|
|
43
57
|
### 第一步:安装依赖
|
|
44
58
|
|
|
45
|
-
|
|
59
|
+
<Tab defaultTab="video">
|
|
60
|
+
<TabItem label="视频" value="video">
|
|
61
|
+
|
|
62
|
+
<iframe title="如何使用 Intlayer 翻译你的 Nuxt 和 Vue 应用?探索 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/IE3XWkZ6a5U?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
63
|
+
|
|
64
|
+
</TabItem>
|
|
65
|
+
<TabItem label="代码" value="code">
|
|
66
|
+
|
|
67
|
+
<iframe
|
|
68
|
+
src="https://stackblitz.com/github/aymericzip/intlayer-nuxt-4-template?embed=1&ctl=1&file=intlayer.config.ts"
|
|
69
|
+
className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
|
|
70
|
+
title="演示 CodeSandbox - 如何使用 Intlayer 实现应用国际化"
|
|
71
|
+
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
|
72
|
+
loading="lazy"
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
</TabItem>
|
|
76
|
+
</Tab>
|
|
77
|
+
|
|
78
|
+
查看 GitHub 上的[应用模板](https://github.com/aymericzip/intlayer-nuxt-4-template)。
|
|
79
|
+
|
|
80
|
+
使用 npm 安装必要的包:
|
|
46
81
|
|
|
47
82
|
```bash packageManager="npm"
|
|
48
83
|
npm install intlayer vue-intlayer
|
|
@@ -61,15 +96,15 @@ yarn add --save-dev nuxt-intlayer
|
|
|
61
96
|
|
|
62
97
|
- **intlayer**
|
|
63
98
|
|
|
64
|
-
核心包,提供国际化工具,用于配置管理、翻译、[内容声明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/
|
|
99
|
+
核心包,提供国际化工具,用于配置管理、翻译、[内容声明](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)。
|
|
65
100
|
|
|
66
101
|
- **vue-intlayer**
|
|
67
|
-
将 Intlayer 集成到 Vue
|
|
102
|
+
将 Intlayer 集成到 Vue 应用中的包。它提供了 Vue 组件的组合式函数。
|
|
68
103
|
|
|
69
104
|
- **nuxt-intlayer**
|
|
70
105
|
集成 Intlayer 与 Nuxt 应用的 Nuxt 模块。它提供自动设置、用于语言环境检测的中间件、Cookie 管理和 URL 重定向。
|
|
71
106
|
|
|
72
|
-
### 第
|
|
107
|
+
### 第2步:配置您的项目
|
|
73
108
|
|
|
74
109
|
创建一个配置文件来配置您应用的语言:
|
|
75
110
|
|
|
@@ -86,9 +121,6 @@ const config: IntlayerConfig = {
|
|
|
86
121
|
],
|
|
87
122
|
defaultLocale: Locales.ENGLISH,
|
|
88
123
|
},
|
|
89
|
-
content: {
|
|
90
|
-
contentDir: ["."], // 因为默认情况下 Intlayer 会监视来自 `./src` 目录的内容声明文件
|
|
91
|
-
},
|
|
92
124
|
};
|
|
93
125
|
|
|
94
126
|
export default config;
|
|
@@ -98,19 +130,15 @@ export default config;
|
|
|
98
130
|
import { Locales } from "intlayer";
|
|
99
131
|
|
|
100
132
|
/** @type {import('intlayer').IntlayerConfig} */
|
|
101
|
-
// 配置对象定义
|
|
102
133
|
const config = {
|
|
103
134
|
internationalization: {
|
|
104
135
|
locales: [
|
|
105
|
-
Locales.ENGLISH,
|
|
106
|
-
Locales.FRENCH,
|
|
107
|
-
Locales.SPANISH,
|
|
136
|
+
Locales.ENGLISH,
|
|
137
|
+
Locales.FRENCH,
|
|
138
|
+
Locales.SPANISH,
|
|
108
139
|
// 你的其他语言
|
|
109
140
|
],
|
|
110
|
-
defaultLocale: Locales.ENGLISH,
|
|
111
|
-
},
|
|
112
|
-
content: {
|
|
113
|
-
contentDir: ["."], // 内容目录设置为当前目录
|
|
141
|
+
defaultLocale: Locales.ENGLISH,
|
|
114
142
|
},
|
|
115
143
|
};
|
|
116
144
|
|
|
@@ -121,28 +149,24 @@ export default config;
|
|
|
121
149
|
const { Locales } = require("intlayer");
|
|
122
150
|
|
|
123
151
|
/** @type {import('intlayer').IntlayerConfig} */
|
|
124
|
-
// 配置对象定义
|
|
125
152
|
const config = {
|
|
126
153
|
internationalization: {
|
|
127
154
|
locales: [
|
|
128
|
-
Locales.ENGLISH,
|
|
129
|
-
Locales.FRENCH,
|
|
130
|
-
Locales.SPANISH,
|
|
155
|
+
Locales.ENGLISH,
|
|
156
|
+
Locales.FRENCH,
|
|
157
|
+
Locales.SPANISH,
|
|
131
158
|
// 你的其他语言
|
|
132
159
|
],
|
|
133
|
-
defaultLocale: Locales.ENGLISH,
|
|
134
|
-
},
|
|
135
|
-
content: {
|
|
136
|
-
contentDir: ["."],
|
|
160
|
+
defaultLocale: Locales.ENGLISH,
|
|
137
161
|
},
|
|
138
162
|
};
|
|
139
163
|
|
|
140
164
|
module.exports = config;
|
|
141
165
|
```
|
|
142
166
|
|
|
143
|
-
> 通过此配置文件,您可以设置本地化的 URL、中间件重定向、cookie
|
|
167
|
+
> 通过此配置文件,您可以设置本地化的 URL、中间件重定向、cookie 名称、内容声明的位置和扩展名,禁用控制台中的 Intlayer 日志等。有关可用参数的完整列表,请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
|
|
144
168
|
|
|
145
|
-
###
|
|
169
|
+
### 第三步:在您的 Nuxt 配置中集成 Intlayer
|
|
146
170
|
|
|
147
171
|
将 intlayer 模块添加到您的 Nuxt 配置中:
|
|
148
172
|
|
|
@@ -161,262 +185,40 @@ export default defineNuxtConfig({
|
|
|
161
185
|
|
|
162
186
|
创建并管理您的内容声明以存储翻译:
|
|
163
187
|
|
|
164
|
-
```tsx fileName="
|
|
165
|
-
import {
|
|
188
|
+
```tsx fileName="content/home-page.content.ts" contentDeclarationFormat="typescript"
|
|
189
|
+
import { type Dictionary, t } from "intlayer";
|
|
166
190
|
|
|
167
|
-
const
|
|
168
|
-
key: "
|
|
191
|
+
const content = {
|
|
192
|
+
key: "home-page",
|
|
169
193
|
content: {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
175
|
-
}),
|
|
176
|
-
checkOut: t({ en: "Check out ", fr: "Vérifiez ", es: "Compruebe " }),
|
|
177
|
-
nuxtIntlayer: t({
|
|
178
|
-
en: "Nuxt Intlayer documentation",
|
|
179
|
-
fr: "Documentation de Nuxt Intlayer",
|
|
180
|
-
es: "Documentación de Nuxt Intlayer",
|
|
181
|
-
}),
|
|
182
|
-
learnMore: t({
|
|
183
|
-
en: "Learn more about Nuxt in the ",
|
|
184
|
-
fr: "En savoir plus sur Nuxt dans la ",
|
|
185
|
-
es: "Aprenda más sobre Nuxt en la ",
|
|
186
|
-
}),
|
|
187
|
-
nuxtDocs: t({
|
|
188
|
-
en: "Nuxt Documentation",
|
|
189
|
-
fr: "Documentation Nuxt",
|
|
190
|
-
es: "Documentación de Nuxt",
|
|
191
|
-
}),
|
|
192
|
-
readTheDocs: t({
|
|
193
|
-
en: "Click on the Nuxt logo to learn more",
|
|
194
|
-
fr: "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
195
|
-
es: "Haga clic en el logotipo de Nuxt para obtener más información",
|
|
196
|
-
}),
|
|
197
|
-
},
|
|
198
|
-
} satisfies Dictionary;
|
|
199
|
-
|
|
200
|
-
export default helloWorldContent;
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
```javascript fileName="components/helloWorld.content.mjs" contentDeclarationFormat="esm"
|
|
204
|
-
import { t } from "intlayer";
|
|
205
|
-
|
|
206
|
-
/** @type {import('intlayer').Dictionary} */
|
|
207
|
-
const helloWorldContent = {
|
|
208
|
-
key: "helloworld",
|
|
209
|
-
content: {
|
|
210
|
-
count: t({ zh: "计数是 ", en: "count is ", fr: "le compte est ", es: "el recuento es " }),
|
|
211
|
-
edit: t({
|
|
212
|
-
zh: "编辑 <code>components/HelloWorld.vue</code> 并保存以测试 HMR",
|
|
213
|
-
en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
|
|
214
|
-
fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
|
|
215
|
-
es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
216
|
-
}),
|
|
217
|
-
checkOut: t({ en: "Check out ", fr: "Vérifiez ", es: "Compruebe " }),
|
|
218
|
-
nuxtIntlayer: t({
|
|
219
|
-
en: "Nuxt Intlayer documentation",
|
|
220
|
-
fr: "Documentation de Nuxt Intlayer",
|
|
221
|
-
es: "Documentación de Nuxt Intlayer",
|
|
222
|
-
}),
|
|
223
|
-
learnMore: t({
|
|
224
|
-
en: "Learn more about Nuxt in the ",
|
|
225
|
-
fr: "En savoir plus sur Nuxt dans la ",
|
|
226
|
-
es: "Aprenda más sobre Nuxt en la ",
|
|
227
|
-
}),
|
|
228
|
-
nuxtDocs: t({
|
|
229
|
-
en: "Nuxt Documentation",
|
|
230
|
-
fr: "Documentation Nuxt",
|
|
231
|
-
es: "Documentación de Nuxt",
|
|
194
|
+
title: t({
|
|
195
|
+
en: "Hello world",
|
|
196
|
+
fr: "Bonjour le monde",
|
|
197
|
+
es: "Hola mundo",
|
|
232
198
|
}),
|
|
233
|
-
|
|
234
|
-
en: "
|
|
235
|
-
fr: "
|
|
236
|
-
es: "
|
|
199
|
+
metaTitle: t({
|
|
200
|
+
en: "Welcome | My Application",
|
|
201
|
+
fr: "Bienvenue | Mon Application",
|
|
202
|
+
es: "Bienvenido | Mi Aplicación",
|
|
237
203
|
}),
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
fr: "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
243
|
-
es: "Haga clic en el logotipo de Nuxt para obtener más información",
|
|
204
|
+
metaDescription: t({
|
|
205
|
+
en: "Discover your multilingual Nuxt app homepage powered by Intlayer.",
|
|
206
|
+
fr: "Découvrez la page d'accueil multilingue de votre application Nuxt propulsée par Intlayer.",
|
|
207
|
+
es: "Descubre la página de inicio multilingüe de tu aplicación Nuxt impulsada por Intlayer.",
|
|
244
208
|
}),
|
|
245
209
|
},
|
|
246
210
|
} satisfies Dictionary;
|
|
247
211
|
|
|
248
|
-
export default
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
```javascript fileName="components/helloWorld.content.mjs" contentDeclarationFormat="esm"
|
|
252
|
-
import { t } from "intlayer";
|
|
253
|
-
|
|
254
|
-
/** @type {import('intlayer').Dictionary} */
|
|
255
|
-
const helloWorldContent = {
|
|
256
|
-
key: "helloworld",
|
|
257
|
-
content: {
|
|
258
|
-
count: t({ en: "count is ", fr: "le compte est ", es: "el recuento es " }),
|
|
259
|
-
edit: t({
|
|
260
|
-
en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
|
|
261
|
-
fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
|
|
262
|
-
es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
263
|
-
}),
|
|
264
|
-
checkOut: t({
|
|
265
|
-
en: "Check out ",
|
|
266
|
-
zh: "查看 ",
|
|
267
|
-
fr: "Vérifiez ",
|
|
268
|
-
es: "Compruebe ",
|
|
269
|
-
}),
|
|
270
|
-
nuxtIntlayer: t({
|
|
271
|
-
en: "Nuxt Intlayer documentation",
|
|
272
|
-
zh: "Nuxt Intlayer 文档",
|
|
273
|
-
fr: "Documentation de Nuxt Intlayer",
|
|
274
|
-
es: "Documentación de Nuxt Intlayer",
|
|
275
|
-
}),
|
|
276
|
-
learnMore: t({
|
|
277
|
-
en: "Learn more about Nuxt in the ",
|
|
278
|
-
zh: "在此了解更多关于 Nuxt 的信息 ",
|
|
279
|
-
fr: "En savoir plus sur Nuxt dans la ",
|
|
280
|
-
es: "Aprenda más sobre Nuxt en la ",
|
|
281
|
-
}),
|
|
282
|
-
nuxtDocs: t({
|
|
283
|
-
en: "Nuxt Documentation",
|
|
284
|
-
zh: "Nuxt 文档",
|
|
285
|
-
fr: "Documentation Nuxt",
|
|
286
|
-
es: "Documentación de Nuxt",
|
|
287
|
-
}),
|
|
288
|
-
readTheDocs: t({
|
|
289
|
-
en: "Click on the Nuxt logo to learn more",
|
|
290
|
-
zh: "点击 Nuxt 标志了解更多",
|
|
291
|
-
fr: "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
292
|
-
es: "Haga clic en el logotipo de Nuxt para obtener más información",
|
|
293
|
-
}),
|
|
294
|
-
},
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
export default helloWorldContent;
|
|
212
|
+
export default content;
|
|
298
213
|
```
|
|
299
214
|
|
|
300
|
-
|
|
301
|
-
const { t } = require("intlayer");
|
|
215
|
+
> 您的内容声明可以定义在应用程序中的任何位置,只要它们包含在 `contentDir` 目录中(默认是 `./src`),并且匹配内容声明文件扩展名(默认是 `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`)。
|
|
302
216
|
|
|
303
|
-
|
|
304
|
-
const helloWorldContent = {
|
|
305
|
-
key: "helloworld",
|
|
306
|
-
content: {
|
|
307
|
-
count: t({
|
|
308
|
-
zh: "计数是 ",
|
|
309
|
-
en: "count is ",
|
|
310
|
-
fr: "le compte est ",
|
|
311
|
-
es: "el recuento es ",
|
|
312
|
-
}),
|
|
313
|
-
edit: t({
|
|
314
|
-
zh: "编辑 <code>components/HelloWorld.vue</code> 并保存以测试 HMR",
|
|
315
|
-
en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
|
|
316
|
-
fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
|
|
317
|
-
es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
318
|
-
}),
|
|
319
|
-
checkOut: t({
|
|
320
|
-
zh: "查看 ",
|
|
321
|
-
en: "Check out ",
|
|
322
|
-
fr: "Vérifiez ",
|
|
323
|
-
es: "Compruebe ",
|
|
324
|
-
}),
|
|
325
|
-
nuxtIntlayer: t({
|
|
326
|
-
zh: "Nuxt Intlayer 文档",
|
|
327
|
-
en: "Nuxt Intlayer documentation",
|
|
328
|
-
fr: "Documentation de Nuxt Intlayer",
|
|
329
|
-
es: "Nuxt Intlayer 文档",
|
|
330
|
-
}),
|
|
331
|
-
learnMore: t({
|
|
332
|
-
en: "了解更多关于 Nuxt 的信息,请访问 ",
|
|
333
|
-
fr: "En savoir plus sur Nuxt dans la ",
|
|
334
|
-
es: "Aprenda más sobre Nuxt en la ",
|
|
335
|
-
}),
|
|
336
|
-
nuxtDocs: t({
|
|
337
|
-
en: "Nuxt 文档",
|
|
338
|
-
fr: "Documentation Nuxt",
|
|
339
|
-
es: "Documentación de Nuxt",
|
|
340
|
-
}),
|
|
341
|
-
readTheDocs: t({
|
|
342
|
-
en: "点击 Nuxt 标志了解更多",
|
|
343
|
-
fr: "Cliquez sur le logo Nuxt pour en savoir plus",
|
|
344
|
-
es: "Haga clic en el logotipo de Nuxt para obtener más información",
|
|
345
|
-
}),
|
|
346
|
-
},
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
module.exports = helloWorldContent;
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
```json fileName="components/helloWorld.content.json" contentDeclarationFormat="json"
|
|
353
|
-
{
|
|
354
|
-
"$schema": "https://intlayer.org/schema.json",
|
|
355
|
-
"key": "helloworld",
|
|
356
|
-
"content": {
|
|
357
|
-
"count": {
|
|
358
|
-
"nodeType": "translation",
|
|
359
|
-
"translation": {
|
|
360
|
-
"en": "count is ",
|
|
361
|
-
"fr": "le compte est ",
|
|
362
|
-
"es": "el recuento es ",
|
|
363
|
-
"zh": "计数是 "
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
"edit": {
|
|
367
|
-
"nodeType": "translation",
|
|
368
|
-
"translation": {
|
|
369
|
-
"en": "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
|
|
370
|
-
"fr": "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
|
|
371
|
-
"es": "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
|
|
372
|
-
"zh": "编辑 <code>components/HelloWorld.vue</code> 并保存以测试 HMR"
|
|
373
|
-
}
|
|
374
|
-
},
|
|
375
|
-
"checkOut": {
|
|
376
|
-
"nodeType": "translation",
|
|
377
|
-
"translation": {
|
|
378
|
-
"en": "Check out ",
|
|
379
|
-
"fr": "Vérifiez ",
|
|
380
|
-
"es": "Compruebe ",
|
|
381
|
-
"zh": "查看 "
|
|
382
|
-
}
|
|
383
|
-
},
|
|
384
|
-
"nuxtIntlayer": {
|
|
385
|
-
"nodeType": "translation",
|
|
386
|
-
"translation": {
|
|
387
|
-
"zh": "Nuxt Intlayer 文档"
|
|
388
|
-
}
|
|
389
|
-
},
|
|
390
|
-
"learnMore": {
|
|
391
|
-
"nodeType": "translation",
|
|
392
|
-
"translation": {
|
|
393
|
-
"zh": "在这里了解更多关于 Nuxt 的信息"
|
|
394
|
-
}
|
|
395
|
-
},
|
|
396
|
-
"nuxtDocs": {
|
|
397
|
-
"nodeType": "translation",
|
|
398
|
-
"translation": {
|
|
399
|
-
"zh": "Nuxt 文档"
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
"readTheDocs": {
|
|
403
|
-
"nodeType": "translation",
|
|
404
|
-
"translation": {
|
|
405
|
-
"zh": "点击 Nuxt 标志了解更多"
|
|
406
|
-
"es": "Haga clic en el logotipo de Nuxt para obtener más información"
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
> 您的内容声明可以定义在应用程序的任何位置,只要它们包含在 `contentDir` 目录中(默认是 `./src`),并且匹配内容声明文件的扩展名(默认是 `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`)。
|
|
414
|
-
|
|
415
|
-
> 更多详情,请参阅 [内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)。
|
|
217
|
+
> 更多详情,请参阅[内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/content_file.md)。
|
|
416
218
|
|
|
417
219
|
### 第5步:在代码中使用 Intlayer
|
|
418
220
|
|
|
419
|
-
在整个 Nuxt
|
|
221
|
+
在整个 Nuxt 应用中使用 `useIntlayer` 组合式函数访问您的内容字典:
|
|
420
222
|
|
|
421
223
|
```vue fileName="components/HelloWorld.vue"
|
|
422
224
|
<script setup lang="ts">
|
|
@@ -424,7 +226,7 @@ import { ref } from "vue";
|
|
|
424
226
|
import { useIntlayer } from "vue-intlayer";
|
|
425
227
|
|
|
426
228
|
defineProps({
|
|
427
|
-
msg: String,
|
|
229
|
+
msg: String, // 消息属性
|
|
428
230
|
});
|
|
429
231
|
|
|
430
232
|
const {
|
|
@@ -435,8 +237,8 @@ const {
|
|
|
435
237
|
learnMore,
|
|
436
238
|
nuxtDocs,
|
|
437
239
|
readTheDocs,
|
|
438
|
-
} = useIntlayer("helloworld");
|
|
439
|
-
const countRef = ref(0);
|
|
240
|
+
} = useIntlayer("helloworld"); // 使用名为 "helloworld" 的内容字典
|
|
241
|
+
const countRef = ref(0); // 计数引用
|
|
440
242
|
</script>
|
|
441
243
|
|
|
442
244
|
<template>
|
|
@@ -465,12 +267,12 @@ const countRef = ref(0);
|
|
|
465
267
|
</template>
|
|
466
268
|
```
|
|
467
269
|
|
|
468
|
-
####
|
|
270
|
+
#### 访问 Intlayer 中的内容
|
|
469
271
|
|
|
470
272
|
Intlayer 提供了多种 API 来访问您的内容:
|
|
471
273
|
|
|
472
274
|
- **基于组件的语法**(推荐):
|
|
473
|
-
使用 `<myContent />` 或 `<Component :is="myContent" />` 语法将内容渲染为 Intlayer 节点。这与[可视化编辑器](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_visual_editor.md)和[
|
|
275
|
+
使用 `<myContent />` 或 `<Component :is="myContent" />` 语法将内容渲染为 Intlayer 节点。这与[可视化编辑器](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)无缝集成。
|
|
474
276
|
|
|
475
277
|
- **基于字符串的语法**:
|
|
476
278
|
使用 `{{ myContent }}` 将内容渲染为纯文本,不支持可视化编辑器。
|
|
@@ -479,72 +281,62 @@ Intlayer 提供了多种 API 来访问您的内容:
|
|
|
479
281
|
使用 `<div v-html="myContent" />` 将内容渲染为原始 HTML,不支持可视化编辑器。
|
|
480
282
|
|
|
481
283
|
- **解构语法**:
|
|
482
|
-
`useIntlayer`
|
|
483
|
-
- 使用 `const content = useIntlayer("myContent");`
|
|
484
|
-
- 或者使用 `const { myContent } = useIntlayer("myContent");`
|
|
284
|
+
`useIntlayer` 组合函数返回一个包含内容的 Proxy。该 Proxy 可以被解构以访问内容,同时保持响应性。
|
|
285
|
+
- 使用 `const content = useIntlayer("myContent");` 以及 `{{ content.myContent }}` / `<content.myContent />`。
|
|
286
|
+
- 或者使用 `const { myContent } = useIntlayer("myContent");` 以及 `{{ myContent}}` / `<myContent/>` 来解构内容。
|
|
485
287
|
|
|
486
|
-
### (可选)步骤
|
|
288
|
+
### (可选)步骤6:更改内容语言
|
|
487
289
|
|
|
488
|
-
要更改内容的语言,可以使用 `useLocale`
|
|
290
|
+
要更改内容的语言,可以使用 `useLocale` 组合函数提供的 `setLocale` 函数。该函数允许您设置应用程序的语言环境并相应地更新内容。
|
|
489
291
|
|
|
490
|
-
|
|
292
|
+
创建一个组件,使用 `NuxtLink` 在语言之间切换。**使用链接而非按钮进行语言切换是 SEO 和页面可发现性的最佳实践**,因为这允许搜索引擎抓取并索引页面的所有本地化版本:
|
|
491
293
|
|
|
492
294
|
```vue fileName="components/LocaleSwitcher.vue"
|
|
493
|
-
<template>
|
|
494
|
-
<div class="locale-switcher">
|
|
495
|
-
<select v-model="selectedLocale" @change="changeLocale">
|
|
496
|
-
<option v-for="loc in availableLocales" :key="loc" :value="loc">
|
|
497
|
-
{{ getLocaleName(loc) }}
|
|
498
|
-
</option>
|
|
499
|
-
</select>
|
|
500
|
-
</div>
|
|
501
|
-
</template>
|
|
502
|
-
|
|
503
295
|
<script setup lang="ts">
|
|
504
|
-
import {
|
|
505
|
-
import { getLocaleName } from "intlayer";
|
|
296
|
+
import { getLocaleName, getLocalizedUrl } from "intlayer";
|
|
506
297
|
import { useLocale } from "vue-intlayer";
|
|
507
298
|
|
|
508
|
-
//
|
|
299
|
+
// Nuxt 自动导入 useRoute
|
|
300
|
+
const route = useRoute();
|
|
509
301
|
const { locale, availableLocales, setLocale } = useLocale();
|
|
510
|
-
|
|
511
|
-
// 使用 ref 跟踪选中的语言
|
|
512
|
-
const selectedLocale = ref(locale.value);
|
|
513
|
-
|
|
514
|
-
// 当选择变化时更新语言
|
|
515
|
-
const changeLocale = () => setLocale(selectedLocale.value);
|
|
516
|
-
|
|
517
|
-
// 保持 selectedLocale 与全局语言同步
|
|
518
|
-
watch(
|
|
519
|
-
() => locale.value,
|
|
520
|
-
(newLocale) => {
|
|
521
|
-
selectedLocale.value = newLocale;
|
|
522
|
-
}
|
|
523
|
-
);
|
|
524
302
|
</script>
|
|
303
|
+
|
|
304
|
+
<template>
|
|
305
|
+
<nav class="locale-switcher">
|
|
306
|
+
<NuxtLink
|
|
307
|
+
v-for="localeEl in availableLocales"
|
|
308
|
+
:key="localeEl"
|
|
309
|
+
:to="getLocalizedUrl(route.fullPath, localeEl)"
|
|
310
|
+
class="locale-link"
|
|
311
|
+
:class="{ 'active-locale': localeEl === locale }"
|
|
312
|
+
@click="setLocale(localeEl)"
|
|
313
|
+
>
|
|
314
|
+
{{ getLocaleName(localeEl) }}
|
|
315
|
+
</NuxtLink>
|
|
316
|
+
</nav>
|
|
525
317
|
</template>
|
|
318
|
+
```
|
|
526
319
|
|
|
527
|
-
|
|
528
|
-
.locale-switcher {
|
|
529
|
-
margin: 1rem 0;
|
|
530
|
-
}
|
|
320
|
+
> 使用带有正确 `href` 属性(通过 `getLocalizedUrl`)的 `NuxtLink` 确保搜索引擎能够发现您页面的所有语言版本。这比仅使用 JavaScript 的语言切换更优,因为搜索引擎爬虫可能无法跟踪后者。
|
|
531
321
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
322
|
+
然后,设置您的 `app.vue` 以使用布局:
|
|
323
|
+
|
|
324
|
+
```vue fileName="app.vue"
|
|
325
|
+
<template>
|
|
326
|
+
<NuxtLayout>
|
|
327
|
+
<NuxtPage />
|
|
328
|
+
</NuxtLayout>
|
|
329
|
+
</template>
|
|
538
330
|
```
|
|
539
331
|
|
|
540
|
-
|
|
332
|
+
### (可选)步骤 6b:创建带导航的布局
|
|
541
333
|
|
|
542
|
-
|
|
334
|
+
Nuxt 布局允许您为页面定义一个通用结构。创建一个包含语言切换器和导航的默认布局:
|
|
335
|
+
|
|
336
|
+
```vue fileName="layouts/default.vue"
|
|
543
337
|
<script setup lang="ts">
|
|
544
|
-
import
|
|
338
|
+
import Links from "~/components/Links.vue";
|
|
545
339
|
import LocaleSwitcher from "~/components/LocaleSwitcher.vue";
|
|
546
|
-
|
|
547
|
-
const content = useIntlayer("app"); // 创建相关的 intlayer 声明文件
|
|
548
340
|
</script>
|
|
549
341
|
|
|
550
342
|
<template>
|
|
@@ -553,15 +345,20 @@ const content = useIntlayer("app"); // 创建相关的 intlayer 声明文件
|
|
|
553
345
|
<LocaleSwitcher />
|
|
554
346
|
</header>
|
|
555
347
|
<main>
|
|
556
|
-
<
|
|
348
|
+
<slot />
|
|
557
349
|
</main>
|
|
350
|
+
|
|
351
|
+
<Links href="/">首页</Links>
|
|
352
|
+
<Links href="/about">关于</Links>
|
|
558
353
|
</div>
|
|
559
354
|
</template>
|
|
560
355
|
```
|
|
561
356
|
|
|
562
|
-
|
|
357
|
+
`Links` 组件(如下所示)确保内部导航链接会自动本地化。
|
|
563
358
|
|
|
564
|
-
|
|
359
|
+
### (可选)步骤 7:为您的应用添加本地化路由
|
|
360
|
+
|
|
361
|
+
当使用 `nuxt-intlayer` 模块时,Nuxt 会自动处理本地化路由。它会根据您的页面目录结构自动为每种语言创建路由。
|
|
565
362
|
|
|
566
363
|
示例:
|
|
567
364
|
|
|
@@ -573,213 +370,285 @@ pages/
|
|
|
573
370
|
└── index.vue → /contact, /fr/contact, /es/contact
|
|
574
371
|
```
|
|
575
372
|
|
|
576
|
-
要创建本地化页面,只需在 `pages/`
|
|
373
|
+
要创建本地化页面,只需在 `pages/` 目录中创建您的 Vue 文件。以下是两个示例页面:
|
|
374
|
+
|
|
375
|
+
**主页 (`pages/index.vue`):**
|
|
376
|
+
|
|
377
|
+
```vue fileName="pages/index.vue"
|
|
378
|
+
<script setup lang="ts">
|
|
379
|
+
import { useIntlayer } from "vue-intlayer";
|
|
380
|
+
|
|
381
|
+
const content = useIntlayer("home-page");
|
|
382
|
+
|
|
383
|
+
useHead({
|
|
384
|
+
title: content.metaTitle.value,
|
|
385
|
+
meta: [
|
|
386
|
+
{
|
|
387
|
+
name: "description",
|
|
388
|
+
content: content.metaDescription.value,
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
});
|
|
392
|
+
</script>
|
|
393
|
+
|
|
394
|
+
<template>
|
|
395
|
+
<h1><content.title /></h1>
|
|
396
|
+
</template>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**关于页面 (`pages/about.vue`):**
|
|
577
400
|
|
|
578
401
|
```vue fileName="pages/about.vue"
|
|
579
402
|
<script setup lang="ts">
|
|
580
403
|
import { useIntlayer } from "vue-intlayer";
|
|
581
404
|
|
|
582
|
-
const content = useIntlayer("about");
|
|
405
|
+
const content = useIntlayer("about-page");
|
|
406
|
+
|
|
407
|
+
useHead({
|
|
408
|
+
title: content.metaTitle.raw, // 使用 .raw 访问原始字符串
|
|
409
|
+
meta: [
|
|
410
|
+
{
|
|
411
|
+
name: "description",
|
|
412
|
+
content: content.metaDescription.raw, // 使用 .raw 访问原始字符串
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
});
|
|
583
416
|
</script>
|
|
584
417
|
|
|
585
418
|
<template>
|
|
586
|
-
<
|
|
587
|
-
<h1>{{ content.title }}</h1>
|
|
588
|
-
<p>{{ content.description }}</p>
|
|
589
|
-
</div>
|
|
419
|
+
<h1><content.title /></h1>
|
|
590
420
|
</template>
|
|
591
421
|
```
|
|
592
422
|
|
|
423
|
+
> 注意:`useHead` 在 Nuxt 中是自动导入的。你可以根据需要使用 `.value`(响应式)或 `.raw`(原始字符串)来访问内容值。
|
|
424
|
+
|
|
593
425
|
`nuxt-intlayer` 模块将自动:
|
|
594
426
|
|
|
595
427
|
- 检测用户的首选语言环境
|
|
596
|
-
- 通过 URL
|
|
597
|
-
-
|
|
598
|
-
-
|
|
428
|
+
- 通过 URL 处理语言切换
|
|
429
|
+
- 设置适当的 `<html lang="">` 属性
|
|
430
|
+
- 管理语言环境 Cookie
|
|
599
431
|
- 将用户重定向到相应的本地化 URL
|
|
600
432
|
|
|
601
433
|
### (可选)步骤 8:创建本地化链接组件
|
|
602
434
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
```vue fileName="components/LocalizedLink.vue"
|
|
606
|
-
<template>
|
|
607
|
-
<NuxtLink :to="localizedHref" v-bind="$attrs">
|
|
608
|
-
<slot />
|
|
609
|
-
</NuxtLink>
|
|
610
|
-
</template>
|
|
435
|
+
为了确保您的应用程序导航遵循当前的语言环境,您可以创建一个自定义的 `Links` 组件。该组件会自动为内部 URL 添加当前语言前缀,这对于 **SEO 和页面可发现性** 至关重要。
|
|
611
436
|
|
|
437
|
+
```vue fileName="components/Links.vue"
|
|
612
438
|
<script setup lang="ts">
|
|
613
|
-
import { computed } from "vue";
|
|
614
439
|
import { getLocalizedUrl } from "intlayer";
|
|
615
440
|
import { useLocale } from "vue-intlayer";
|
|
616
441
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
442
|
+
interface Props {
|
|
443
|
+
href: string;
|
|
444
|
+
locale?: string;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const props = defineProps<Props>();
|
|
623
448
|
|
|
624
|
-
const { locale } = useLocale();
|
|
449
|
+
const { locale: currentLocale } = useLocale();
|
|
625
450
|
|
|
626
|
-
//
|
|
627
|
-
const
|
|
451
|
+
// 计算最终路径
|
|
452
|
+
const finalPath = computed(() => {
|
|
453
|
+
// 1. 检查链接是否为外部链接
|
|
454
|
+
const isExternal = /^https?:\/\//.test(props.href || "");
|
|
628
455
|
|
|
629
|
-
//
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
456
|
+
// 2. 如果是外部链接,原样返回(NuxtLink 负责生成 <a> 标签)
|
|
457
|
+
if (isExternal) return props.href;
|
|
458
|
+
|
|
459
|
+
// 3. 如果是内部链接,则本地化 URL
|
|
460
|
+
const targetLocale = props.locale || currentLocale.value;
|
|
461
|
+
return getLocalizedUrl(props.href, targetLocale);
|
|
462
|
+
});
|
|
633
463
|
</script>
|
|
464
|
+
|
|
465
|
+
<template>
|
|
466
|
+
<NuxtLink :to="finalPath" v-bind="$attrs">
|
|
467
|
+
<slot />
|
|
468
|
+
</NuxtLink>
|
|
469
|
+
</template>
|
|
634
470
|
```
|
|
635
471
|
|
|
636
472
|
然后在整个应用中使用此组件:
|
|
637
473
|
|
|
638
|
-
```vue fileName="
|
|
474
|
+
```vue fileName="layouts/default.vue"
|
|
475
|
+
<script setup lang="ts">
|
|
476
|
+
import Links from "~/components/Links.vue";
|
|
477
|
+
import LocaleSwitcher from "~/components/LocaleSwitcher.vue";
|
|
478
|
+
</script>
|
|
479
|
+
|
|
639
480
|
<template>
|
|
640
481
|
<div>
|
|
641
|
-
<
|
|
642
|
-
|
|
643
|
-
</
|
|
644
|
-
<
|
|
645
|
-
|
|
646
|
-
</
|
|
482
|
+
<header>
|
|
483
|
+
<LocaleSwitcher />
|
|
484
|
+
</header>
|
|
485
|
+
<main>
|
|
486
|
+
<slot />
|
|
487
|
+
</main>
|
|
488
|
+
|
|
489
|
+
<Links href="/">首页</Links>
|
|
490
|
+
<Links href="/about">关于</Links>
|
|
647
491
|
</div>
|
|
648
492
|
</template>
|
|
649
|
-
|
|
650
|
-
<script setup lang="ts">
|
|
651
|
-
import { useIntlayer } from "vue-intlayer";
|
|
652
|
-
import LocalizedLink from "~/components/LocalizedLink.vue";
|
|
653
|
-
|
|
654
|
-
const content = useIntlayer("home");
|
|
655
|
-
</script>
|
|
656
493
|
```
|
|
657
494
|
|
|
658
|
-
|
|
495
|
+
> 通过使用带有本地化路径的 `NuxtLink`,您可以确保:
|
|
496
|
+
>
|
|
497
|
+
> - 搜索引擎能够抓取并索引您页面的所有语言版本
|
|
498
|
+
> - 用户可以直接分享本地化的 URL
|
|
499
|
+
> - 浏览器历史记录能正确处理带有语言前缀的 URL
|
|
500
|
+
|
|
501
|
+
### (可选)步骤 9:处理元数据和 SEO
|
|
659
502
|
|
|
660
|
-
Nuxt
|
|
503
|
+
Nuxt 通过 `useHead` 组合式函数(自动导入)提供了出色的 SEO 功能。您可以使用 Intlayer 处理本地化的元数据,使用 `.raw` 或 `.value` 访问器获取原始字符串值:
|
|
661
504
|
|
|
662
505
|
```vue fileName="pages/about.vue"
|
|
663
506
|
<script setup lang="ts">
|
|
664
|
-
import {
|
|
665
|
-
import { getIntlayer } from "intlayer";
|
|
666
|
-
import { useLocale } from "vue-intlayer";
|
|
507
|
+
import { useIntlayer } from "vue-intlayer";
|
|
667
508
|
|
|
668
|
-
|
|
669
|
-
const content =
|
|
509
|
+
// useHead 在 Nuxt 中自动导入
|
|
510
|
+
const content = useIntlayer("about-page");
|
|
670
511
|
|
|
671
|
-
|
|
672
|
-
title: content.
|
|
673
|
-
|
|
512
|
+
useHead({
|
|
513
|
+
title: content.metaTitle.raw, // 使用 .raw 获取原始字符串
|
|
514
|
+
meta: [
|
|
515
|
+
{
|
|
516
|
+
name: "description",
|
|
517
|
+
content: content.metaDescription.raw, // 使用 .raw 获取原始字符串值
|
|
518
|
+
},
|
|
519
|
+
],
|
|
674
520
|
});
|
|
675
521
|
</script>
|
|
676
522
|
|
|
677
523
|
<template>
|
|
678
|
-
<
|
|
679
|
-
<h1>{{ content.pageTitle }}</h1>
|
|
680
|
-
<p>{{ content.pageContent }}</p>
|
|
681
|
-
</div>
|
|
524
|
+
<h1><content.title /></h1>
|
|
682
525
|
</template>
|
|
683
526
|
```
|
|
684
527
|
|
|
528
|
+
> 或者,你可以使用 `import { getIntlayer } from "intlayer"` 函数来获取内容,且不带 Vue 响应性。
|
|
529
|
+
|
|
530
|
+
> **访问内容值:**
|
|
531
|
+
>
|
|
532
|
+
> - 使用 `.raw` 获取原始字符串值(非响应式)
|
|
533
|
+
> - 使用 `.value` 获取响应式值
|
|
534
|
+
> - 使用 `<content.key />` 组件语法以支持可视化编辑器
|
|
535
|
+
|
|
685
536
|
创建对应的内容声明:
|
|
686
537
|
|
|
687
|
-
```ts fileName="pages/about-
|
|
538
|
+
```ts fileName="pages/about-page.content.ts" contentDeclarationFormat="typescript"
|
|
688
539
|
import { t, type Dictionary } from "intlayer";
|
|
689
|
-
import type { useSeoMeta } from "nuxt/app";
|
|
690
540
|
|
|
691
|
-
const
|
|
692
|
-
key: "about-
|
|
541
|
+
const aboutPageContent = {
|
|
542
|
+
key: "about-page",
|
|
693
543
|
content: {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
en: "About Us - My Company",
|
|
544
|
+
metaTitle: t({
|
|
545
|
+
en: "关于我们 - 我的公司",
|
|
697
546
|
fr: "À Propos - Ma Société",
|
|
698
547
|
es: "Acerca de Nosotros - Mi Empresa",
|
|
699
548
|
}),
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
en: "Learn more about our company and our mission",
|
|
549
|
+
metaDescription: t({
|
|
550
|
+
en: "了解更多关于我们公司及我们的使命",
|
|
703
551
|
fr: "En savoir plus sur notre société et notre mission",
|
|
704
552
|
es: "Conozca más sobre nuestra empresa y nuestra misión",
|
|
705
553
|
}),
|
|
554
|
+
title: t({
|
|
555
|
+
en: "关于我们",
|
|
556
|
+
fr: "À Propos",
|
|
557
|
+
es: "Acerca de Nosotros",
|
|
558
|
+
}),
|
|
706
559
|
},
|
|
707
|
-
} satisfies Dictionary
|
|
560
|
+
} satisfies Dictionary;
|
|
708
561
|
|
|
709
|
-
export default
|
|
562
|
+
export default aboutPageContent;
|
|
710
563
|
```
|
|
711
564
|
|
|
712
|
-
```
|
|
565
|
+
```javascript fileName="pages/about-page.content.mjs" contentDeclarationFormat="esm"
|
|
713
566
|
import { t } from "intlayer";
|
|
714
567
|
|
|
715
568
|
/** @type {import('intlayer').Dictionary} */
|
|
716
|
-
const
|
|
717
|
-
key: "about-
|
|
569
|
+
const aboutPageContent = {
|
|
570
|
+
key: "about-page",
|
|
718
571
|
content: {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
en: "About Us - My Company",
|
|
572
|
+
metaTitle: t({
|
|
573
|
+
en: "关于我们 - 我的公司",
|
|
722
574
|
fr: "À Propos - Ma Société",
|
|
723
575
|
es: "Acerca de Nosotros - Mi Empresa",
|
|
724
576
|
}),
|
|
725
|
-
|
|
577
|
+
metaDescription: t({
|
|
726
578
|
zh: "了解更多关于我们公司和我们的使命",
|
|
727
579
|
en: "Learn more about our company and our mission",
|
|
728
580
|
fr: "En savoir plus sur notre société et notre mission",
|
|
729
581
|
es: "Conozca más sobre nuestra empresa y nuestra misión",
|
|
730
582
|
}),
|
|
583
|
+
title: t({
|
|
584
|
+
zh: "关于我们",
|
|
585
|
+
en: "About Us",
|
|
586
|
+
fr: "À Propos",
|
|
587
|
+
es: "Acerca de Nosotros",
|
|
588
|
+
}),
|
|
731
589
|
},
|
|
732
590
|
};
|
|
733
591
|
|
|
734
|
-
export default
|
|
592
|
+
export default aboutPageContent;
|
|
735
593
|
```
|
|
736
594
|
|
|
737
|
-
```
|
|
595
|
+
```javascript fileName="pages/about-page.content.cjs" contentDeclarationFormat="commonjs"
|
|
738
596
|
const { t } = require("intlayer");
|
|
739
597
|
|
|
740
598
|
/** @type {import('intlayer').Dictionary} */
|
|
741
|
-
const
|
|
742
|
-
key: "about-
|
|
599
|
+
const aboutPageContent = {
|
|
600
|
+
key: "about-page",
|
|
743
601
|
content: {
|
|
744
|
-
|
|
602
|
+
metaTitle: t({
|
|
745
603
|
zh: "关于我们 - 我的公司",
|
|
746
604
|
en: "About Us - My Company",
|
|
747
605
|
fr: "À Propos - Ma Société",
|
|
748
|
-
es: "
|
|
606
|
+
es: "关于我们 - 我的公司",
|
|
749
607
|
}),
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
608
|
+
metaDescription: t({
|
|
609
|
+
en: "了解更多关于我们的公司和我们的使命",
|
|
610
|
+
fr: "了解更多关于我们的公司和我们的使命",
|
|
611
|
+
es: "了解更多关于我们的公司和我们的使命",
|
|
612
|
+
}),
|
|
613
|
+
title: t({
|
|
614
|
+
en: "关于我们",
|
|
615
|
+
fr: "关于我们",
|
|
616
|
+
es: "关于我们",
|
|
755
617
|
}),
|
|
756
618
|
},
|
|
757
619
|
};
|
|
758
620
|
|
|
759
|
-
module.exports =
|
|
621
|
+
module.exports = aboutPageContent;
|
|
760
622
|
```
|
|
761
623
|
|
|
762
|
-
```json fileName="pages/about-
|
|
624
|
+
```json fileName="pages/about-page.content.json" contentDeclarationFormat="json"
|
|
763
625
|
{
|
|
764
|
-
"
|
|
626
|
+
"$schema": "https://intlayer.org/schema.json",
|
|
627
|
+
"key": "about-page",
|
|
765
628
|
"content": {
|
|
766
|
-
"
|
|
629
|
+
"metaTitle": {
|
|
767
630
|
"nodeType": "translation",
|
|
768
|
-
"
|
|
769
|
-
"
|
|
770
|
-
"
|
|
771
|
-
"
|
|
772
|
-
"es": "Acerca de Nosotros - Mi Empresa"
|
|
631
|
+
"translation": {
|
|
632
|
+
"en": "关于我们 - 我的公司",
|
|
633
|
+
"fr": "关于我们 - 我的公司",
|
|
634
|
+
"es": "关于我们 - 我的公司"
|
|
773
635
|
}
|
|
774
636
|
},
|
|
775
|
-
"
|
|
637
|
+
"metaDescription": {
|
|
776
638
|
"nodeType": "translation",
|
|
777
|
-
"
|
|
778
|
-
"
|
|
779
|
-
"en": "Learn more about our company and our mission",
|
|
639
|
+
"translation": {
|
|
640
|
+
"en": "了解更多关于我们公司及我们的使命",
|
|
780
641
|
"fr": "En savoir plus sur notre société et notre mission",
|
|
781
642
|
"es": "Conozca más sobre nuestra empresa y nuestra misión"
|
|
782
643
|
}
|
|
644
|
+
},
|
|
645
|
+
"title": {
|
|
646
|
+
"nodeType": "translation",
|
|
647
|
+
"translation": {
|
|
648
|
+
"en": "关于我们",
|
|
649
|
+
"fr": "À Propos",
|
|
650
|
+
"es": "Acerca de Nosotros"
|
|
651
|
+
}
|
|
783
652
|
}
|
|
784
653
|
}
|
|
785
654
|
}
|
|
@@ -787,11 +656,11 @@ module.exports = aboutMetaContent;
|
|
|
787
656
|
|
|
788
657
|
### 配置 TypeScript
|
|
789
658
|
|
|
790
|
-
Intlayer 使用模块增强来利用 TypeScript
|
|
659
|
+
Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库更强大。
|
|
791
660
|
|
|
792
|
-

|
|
793
662
|
|
|
794
|
-

|
|
795
664
|
|
|
796
665
|
确保您的 TypeScript 配置包含自动生成的类型。
|
|
797
666
|
|
|
@@ -824,17 +693,15 @@ Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库
|
|
|
824
693
|
|
|
825
694
|
该扩展提供:
|
|
826
695
|
|
|
827
|
-
-
|
|
828
|
-
-
|
|
829
|
-
-
|
|
830
|
-
-
|
|
696
|
+
- 翻译键的 **自动补全**。
|
|
697
|
+
- 缺失翻译的 **实时错误检测**。
|
|
698
|
+
- 翻译内容的 **内联预览**。
|
|
699
|
+
- 轻松创建和更新翻译的 **快速操作**。
|
|
831
700
|
|
|
832
|
-
有关如何使用该扩展的更多详细信息,请参阅[Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
|
|
701
|
+
有关如何使用该扩展的更多详细信息,请参阅 [Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
|
|
833
702
|
|
|
834
703
|
---
|
|
835
704
|
|
|
836
|
-
###
|
|
837
|
-
|
|
838
|
-
要进一步使用,您可以实现[可视化编辑器](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)将内容外部化。
|
|
705
|
+
### 更进一步
|
|
839
706
|
|
|
840
|
-
|
|
707
|
+
要进一步提升,您可以实现[可视化编辑器](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)将内容外部化。
|