@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,47 +4,43 @@ title: Resource Loading
|
|
|
4
4
|
|
|
5
5
|
# Resource Loading
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
How translation files are loaded depends on where your translation resources are stored:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
| Scenario | Loading method |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| Translation files are local to the project | Static file backend (the default method in this guide) |
|
|
12
|
+
| Translations come from a remote API or translation platform | Custom backend |
|
|
13
|
+
| Both: local fallback + remote real-time updates | Chained backend |
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
## Static File Backend
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
Put translation files in your project and the plugin loads them directly. This is the most common approach.
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
```
|
|
19
|
+
**CSR and SSR use different loading mechanisms, but the configuration is exactly the same:**
|
|
20
|
+
|
|
21
|
+
- CSR: The browser fetches translation files through HTTP, such as `GET /locales/zh/translation.json`.
|
|
22
|
+
- SSR: The server reads files directly from disk without making HTTP requests.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
The plugin automatically chooses the right mechanism based on the runtime environment. You only need to configure `loadPath` once.
|
|
25
25
|
|
|
26
|
-
Resource
|
|
26
|
+
**Resource file location:**
|
|
27
27
|
|
|
28
28
|
```
|
|
29
|
-
config/public/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
│ └── translation.json
|
|
33
|
-
└── zh/
|
|
34
|
-
└── translation.json
|
|
29
|
+
config/public/locales/ <- Default location. No extra configuration required.
|
|
30
|
+
├── en/translation.json
|
|
31
|
+
└── zh/translation.json
|
|
35
32
|
```
|
|
36
33
|
|
|
37
|
-
Or configure a custom directory through `server.publicDir`:
|
|
38
|
-
|
|
39
34
|
```ts
|
|
35
|
+
// modern.config.ts
|
|
40
36
|
export default defineConfig({
|
|
41
|
-
server: {
|
|
42
|
-
publicDir: './locales', // Specify resource file directory
|
|
43
|
-
},
|
|
44
37
|
plugins: [
|
|
38
|
+
appTools(),
|
|
45
39
|
i18nPlugin({
|
|
46
40
|
backend: {
|
|
47
|
-
|
|
41
|
+
// `{{lng}}` is the language code, and `{{ns}}` is the namespace name.
|
|
42
|
+
// During SSR, the plugin automatically converts the leading `/` prefix
|
|
43
|
+
// to a relative path before reading the file. No extra handling is needed.
|
|
48
44
|
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
|
49
45
|
},
|
|
50
46
|
}),
|
|
@@ -52,115 +48,43 @@ export default defineConfig({
|
|
|
52
48
|
});
|
|
53
49
|
```
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```json
|
|
58
|
-
{
|
|
59
|
-
"key1": "value1",
|
|
60
|
-
"key2": "value2",
|
|
61
|
-
"nested": {
|
|
62
|
-
"key": "value"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Path Variables
|
|
68
|
-
|
|
69
|
-
`loadPath` supports the following variables:
|
|
70
|
-
|
|
71
|
-
- `{{lng}}`: Language code (e.g., `en`, `zh`)
|
|
72
|
-
- `{{ns}}`: Namespace (e.g., `translation`, `common`)
|
|
73
|
-
|
|
74
|
-
**Examples**:
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
// Default path format
|
|
78
|
-
loadPath: '/locales/{{lng}}/{{ns}}.json';
|
|
79
|
-
// Actual loading paths:
|
|
80
|
-
// /locales/en/translation.json
|
|
81
|
-
// /locales/zh/translation.json
|
|
82
|
-
|
|
83
|
-
// Custom path format
|
|
84
|
-
loadPath: '/i18n/{{lng}}/{{ns}}.json';
|
|
85
|
-
// Actual loading paths:
|
|
86
|
-
// /i18n/en/translation.json
|
|
87
|
-
// /i18n/zh/translation.json
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## File System Backend (FS Backend)
|
|
91
|
-
|
|
92
|
-
File System backend reads resource files directly from the file system, suitable for server-side rendering (SSR) scenarios.
|
|
93
|
-
|
|
94
|
-
### Configuration
|
|
95
|
-
|
|
96
|
-
In SSR scenarios, the plugin will automatically use the file system backend. Resource files need to be placed in the project directory:
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
Project Root/
|
|
100
|
-
└── locales/
|
|
101
|
-
├── en/
|
|
102
|
-
│ └── translation.json
|
|
103
|
-
└── zh/
|
|
104
|
-
└── translation.json
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Resource File Path
|
|
108
|
-
|
|
109
|
-
The default path format for file system backend is a relative path:
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
./locales/{{lng}}/{{ns}}.json
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
You can customize the path through `loadPath`:
|
|
116
|
-
|
|
117
|
-
```ts
|
|
118
|
-
i18nPlugin({
|
|
119
|
-
backend: {
|
|
120
|
-
enabled: true,
|
|
121
|
-
loadPath: '/locales/{{lng}}/{{ns}}.json', // Use absolute path (recommended)
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
:::warning
|
|
127
|
-
The `loadPath` configuration is used for both HTTP backend (frontend) and file system backend (server-side). If configured as an absolute path starting with `/` (e.g., `/locales/{{lng}}/{{ns}}.json`), the file system backend will automatically convert it to a relative path (`./locales/{{lng}}/{{ns}}.json`). Therefore, it's recommended to use absolute paths in the configuration, which can meet both frontend and backend requirements.
|
|
128
|
-
|
|
129
|
-
:::
|
|
51
|
+
To store files in another directory, configure `server.publicDir`. The relationship between **`server.publicDir` and `backend.loadPath`** is:
|
|
130
52
|
|
|
131
|
-
|
|
53
|
+
- `server.publicDir`: Decides which local directory is exposed as static assets, that is, where files are placed.
|
|
54
|
+
- `backend.loadPath`: Decides which URL i18next requests for translation files, or which path the server reads from.
|
|
132
55
|
|
|
133
|
-
|
|
56
|
+
## Custom Backend
|
|
134
57
|
|
|
135
|
-
|
|
58
|
+
When translation resources are not local files but come from a remote API, database, or translation platform, load them with an async function.
|
|
136
59
|
|
|
137
|
-
**Step 1:
|
|
60
|
+
**Step 1: declare it enabled in `modern.config.ts`**
|
|
138
61
|
|
|
139
62
|
```ts
|
|
140
63
|
i18nPlugin({
|
|
141
64
|
backend: {
|
|
142
|
-
|
|
143
|
-
sdk: true, // Enable SDK mode
|
|
65
|
+
sdk: true,
|
|
144
66
|
},
|
|
145
67
|
});
|
|
146
68
|
```
|
|
147
69
|
|
|
148
|
-
**Step 2:
|
|
70
|
+
**Step 2: implement the loader function in `modern.runtime.ts`**
|
|
149
71
|
|
|
150
72
|
```ts
|
|
151
73
|
import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
152
|
-
import type { I18nSdkLoader
|
|
74
|
+
import type { I18nSdkLoader } from '@modern-js/plugin-i18n/runtime';
|
|
153
75
|
|
|
154
|
-
const
|
|
155
|
-
//
|
|
156
|
-
if (options.
|
|
157
|
-
|
|
158
|
-
|
|
76
|
+
const myLoader: I18nSdkLoader = async options => {
|
|
77
|
+
// Most common case: load a single resource by language + namespace.
|
|
78
|
+
if (options.lng && options.ns) {
|
|
79
|
+
const res = await fetch(`/api/i18n/${options.lng}/${options.ns}`);
|
|
80
|
+
const data = await res.json();
|
|
81
|
+
return { [options.lng]: { [options.ns]: data } };
|
|
159
82
|
}
|
|
160
83
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
84
|
+
// Load all resources at once.
|
|
85
|
+
if (options.all) {
|
|
86
|
+
const res = await fetch('/api/i18n/all');
|
|
87
|
+
return res.json(); // Format: { en: { translation: {...} }, zh: { translation: {...} } }
|
|
164
88
|
}
|
|
165
89
|
|
|
166
90
|
return {};
|
|
@@ -169,238 +93,53 @@ const mySdkLoader: I18nSdkLoader = async options => {
|
|
|
169
93
|
export default defineRuntimeConfig({
|
|
170
94
|
i18n: {
|
|
171
95
|
initOptions: {
|
|
172
|
-
backend: {
|
|
173
|
-
sdk: mySdkLoader,
|
|
174
|
-
},
|
|
96
|
+
backend: { sdk: myLoader },
|
|
175
97
|
},
|
|
176
98
|
},
|
|
177
99
|
});
|
|
178
100
|
```
|
|
179
101
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
The SDK function receives an `I18nSdkLoadOptions` parameter and needs to return data in `Resources` format:
|
|
102
|
+
**Loader parameter type:**
|
|
183
103
|
|
|
184
104
|
```ts
|
|
185
105
|
interface I18nSdkLoadOptions {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
lngs?: string[];
|
|
192
|
-
/** Multiple namespaces */
|
|
193
|
-
nss?: string[];
|
|
194
|
-
/** Load all resources */
|
|
195
|
-
all?: boolean;
|
|
106
|
+
lng?: string; // Single language code
|
|
107
|
+
ns?: string; // Single namespace
|
|
108
|
+
lngs?: string[]; // Multiple language codes
|
|
109
|
+
nss?: string[]; // Multiple namespaces
|
|
110
|
+
all?: boolean; // Load all resources
|
|
196
111
|
}
|
|
197
|
-
|
|
198
|
-
type Resources = {
|
|
199
|
-
[lng: string]: {
|
|
200
|
-
[ns: string]: Record<string, string>;
|
|
201
|
-
};
|
|
202
|
-
};
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Batch Loading Examples
|
|
206
|
-
|
|
207
|
-
SDK backend supports multiple loading modes:
|
|
208
|
-
|
|
209
|
-
**1. Load single resource**:
|
|
210
|
-
|
|
211
|
-
```ts
|
|
212
|
-
const sdkLoader: I18nSdkLoader = async options => {
|
|
213
|
-
if (options.lng && options.ns) {
|
|
214
|
-
const response = await fetch(`/api/i18n/${options.lng}/${options.ns}`);
|
|
215
|
-
const data = await response.json();
|
|
216
|
-
return {
|
|
217
|
-
[options.lng]: {
|
|
218
|
-
[options.ns]: data,
|
|
219
|
-
},
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
return {};
|
|
223
|
-
};
|
|
224
112
|
```
|
|
225
113
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
```ts
|
|
229
|
-
const sdkLoader: I18nSdkLoader = async options => {
|
|
230
|
-
if (options.lngs && options.ns) {
|
|
231
|
-
const resources: Resources = {};
|
|
232
|
-
for (const lng of options.lngs) {
|
|
233
|
-
const response = await fetch(`/api/i18n/${lng}/${options.ns}`);
|
|
234
|
-
resources[lng] = {
|
|
235
|
-
[options.ns]: await response.json(),
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
return resources;
|
|
239
|
-
}
|
|
240
|
-
return {};
|
|
241
|
-
};
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
**3. Batch load multiple namespaces**:
|
|
245
|
-
|
|
246
|
-
```ts
|
|
247
|
-
const sdkLoader: I18nSdkLoader = async options => {
|
|
248
|
-
if (options.lng && options.nss) {
|
|
249
|
-
const resources: Resources = {
|
|
250
|
-
[options.lng]: {},
|
|
251
|
-
};
|
|
252
|
-
for (const ns of options.nss) {
|
|
253
|
-
const response = await fetch(`/api/i18n/${options.lng}/${ns}`);
|
|
254
|
-
resources[options.lng][ns] = await response.json();
|
|
255
|
-
}
|
|
256
|
-
return resources;
|
|
257
|
-
}
|
|
258
|
-
return {};
|
|
259
|
-
};
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
**4. Load all resources**:
|
|
263
|
-
|
|
264
|
-
```ts
|
|
265
|
-
const sdkLoader: I18nSdkLoader = async options => {
|
|
266
|
-
if (options.all) {
|
|
267
|
-
const response = await fetch('/api/i18n/all');
|
|
268
|
-
return await response.json();
|
|
269
|
-
}
|
|
270
|
-
return {};
|
|
271
|
-
};
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### Check Resource Loading State
|
|
275
|
-
|
|
276
|
-
When using SDK backend, you can check if resources are loaded using `isResourcesReady`:
|
|
277
|
-
|
|
278
|
-
```tsx
|
|
279
|
-
import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
280
|
-
|
|
281
|
-
function MyComponent() {
|
|
282
|
-
const { isResourcesReady } = useModernI18n();
|
|
283
|
-
|
|
284
|
-
if (!isResourcesReady) {
|
|
285
|
-
return <div>Loading translation resources...</div>;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
return <div>Resources are ready!</div>;
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
This is particularly useful when resources are loaded asynchronously, as it ensures all required namespaces for the current language are loaded before rendering content that depends on translations.
|
|
114
|
+
When using a custom backend, translation resources are loaded asynchronously. You can use `isResourcesReady` to show a loading state before loading is complete. See [Best Practices -> Loading State Handling](./best-practices.md#loading-state-handling).
|
|
293
115
|
|
|
294
116
|
## Chained Backend
|
|
295
117
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
### How It Works
|
|
299
|
-
|
|
300
|
-
The chained backend workflow:
|
|
301
|
-
|
|
302
|
-
1. **Initial Load**: First load resources from HTTP/FS backend and display immediately (quick display of basic translations)
|
|
303
|
-
2. **Async Update**: Then asynchronously load resources from SDK backend and update the i18next store (update/supplement translations)
|
|
304
|
-
|
|
305
|
-
This ensures users see page content quickly while the latest translation resources are loaded in the background.
|
|
306
|
-
|
|
307
|
-
### Configuration
|
|
308
|
-
|
|
309
|
-
**Step 1: Configure chained backend in `modern.config.ts`**
|
|
310
|
-
|
|
311
|
-
```ts
|
|
312
|
-
i18nPlugin({
|
|
313
|
-
backend: {
|
|
314
|
-
enabled: true,
|
|
315
|
-
loadPath: '/locales/{{lng}}/{{ns}}.json', // HTTP/FS backend
|
|
316
|
-
sdk: true, // SDK backend
|
|
317
|
-
// cacheHitMode: 'refreshAndUpdateStore', // Default value, can be omitted
|
|
318
|
-
},
|
|
319
|
-
});
|
|
320
|
-
```
|
|
118
|
+
Use local files and a custom backend together to implement "show local translations quickly first, then update asynchronously with the latest translations":
|
|
321
119
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
```ts
|
|
325
|
-
import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
326
|
-
|
|
327
|
-
export default defineRuntimeConfig({
|
|
328
|
-
i18n: {
|
|
329
|
-
initOptions: {
|
|
330
|
-
backend: {
|
|
331
|
-
sdk: async options => {
|
|
332
|
-
// SDK implementation
|
|
333
|
-
if (options.lng && options.ns) {
|
|
334
|
-
return await mySdk.getResource(options.lng, options.ns);
|
|
335
|
-
}
|
|
336
|
-
},
|
|
337
|
-
},
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
});
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### Cache Hit Mode (cacheHitMode)
|
|
344
|
-
|
|
345
|
-
The `cacheHitMode` option controls the behavior of chained backend:
|
|
346
|
-
|
|
347
|
-
- **`'none'`** (default, only when chained backend is not configured): If the first backend returns resources, stop and don't try the next backend
|
|
348
|
-
- **`'refresh'`**: Try to refresh the cache by loading from the next backend and update the cache
|
|
349
|
-
- **`'refreshAndUpdateStore'`** (default for chained backend): Try to refresh the cache by loading from the next backend, update the cache and also update the i18next resource store. This allows FS/HTTP resources to be displayed first, then SDK resources will update them asynchronously.
|
|
350
|
-
|
|
351
|
-
**Configuration example**:
|
|
120
|
+
1. When the page loads, translations are loaded from local files and displayed immediately.
|
|
121
|
+
2. The custom backend loads the latest translations asynchronously in the background. After it completes, the page updates automatically.
|
|
352
122
|
|
|
353
123
|
```ts
|
|
124
|
+
// modern.config.ts
|
|
354
125
|
i18nPlugin({
|
|
355
126
|
backend: {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
sdk: true,
|
|
359
|
-
cacheHitMode: 'refreshAndUpdateStore', // Explicitly specify (default value)
|
|
127
|
+
loadPath: '/locales/{{lng}}/{{ns}}.json', // Local files, fast display
|
|
128
|
+
sdk: true, // Remote loading, async update
|
|
360
129
|
},
|
|
361
130
|
});
|
|
362
131
|
```
|
|
363
132
|
|
|
364
|
-
### Use Cases
|
|
365
|
-
|
|
366
|
-
Chained backend is particularly suitable for the following scenarios:
|
|
367
|
-
|
|
368
|
-
1. **Progressive Loading**: Display local/static resources first, then load latest translations from remote services
|
|
369
|
-
2. **Offline Support**: Local resources as offline fallback, SDK resources provide online updates
|
|
370
|
-
3. **Performance Optimization**: Quickly display basic translations, load complete translation content in the background
|
|
371
|
-
4. **A/B Testing**: Local resources as default values, SDK provides dynamic translation variants
|
|
372
|
-
|
|
373
|
-
### Complete Example
|
|
374
|
-
|
|
375
133
|
```ts
|
|
376
|
-
// modern.config.ts
|
|
377
|
-
i18nPlugin({
|
|
378
|
-
backend: {
|
|
379
|
-
enabled: true,
|
|
380
|
-
loadPath: '/locales/{{lng}}/{{ns}}.json', // Local resources
|
|
381
|
-
sdk: true, // Remote SDK resources
|
|
382
|
-
cacheHitMode: 'refreshAndUpdateStore',
|
|
383
|
-
},
|
|
384
|
-
});
|
|
385
|
-
|
|
386
134
|
// modern.runtime.ts
|
|
387
|
-
import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
388
|
-
|
|
389
135
|
export default defineRuntimeConfig({
|
|
390
136
|
i18n: {
|
|
391
137
|
initOptions: {
|
|
392
138
|
backend: {
|
|
393
139
|
sdk: async options => {
|
|
394
140
|
if (options.lng && options.ns) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
`https://api.example.com/i18n/${options.lng}/${options.ns}`,
|
|
398
|
-
);
|
|
399
|
-
return {
|
|
400
|
-
[options.lng]: {
|
|
401
|
-
[options.ns]: await response.json(),
|
|
402
|
-
},
|
|
403
|
-
};
|
|
141
|
+
const res = await fetch(`https://api.example.com/i18n/${options.lng}/${options.ns}`);
|
|
142
|
+
return { [options.lng]: { [options.ns]: await res.json() } };
|
|
404
143
|
}
|
|
405
144
|
return {};
|
|
406
145
|
},
|
|
@@ -410,8 +149,10 @@ export default defineRuntimeConfig({
|
|
|
410
149
|
});
|
|
411
150
|
```
|
|
412
151
|
|
|
413
|
-
|
|
152
|
+
**`cacheHitMode` option** (controls how the two backends cooperate):
|
|
414
153
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
154
|
+
| Value | Behavior |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| `'none'` | Use local files after a successful local hit and do not request the custom backend |
|
|
157
|
+
| `'refresh'` | Continue requesting the custom backend and update cache, but do not update the current page |
|
|
158
|
+
| `'refreshAndUpdateStore'` | Continue requesting the custom backend, update cache, and refresh page text (default) |
|