@modern-js/main-doc 3.1.4 → 3.2.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/docs/en/components/international/init-options-desc.mdx +1 -1
- package/docs/en/components/international/install-command.mdx +4 -17
- package/docs/en/components/international/instance-code.mdx +4 -14
- package/docs/en/components/international/introduce.mdx +4 -1
- package/docs/en/configure/app/source/enable-async-pre-entry.mdx +30 -0
- package/docs/en/configure/app/tools/dev-server.mdx +0 -4
- package/docs/en/guides/advanced-features/international/_meta.json +0 -1
- package/docs/en/guides/advanced-features/international/advanced.mdx +48 -109
- package/docs/en/guides/advanced-features/international/api.mdx +125 -290
- package/docs/en/guides/advanced-features/international/best-practices.mdx +203 -48
- package/docs/en/guides/advanced-features/international/configuration.mdx +108 -315
- package/docs/en/guides/advanced-features/international/locale-detection.mdx +62 -208
- package/docs/en/guides/advanced-features/international/quick-start.mdx +41 -55
- package/docs/en/guides/advanced-features/international/resource-loading.mdx +63 -322
- package/docs/en/guides/advanced-features/international/routing.mdx +60 -138
- package/docs/en/guides/advanced-features/international.mdx +19 -27
- package/docs/en/guides/basic-features/alias.mdx +1 -1
- package/docs/en/guides/basic-features/html.mdx +2 -2
- package/docs/en/guides/basic-features/static-assets.mdx +1 -2
- package/docs/en/guides/concept/entries.mdx +2 -2
- package/docs/zh/components/international/init-options-desc.mdx +1 -1
- package/docs/zh/components/international/install-command.mdx +4 -16
- package/docs/zh/components/international/instance-code.mdx +4 -14
- package/docs/zh/components/international/introduce.mdx +5 -2
- package/docs/zh/configure/app/source/enable-async-pre-entry.mdx +77 -0
- package/docs/zh/configure/app/tools/dev-server.mdx +0 -4
- package/docs/zh/guides/advanced-features/bff/function.mdx +2 -2
- package/docs/zh/guides/advanced-features/international/_meta.json +0 -1
- package/docs/zh/guides/advanced-features/international/advanced.mdx +48 -109
- package/docs/zh/guides/advanced-features/international/api.mdx +126 -292
- package/docs/zh/guides/advanced-features/international/best-practices.mdx +204 -49
- package/docs/zh/guides/advanced-features/international/configuration.mdx +105 -318
- package/docs/zh/guides/advanced-features/international/locale-detection.mdx +62 -236
- package/docs/zh/guides/advanced-features/international/quick-start.mdx +40 -54
- package/docs/zh/guides/advanced-features/international/resource-loading.mdx +62 -324
- package/docs/zh/guides/advanced-features/international/routing.mdx +58 -136
- package/docs/zh/guides/advanced-features/international.mdx +19 -26
- package/docs/zh/guides/basic-features/alias.mdx +1 -1
- package/docs/zh/guides/basic-features/html.mdx +2 -2
- package/docs/zh/guides/basic-features/static-assets.mdx +1 -2
- package/docs/zh/guides/concept/entries.mdx +2 -2
- package/package.json +5 -4
- package/rspress.config.ts +45 -26
- package/docs/en/components/rspackPrecautions.mdx +0 -6
- package/docs/en/guides/advanced-features/international/basic.mdx +0 -417
- package/docs/zh/components/rspackPrecautions.mdx +0 -6
- package/docs/zh/guides/advanced-features/international/basic.mdx +0 -416
|
@@ -4,21 +4,29 @@ title: 语言检测
|
|
|
4
4
|
|
|
5
5
|
# 语言检测
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
语言检测指的是在用户没有手动选择语言的情况下,自动推断应该使用哪种语言。插件支持从 URL 路径、Cookie、请求头、浏览器设置等多个来源检测,可以组合使用。
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 检测优先级
|
|
10
|
+
|
|
11
|
+
无论启用了哪些检测方式,优先级固定如下(从高到低):
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
1. **SSR 数据**:从 `window._SSR_DATA` 读取服务端渲染时已检测到的语言,确保客户端与服务端一致,避免语言闪烁
|
|
14
|
+
2. **路径检测**:从 URL 路径前缀读取(需要启用 `localePathRedirect`)
|
|
15
|
+
3. **i18next 检测器**:按 `detection.order` 配置的顺序依次检测(Cookie、LocalStorage、查询参数等)
|
|
16
|
+
4. **initOptions.lng**:运行时配置中强制指定的语言
|
|
17
|
+
5. **fallbackLanguage**:所有检测方式均失败时的兜底语言
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
## 检测方式
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
### URL 路径检测
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
- `/en/about` → 检测到语言:`en`
|
|
19
|
-
- `/about` → 如果没有语言前缀,会重定向到默认语言路径
|
|
23
|
+
设置 `localePathRedirect: true` 后,插件从 URL 路径前缀识别语言,并将无前缀的路径自动重定向到默认语言:
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
```
|
|
26
|
+
/about → 重定向到 /en/about(fallbackLanguage 为 en)
|
|
27
|
+
/zh/about → 识别语言为 zh,不重定向
|
|
28
|
+
/en/about → 识别语言为 en,不重定向
|
|
29
|
+
```
|
|
22
30
|
|
|
23
31
|
```ts
|
|
24
32
|
i18nPlugin({
|
|
@@ -30,63 +38,11 @@ i18nPlugin({
|
|
|
30
38
|
});
|
|
31
39
|
```
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
使用约定式路由时,需要在 `routes/` 目录下创建 `[lang]` 目录来表示语言参数:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
routes/
|
|
39
|
-
├── [lang]/
|
|
40
|
-
│ ├── layout.tsx # 布局组件
|
|
41
|
-
│ ├── page.tsx # 首页
|
|
42
|
-
│ └── about/
|
|
43
|
-
│ └── page.tsx # About 页面
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**routes/[lang]/layout.tsx**:
|
|
47
|
-
|
|
48
|
-
```tsx
|
|
49
|
-
import { Outlet } from '@modern-js/runtime/router';
|
|
50
|
-
|
|
51
|
-
export default function Layout() {
|
|
52
|
-
return <Outlet />;
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**routes/[lang]/page.tsx**:
|
|
57
|
-
|
|
58
|
-
```tsx
|
|
59
|
-
export default function Home() {
|
|
60
|
-
return <div>Home</div>;
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**routes/[lang]/about/page.tsx**:
|
|
65
|
-
|
|
66
|
-
```tsx
|
|
67
|
-
export default function About() {
|
|
68
|
-
return <div>About</div>;
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
:::info
|
|
73
|
-
|
|
74
|
-
如果使用自定义路由(`modern.routes.ts`),需要在路由配置中添加 `:lang` 动态参数。约定式路由会自动根据文件结构生成对应的路由。
|
|
75
|
-
|
|
76
|
-
:::
|
|
41
|
+
启用路径检测后,还需要在路由中配置 `[lang]` 动态参数,详见[路由集成](./routing.md)。
|
|
77
42
|
|
|
78
|
-
###
|
|
43
|
+
### i18next 检测器
|
|
79
44
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
- **Cookie**:从 Cookie 中读取语言设置
|
|
83
|
-
- **LocalStorage**:从浏览器 LocalStorage 中读取
|
|
84
|
-
- **查询参数**:从 URL 查询参数中读取(如 `?lng=en`)
|
|
85
|
-
- **请求头**:从 HTTP 请求头中读取(如 `Accept-Language`)
|
|
86
|
-
- **HTML 标签**:从 HTML 标签的 `lang` 属性读取
|
|
87
|
-
- **子域名**:从子域名中读取(如 `en.example.com`)
|
|
88
|
-
|
|
89
|
-
**配置**:
|
|
45
|
+
设置 `i18nextDetector: true` 后,启用从 Cookie、LocalStorage、查询参数、请求头等位置检测语言:
|
|
90
46
|
|
|
91
47
|
```ts
|
|
92
48
|
i18nPlugin({
|
|
@@ -103,202 +59,72 @@ i18nPlugin({
|
|
|
103
59
|
});
|
|
104
60
|
```
|
|
105
61
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
通过 `detection` 选项可以自定义检测行为:
|
|
62
|
+
两种方式可以同时启用:
|
|
109
63
|
|
|
110
64
|
```ts
|
|
111
65
|
i18nPlugin({
|
|
112
66
|
localeDetection: {
|
|
113
|
-
|
|
67
|
+
localePathRedirect: true, // 路径前缀
|
|
68
|
+
i18nextDetector: true, // Cookie / Header 等
|
|
69
|
+
languages: ['zh', 'en'],
|
|
70
|
+
fallbackLanguage: 'en',
|
|
114
71
|
detection: {
|
|
115
|
-
|
|
116
|
-
order: ['path', 'cookie', 'querystring', 'header'],
|
|
117
|
-
|
|
118
|
-
// Cookie 相关
|
|
119
|
-
lookupCookie: 'i18next',
|
|
120
|
-
cookieExpirationDate: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1年后过期
|
|
121
|
-
cookieDomain: '.example.com',
|
|
122
|
-
|
|
123
|
-
// 查询参数相关
|
|
124
|
-
lookupQuerystring: 'lng',
|
|
125
|
-
|
|
126
|
-
// 请求头相关
|
|
127
|
-
lookupHeader: 'accept-language',
|
|
128
|
-
|
|
129
|
-
// 缓存配置
|
|
130
|
-
caches: ['cookie', 'localStorage'],
|
|
72
|
+
order: ['cookie', 'header'],
|
|
131
73
|
},
|
|
132
74
|
},
|
|
133
75
|
});
|
|
134
76
|
```
|
|
135
77
|
|
|
136
|
-
##
|
|
137
|
-
|
|
138
|
-
插件的语言检测遵循以下优先级顺序(从高到低):
|
|
139
|
-
|
|
140
|
-
1. **SSR 数据**(最高优先级):从 `window._SSR_DATA` 中读取服务端渲染时设置的语言,适用于 SSR 和 CSR 项目
|
|
141
|
-
2. **路径检测**:如果 `localePathRedirect` 为 `true`,从 URL 路径中检测语言前缀
|
|
142
|
-
3. **i18next 检测器**:按照 `detection.order` 配置的顺序执行检测(Cookie、LocalStorage、查询参数、请求头等)
|
|
143
|
-
4. **用户配置语言**:使用 `initOptions.lng` 中配置的语言
|
|
144
|
-
5. **回退语言**:使用 `fallbackLanguage` 作为最终回退
|
|
78
|
+
## 检测选项(detection)
|
|
145
79
|
|
|
146
|
-
|
|
80
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
81
|
+
| --- | --- | --- | --- |
|
|
82
|
+
| `order` | `string[]` | 见下方 | i18next 检测器内部的检测顺序 |
|
|
83
|
+
| `lookupQuerystring` | `string` | `'lng'` | 查询参数键名,例如 `?lng=en` |
|
|
84
|
+
| `lookupCookie` | `string` | `'i18next'` | Cookie 键名 |
|
|
85
|
+
| `lookupLocalStorage` | `string` | `'i18nextLng'` | LocalStorage 键名(仅浏览器) |
|
|
86
|
+
| `lookupSession` | `string` | — | SessionStorage 键名(仅浏览器) |
|
|
87
|
+
| `lookupHeader` | `string` | `'accept-language'` | HTTP 请求头键名 |
|
|
88
|
+
| `lookupFromPathIndex` | `number` | `0` | 从 URL 路径的第几段开始识别语言 |
|
|
89
|
+
| `caches` | `false \| string[]` | — | 检测到的语言缓存到哪里,如 `['cookie']` |
|
|
90
|
+
| `cookieMinutes` | `number` | `525600`(1年) | Cookie 过期时间(分钟) |
|
|
91
|
+
| `cookieExpirationDate` | `Date` | — | Cookie 过期日期,优先级高于 `cookieMinutes` |
|
|
92
|
+
| `cookieDomain` | `string` | — | Cookie 域名 |
|
|
147
93
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
:::
|
|
151
|
-
|
|
152
|
-
**示例**:
|
|
94
|
+
**默认检测顺序(未配置 `order` 时):**
|
|
153
95
|
|
|
154
96
|
```ts
|
|
155
|
-
|
|
156
|
-
detection: {
|
|
157
|
-
order: ['path', 'cookie', 'querystring', 'header'],
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// 实际检测流程:
|
|
161
|
-
// 1. 首先检查 SSR 数据(window._SSR_DATA)
|
|
162
|
-
// 2. 然后检查 URL 路径(如果启用 localePathRedirect)
|
|
163
|
-
// 3. 然后按照 order 顺序检查 i18next 检测器:
|
|
164
|
-
// - Cookie
|
|
165
|
-
// - 查询参数
|
|
166
|
-
// - 请求头
|
|
167
|
-
// 4. 然后使用 initOptions.lng(如果配置)
|
|
168
|
-
// 5. 最后使用 fallbackLanguage
|
|
97
|
+
['querystring', 'cookie', 'localStorage', 'header', 'navigator', 'htmlTag', 'path', 'subdomain']
|
|
169
98
|
```
|
|
170
99
|
|
|
171
|
-
|
|
100
|
+
**`order` 可用值:**
|
|
172
101
|
|
|
173
|
-
|
|
102
|
+
| 值 | 检测来源 | 限制 |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| `querystring` | URL 查询参数(`?lng=en`) | — |
|
|
105
|
+
| `cookie` | Cookie | — |
|
|
106
|
+
| `localStorage` | LocalStorage | 仅浏览器 |
|
|
107
|
+
| `sessionStorage` | SessionStorage | 仅浏览器 |
|
|
108
|
+
| `navigator` | 浏览器语言设置 | 仅浏览器 |
|
|
109
|
+
| `htmlTag` | `<html lang="...">` | 仅浏览器 |
|
|
110
|
+
| `header` | `Accept-Language` 请求头 | — |
|
|
111
|
+
| `path` | URL 路径(需同时启用 `localePathRedirect`) | — |
|
|
112
|
+
| `subdomain` | 子域名(`en.example.com`) | — |
|
|
174
113
|
|
|
175
|
-
|
|
114
|
+
## ignoreRedirectRoutes
|
|
176
115
|
|
|
177
|
-
|
|
178
|
-
- `querystring`:从查询参数检测(如 `?lng=en`)
|
|
179
|
-
- `cookie`:从 Cookie 检测
|
|
180
|
-
- `localStorage`:从 LocalStorage 检测(仅浏览器环境)
|
|
181
|
-
- `sessionStorage`:从 SessionStorage 检测(仅浏览器环境)
|
|
182
|
-
- `navigator`:从浏览器语言设置检测(仅浏览器环境)
|
|
183
|
-
- `htmlTag`:从 HTML 标签的 `lang` 属性检测(仅浏览器环境)
|
|
184
|
-
- `header`:从 HTTP 请求头检测(如 `Accept-Language`)
|
|
185
|
-
- `subdomain`:从子域名检测(如 `en.example.com`)
|
|
116
|
+
指定哪些路径跳过语言路径重定向,适用于 API 路由、静态资源等不需要语言前缀的路径。
|
|
186
117
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
如果不配置 `order`,插件会使用以下默认顺序:
|
|
118
|
+
**写法一:字符串数组**(支持精确匹配和前缀匹配)
|
|
190
119
|
|
|
191
120
|
```ts
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
'cookie', // 然后是 Cookie
|
|
195
|
-
'localStorage', // 然后是 LocalStorage
|
|
196
|
-
'header', // 然后是请求头
|
|
197
|
-
'navigator', // 然后是浏览器语言
|
|
198
|
-
'htmlTag', // 然后是 HTML 标签
|
|
199
|
-
'path', // 然后是路径
|
|
200
|
-
'subdomain', // 最后是子域名
|
|
201
|
-
];
|
|
121
|
+
ignoreRedirectRoutes: ['/api', '/admin', '/static']
|
|
122
|
+
// '/api' 会匹配 /api 和 /api/users
|
|
202
123
|
```
|
|
203
124
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
`path` 检测需要 `localePathRedirect` 为 `true`,`localStorage`、`sessionStorage`、`navigator`、`htmlTag` 仅在浏览器环境可用。
|
|
207
|
-
|
|
208
|
-
:::
|
|
209
|
-
|
|
210
|
-
:::info
|
|
211
|
-
|
|
212
|
-
注意:`order` 配置只影响 i18next 检测器内部的优先级。实际的检测优先级还包括 SSR 数据和路径检测,它们有更高的优先级(见上面的"检测优先级"章节)。
|
|
213
|
-
|
|
214
|
-
:::
|
|
215
|
-
|
|
216
|
-
### caches(缓存方式)
|
|
217
|
-
|
|
218
|
-
指定检测到的语言应该缓存在哪里,可选值:
|
|
219
|
-
|
|
220
|
-
- `false`:不缓存
|
|
221
|
-
- `['cookie']`:缓存到 Cookie
|
|
222
|
-
- `['localStorage']`:缓存到 LocalStorage(仅浏览器)
|
|
223
|
-
- `['cookie', 'localStorage']`:同时缓存到 Cookie 和 LocalStorage
|
|
224
|
-
|
|
225
|
-
### lookupQuerystring、lookupCookie、lookupLocalStorage、lookupSession、lookupHeader
|
|
226
|
-
|
|
227
|
-
指定从查询参数、Cookie、LocalStorage、SessionStorage 或请求头中读取语言时使用的键名:
|
|
228
|
-
|
|
229
|
-
- `lookupQuerystring`:默认 `'lng'`,例如 `?lng=en`
|
|
230
|
-
- `lookupCookie`:默认 `'i18next'`
|
|
231
|
-
- `lookupLocalStorage`:默认 `'i18nextLng'`(仅浏览器环境)
|
|
232
|
-
- `lookupSession`:SessionStorage 的键名(仅浏览器环境)
|
|
233
|
-
- `lookupHeader`:默认 `'accept-language'`
|
|
234
|
-
|
|
235
|
-
### lookupFromPathIndex
|
|
236
|
-
|
|
237
|
-
指定从 URL 路径的哪个位置开始检测语言(当 `order` 中包含 `'path'` 时):
|
|
238
|
-
|
|
239
|
-
- `lookupFromPathIndex`:路径段索引,默认为 `0`(第一个路径段)
|
|
240
|
-
|
|
241
|
-
**示例**:
|
|
242
|
-
|
|
243
|
-
```ts
|
|
244
|
-
// URL: /api/v1/en/users
|
|
245
|
-
// 如果 lookupFromPathIndex = 2,则从第三个路径段('en')开始检测
|
|
246
|
-
detection: {
|
|
247
|
-
order: ['path'],
|
|
248
|
-
lookupFromPathIndex: 2,
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
### cookieMinutes、cookieExpirationDate
|
|
253
|
-
|
|
254
|
-
控制 Cookie 的过期时间:
|
|
255
|
-
|
|
256
|
-
- `cookieMinutes`:Cookie 过期时间(分钟),默认 `525600`(1 年)
|
|
257
|
-
- `cookieExpirationDate`:Cookie 过期日期(Date 对象),优先级高于 `cookieMinutes`
|
|
258
|
-
|
|
259
|
-
**示例**:
|
|
125
|
+
**写法二:函数**(更灵活的自定义逻辑)
|
|
260
126
|
|
|
261
127
|
```ts
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
// 或
|
|
265
|
-
cookieExpirationDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7天后过期
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### ignoreRedirectRoutes
|
|
270
|
-
|
|
271
|
-
指定哪些路由应该忽略自动语言重定向。这对于 API 路由、静态资源等不需要语言前缀的路径非常有用。
|
|
272
|
-
|
|
273
|
-
**配置方式**:
|
|
274
|
-
|
|
275
|
-
```ts
|
|
276
|
-
i18nPlugin({
|
|
277
|
-
localeDetection: {
|
|
278
|
-
localePathRedirect: true,
|
|
279
|
-
languages: ['zh', 'en'],
|
|
280
|
-
fallbackLanguage: 'en',
|
|
281
|
-
// 字符串数组:支持精确匹配和前缀匹配
|
|
282
|
-
ignoreRedirectRoutes: ['/api', '/admin', '/static'],
|
|
283
|
-
// 或使用函数进行更灵活的判断
|
|
284
|
-
ignoreRedirectRoutes: pathname => {
|
|
285
|
-
return pathname.startsWith('/api') || pathname.startsWith('/admin');
|
|
286
|
-
},
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**匹配规则**:
|
|
292
|
-
|
|
293
|
-
- 字符串数组:支持精确匹配(`'/api'`)和前缀匹配(`'/api'` 会匹配 `/api` 和 `/api/users`)
|
|
294
|
-
- 函数:接收路径名(已去除语言前缀),返回 `true` 表示忽略重定向
|
|
295
|
-
|
|
296
|
-
**示例**:
|
|
297
|
-
|
|
298
|
-
```ts
|
|
299
|
-
// 忽略所有 API 路由和静态资源
|
|
300
|
-
ignoreRedirectRoutes: ['/api', '/static', '/assets'];
|
|
301
|
-
|
|
302
|
-
// 使用函数忽略所有以 /api 开头的路径
|
|
303
|
-
ignoreRedirectRoutes: pathname => pathname.startsWith('/api');
|
|
128
|
+
ignoreRedirectRoutes: pathname =>
|
|
129
|
+
pathname.startsWith('/api') || pathname.startsWith('/admin'),
|
|
304
130
|
```
|
|
@@ -8,119 +8,105 @@ title: 快速开始
|
|
|
8
8
|
|
|
9
9
|
## 安装插件
|
|
10
10
|
|
|
11
|
-
首先,安装必要的依赖:
|
|
12
|
-
|
|
13
11
|
import InstallCommand from '@site-docs/components/international/install-command';
|
|
14
12
|
|
|
15
13
|
<InstallCommand />
|
|
16
14
|
|
|
17
15
|
## 基础配置
|
|
18
16
|
|
|
19
|
-
###
|
|
17
|
+
### 第一步:注册插件
|
|
18
|
+
|
|
19
|
+
在 `modern.config.ts` 中注册插件:
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
22
|
import { appTools, defineConfig } from '@modern-js/app-tools';
|
|
23
23
|
import { i18nPlugin } from '@modern-js/plugin-i18n';
|
|
24
24
|
|
|
25
25
|
export default defineConfig({
|
|
26
|
-
server: {
|
|
27
|
-
publicDir: './locales', // 必需:指定资源文件目录
|
|
28
|
-
},
|
|
29
26
|
plugins: [
|
|
30
27
|
appTools(),
|
|
31
28
|
i18nPlugin({
|
|
32
29
|
localeDetection: {
|
|
33
|
-
languages: ['zh', 'en'],
|
|
34
|
-
fallbackLanguage: 'en',
|
|
35
|
-
},
|
|
36
|
-
backend: {
|
|
37
|
-
enabled: true, // 启用后端资源加载
|
|
38
|
-
// loadPath 默认为 '/locales/{{lng}}/{{ns}}.json',通常无需修改
|
|
39
|
-
// 注意:你也可以省略 'enabled',只需配置 'loadPath' 或 'addPath',
|
|
40
|
-
// 或者完全省略 backend 配置,让插件自动检测 locales 目录
|
|
30
|
+
languages: ['zh', 'en'],
|
|
31
|
+
fallbackLanguage: 'en',
|
|
41
32
|
},
|
|
42
33
|
}),
|
|
43
34
|
],
|
|
44
35
|
});
|
|
45
36
|
```
|
|
46
37
|
|
|
47
|
-
|
|
48
|
-
`server.publicDir` 是必需配置,用于指定资源文件的实际存放位置。即使使用默认的 `loadPath` 路径,也需要配置此项。
|
|
38
|
+
### 第二步:创建翻译文件
|
|
49
39
|
|
|
40
|
+
:::note 资源加载
|
|
41
|
+
默认情况下,插件本地指定目录下查找翻译资源,在后续章节中我们会介绍更多资源加载方式。
|
|
50
42
|
:::
|
|
51
43
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
import InstanceCode from '@site-docs/components/international/instance-code';
|
|
55
|
-
|
|
56
|
-
<InstanceCode />
|
|
57
|
-
|
|
58
|
-
### 创建语言资源文件
|
|
59
|
-
|
|
60
|
-
在项目根目录创建 `locales` 文件夹,并按语言组织资源文件:
|
|
44
|
+
创建 `config/public/locales` 目录:
|
|
61
45
|
|
|
62
46
|
```
|
|
63
|
-
locales/
|
|
47
|
+
config/public/locales/
|
|
64
48
|
├── en/
|
|
65
49
|
│ └── translation.json
|
|
66
50
|
└── zh/
|
|
67
51
|
└── translation.json
|
|
68
52
|
```
|
|
69
53
|
|
|
70
|
-
**locales/en/translation.json**:
|
|
71
|
-
|
|
72
54
|
```json
|
|
55
|
+
// locales/en/translation.json
|
|
73
56
|
{
|
|
74
|
-
"hello": "Hello",
|
|
75
|
-
"world": "World",
|
|
76
57
|
"welcome": "Welcome to Modern.js"
|
|
77
58
|
}
|
|
78
59
|
```
|
|
79
60
|
|
|
80
|
-
**locales/zh/translation.json**:
|
|
81
|
-
|
|
82
61
|
```json
|
|
62
|
+
// locales/zh/translation.json
|
|
83
63
|
{
|
|
84
|
-
"hello": "你好",
|
|
85
|
-
"world": "世界",
|
|
86
64
|
"welcome": "欢迎使用 Modern.js"
|
|
87
65
|
}
|
|
88
66
|
```
|
|
89
67
|
|
|
90
|
-
###
|
|
68
|
+
### 第三步:配置运行时选项
|
|
69
|
+
|
|
70
|
+
import InstanceCode from '@site-docs/components/international/instance-code';
|
|
71
|
+
|
|
72
|
+
<InstanceCode />
|
|
73
|
+
|
|
74
|
+
### 第四步:在组件中使用
|
|
75
|
+
|
|
76
|
+
通过 `t()` 函数返回的语言文案,在调用 `changeLanguage` 后会自动更新,无需手动刷新。
|
|
91
77
|
|
|
92
78
|
```tsx
|
|
93
|
-
import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
94
79
|
import { useTranslation } from 'react-i18next';
|
|
80
|
+
import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
95
81
|
|
|
96
82
|
function App() {
|
|
97
|
-
const { language, changeLanguage, supportedLanguages } = useModernI18n();
|
|
98
83
|
const { t } = useTranslation();
|
|
84
|
+
const { language, changeLanguage, supportedLanguages } = useModernI18n();
|
|
99
85
|
|
|
100
86
|
return (
|
|
101
87
|
<div>
|
|
102
88
|
<h1>{t('welcome')}</h1>
|
|
103
|
-
<p
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
))}
|
|
114
|
-
</div>
|
|
89
|
+
<p>当前语言:{language}</p>
|
|
90
|
+
{supportedLanguages.map(lang => (
|
|
91
|
+
<button
|
|
92
|
+
key={lang}
|
|
93
|
+
onClick={() => changeLanguage(lang)}
|
|
94
|
+
disabled={lang === language}
|
|
95
|
+
>
|
|
96
|
+
{lang}
|
|
97
|
+
</button>
|
|
98
|
+
))}
|
|
115
99
|
</div>
|
|
116
100
|
);
|
|
117
101
|
}
|
|
118
|
-
|
|
119
|
-
export default App;
|
|
120
102
|
```
|
|
121
103
|
|
|
122
104
|
## 下一步
|
|
123
105
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
-
|
|
106
|
+
根据你的需求选择继续阅读:
|
|
107
|
+
|
|
108
|
+
- **想要 `/en/about` 这样的 URL 结构** → [路由集成](./routing.md)
|
|
109
|
+
- **需要按 Cookie / Header 自动切换语言** → [语言检测](./locale-detection.md)
|
|
110
|
+
- **翻译资源来自远程服务** → [资源加载 → 自定义后端](./resource-loading.md#自定义后端)
|
|
111
|
+
- **SSR 场景** → [高级用法](./advanced.md)
|
|
112
|
+
- **查看所有配置选项** → [配置说明](./configuration.md)
|