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

|
|
793
|
-
|
|
794
|
-

|
|
795
|
-
|
|
796
|
-
确保您的 TypeScript 配置包含自动生成的类型。
|
|
797
|
-
|
|
798
|
-
```json5 fileName="tsconfig.json"
|
|
799
|
-
{
|
|
800
|
-
// ... 您现有的 TypeScript 配置
|
|
801
|
-
"include": [
|
|
802
|
-
// ... 您现有的 TypeScript 配置
|
|
803
|
-
".intlayer/**/*.ts", // 包含自动生成的类型
|
|
804
|
-
],
|
|
805
|
-
}
|
|
806
|
-
```
|
|
807
|
-
|
|
808
649
|
### Git 配置
|
|
809
650
|
|
|
810
651
|
建议忽略 Intlayer 生成的文件。这样可以避免将它们提交到您的 Git 仓库中。
|
|
@@ -824,17 +665,15 @@ Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库
|
|
|
824
665
|
|
|
825
666
|
该扩展提供:
|
|
826
667
|
|
|
827
|
-
-
|
|
828
|
-
-
|
|
829
|
-
-
|
|
830
|
-
-
|
|
668
|
+
- 翻译键的 **自动补全**。
|
|
669
|
+
- 缺失翻译的 **实时错误检测**。
|
|
670
|
+
- 翻译内容的 **内联预览**。
|
|
671
|
+
- 轻松创建和更新翻译的 **快速操作**。
|
|
831
672
|
|
|
832
|
-
有关如何使用该扩展的更多详细信息,请参阅[Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
|
|
673
|
+
有关如何使用该扩展的更多详细信息,请参阅 [Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
|
|
833
674
|
|
|
834
675
|
---
|
|
835
676
|
|
|
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)将内容外部化。
|
|
677
|
+
### 更进一步
|
|
839
678
|
|
|
840
|
-
|
|
679
|
+
要进一步提升,您可以实现[可视化编辑器](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)将内容外部化。
|