@modern-js/main-doc 3.1.5 → 3.2.1

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.
Files changed (60) hide show
  1. package/docs/en/community/contributing-guide.mdx +1 -1
  2. package/docs/en/components/international/init-options-desc.mdx +1 -1
  3. package/docs/en/components/international/install-command.mdx +4 -17
  4. package/docs/en/components/international/instance-code.mdx +4 -14
  5. package/docs/en/components/international/introduce.mdx +4 -1
  6. package/docs/en/configure/app/server/tsconfig-path.mdx +63 -0
  7. package/docs/en/configure/app/source/enable-async-pre-entry.mdx +30 -0
  8. package/docs/en/configure/app/tools/dev-server.mdx +0 -4
  9. package/docs/en/guides/advanced-features/international/_meta.json +0 -1
  10. package/docs/en/guides/advanced-features/international/advanced.mdx +48 -109
  11. package/docs/en/guides/advanced-features/international/api.mdx +125 -290
  12. package/docs/en/guides/advanced-features/international/best-practices.mdx +203 -48
  13. package/docs/en/guides/advanced-features/international/configuration.mdx +108 -315
  14. package/docs/en/guides/advanced-features/international/locale-detection.mdx +62 -208
  15. package/docs/en/guides/advanced-features/international/quick-start.mdx +41 -55
  16. package/docs/en/guides/advanced-features/international/resource-loading.mdx +63 -322
  17. package/docs/en/guides/advanced-features/international/routing.mdx +60 -138
  18. package/docs/en/guides/advanced-features/international.mdx +19 -27
  19. package/docs/en/guides/basic-features/alias.mdx +1 -1
  20. package/docs/en/guides/basic-features/html.mdx +2 -2
  21. package/docs/en/guides/basic-features/static-assets.mdx +1 -2
  22. package/docs/en/guides/basic-features/testing/_meta.json +1 -1
  23. package/docs/en/guides/concept/entries.mdx +2 -2
  24. package/docs/en/guides/get-started/tech-stack.mdx +6 -0
  25. package/docs/zh/community/contributing-guide.mdx +1 -1
  26. package/docs/zh/components/international/init-options-desc.mdx +1 -1
  27. package/docs/zh/components/international/install-command.mdx +4 -16
  28. package/docs/zh/components/international/instance-code.mdx +4 -14
  29. package/docs/zh/components/international/introduce.mdx +5 -2
  30. package/docs/zh/configure/app/server/tsconfig-path.mdx +63 -0
  31. package/docs/zh/configure/app/source/enable-async-pre-entry.mdx +77 -0
  32. package/docs/zh/configure/app/tools/dev-server.mdx +0 -4
  33. package/docs/zh/guides/advanced-features/bff/function.mdx +2 -2
  34. package/docs/zh/guides/advanced-features/international/_meta.json +0 -1
  35. package/docs/zh/guides/advanced-features/international/advanced.mdx +48 -109
  36. package/docs/zh/guides/advanced-features/international/api.mdx +126 -292
  37. package/docs/zh/guides/advanced-features/international/best-practices.mdx +204 -49
  38. package/docs/zh/guides/advanced-features/international/configuration.mdx +105 -318
  39. package/docs/zh/guides/advanced-features/international/locale-detection.mdx +62 -236
  40. package/docs/zh/guides/advanced-features/international/quick-start.mdx +40 -54
  41. package/docs/zh/guides/advanced-features/international/resource-loading.mdx +62 -324
  42. package/docs/zh/guides/advanced-features/international/routing.mdx +58 -136
  43. package/docs/zh/guides/advanced-features/international.mdx +19 -26
  44. package/docs/zh/guides/basic-features/alias.mdx +1 -1
  45. package/docs/zh/guides/basic-features/html.mdx +2 -2
  46. package/docs/zh/guides/basic-features/static-assets.mdx +1 -2
  47. package/docs/zh/guides/basic-features/testing/_meta.json +1 -1
  48. package/docs/zh/guides/concept/entries.mdx +2 -2
  49. package/docs/zh/guides/get-started/tech-stack.mdx +6 -0
  50. package/package.json +4 -4
  51. package/docs/en/components/rspackPrecautions.mdx +0 -6
  52. package/docs/en/guides/advanced-features/international/basic.mdx +0 -417
  53. package/docs/en/guides/basic-features/testing/cypress.mdx +0 -95
  54. package/docs/en/guides/basic-features/testing/jest.mdx +0 -148
  55. package/docs/en/guides/basic-features/testing/vitest.mdx +0 -100
  56. package/docs/zh/components/rspackPrecautions.mdx +0 -6
  57. package/docs/zh/guides/advanced-features/international/basic.mdx +0 -416
  58. package/docs/zh/guides/basic-features/testing/cypress.mdx +0 -95
  59. package/docs/zh/guides/basic-features/testing/jest.mdx +0 -148
  60. package/docs/zh/guides/basic-features/testing/vitest.mdx +0 -100
@@ -4,312 +4,143 @@ title: API Reference
4
4
 
5
5
  # API Reference
6
6
 
7
- ## useModernI18n Hook
7
+ ## useModernI18n
8
8
 
9
- `useModernI18n` is a React Hook provided by the plugin for accessing internationalization functionality in components.
9
+ `useModernI18n` is a React Hook provided by the plugin. Use it to access internationalization state and actions in components.
10
10
 
11
11
  ### Return Value
12
12
 
13
- ```ts
14
- interface UseModernI18nReturn {
15
- /** Current language code */
16
- language: string;
17
-
18
- /** Function to change language */
19
- changeLanguage: (newLang: string) => Promise<void>;
20
-
21
- /** i18next instance (for advanced usage) */
22
- i18nInstance: I18nInstance;
23
-
24
- /** Supported language list */
25
- supportedLanguages: string[];
26
-
27
- /** Check if language is supported */
28
- isLanguageSupported: (lang: string) => boolean;
29
-
30
- /** Indicates if translation resources for current language are ready to use */
31
- isResourcesReady: boolean;
32
- }
33
- ```
13
+ | Field | Type | Description |
14
+ | --- | --- | --- |
15
+ | `language` | `string` | Current language code |
16
+ | `changeLanguage` | `(lang: string) => Promise<void>` | Switches language |
17
+ | `supportedLanguages` | `string[]` | Supported language list, from `localeDetection.languages` |
18
+ | `isLanguageSupported` | `(lang: string) => boolean` | Checks whether a language is in the supported list |
19
+ | `isResourcesReady` | `boolean` | Whether translation resources for the current language have finished loading |
20
+ | `i18nInstance` | `I18nInstance` | i18next instance for advanced scenarios |
34
21
 
35
- ### Usage Example
22
+ ### Basic Usage
36
23
 
37
24
  ```tsx
38
25
  import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
26
+ import { useTranslation } from 'react-i18next';
39
27
 
40
28
  function LanguageSwitcher() {
41
- const { language, changeLanguage, supportedLanguages, isLanguageSupported } =
42
- useModernI18n();
29
+ const { language, changeLanguage, supportedLanguages } = useModernI18n();
30
+ const { t } = useTranslation();
43
31
 
44
32
  return (
45
33
  <div>
46
- <p>Current language: {language}</p>
47
- <div>
48
- {supportedLanguages.map(lang => (
49
- <button
50
- key={lang}
51
- onClick={() => changeLanguage(lang)}
52
- disabled={lang === language}
53
- >
54
- {lang}
55
- </button>
56
- ))}
57
- </div>
58
- <button
59
- onClick={() => {
60
- if (isLanguageSupported('ja')) {
61
- changeLanguage('ja');
62
- }
63
- }}
64
- >
65
- Switch to Japanese
66
- </button>
34
+ <p>{t('welcome')}</p>
35
+ {supportedLanguages.map(lang => (
36
+ <button
37
+ key={lang}
38
+ onClick={() => changeLanguage(lang)}
39
+ disabled={lang === language}
40
+ >
41
+ {lang}
42
+ </button>
43
+ ))}
67
44
  </div>
68
45
  );
69
46
  }
70
47
  ```
71
48
 
72
- ### changeLanguage Method
49
+ ### changeLanguage
73
50
 
74
- The `changeLanguage` method is used to switch languages. It will:
51
+ When switching language, the following happens in order:
75
52
 
76
- 1. Update the language of the i18next instance
77
- 2. Update browser cache (Cookie/LocalStorage)
78
- 3. Update URL path (if `localePathRedirect` is enabled)
53
+ 1. The language of the i18next instance is updated.
54
+ 2. Browser cache is updated (Cookie / LocalStorage, depending on the `caches` configuration).
55
+ 3. The URL path prefix is updated if `localePathRedirect` is enabled.
79
56
 
80
- ```tsx
81
- const { changeLanguage } = useModernI18n();
57
+ `changeLanguage` is asynchronous, so use `await` when calling it:
82
58
 
83
- // Switch language
59
+ ```ts
84
60
  await changeLanguage('zh');
85
61
  ```
86
62
 
87
- :::info
88
- `changeLanguage` is an async function that returns a Promise.
89
-
90
- :::
91
-
92
- ### Language Support Check
93
-
94
- `isLanguageSupported` is used to check if a language is in the supported language list:
95
-
96
- ```tsx
97
- const { isLanguageSupported, changeLanguage } = useModernI18n();
98
-
99
- function handleLanguageChange(lang: string) {
100
- if (isLanguageSupported(lang)) {
101
- changeLanguage(lang);
102
- } else {
103
- console.warn(`Language ${lang} is not supported`);
104
- }
105
- }
106
- ```
107
-
108
- ### Resource Loading State
63
+ ### isResourcesReady
109
64
 
110
- `isResourcesReady` indicates whether the translation resources for the current language are loaded and ready to use. This is particularly useful when using SDK backend to load resources dynamically.
65
+ In custom backend scenarios, translation resources are loaded asynchronously. Use `isResourcesReady` to avoid rendering before resources are ready:
111
66
 
112
67
  ```tsx
113
- import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
114
-
115
68
  function MyComponent() {
116
69
  const { isResourcesReady } = useModernI18n();
70
+ const { t } = useTranslation();
117
71
 
118
72
  if (!isResourcesReady) {
119
- return <div>Loading translation resources...</div>;
73
+ return <div>Loading translations...</div>;
120
74
  }
121
75
 
122
- return <div>Translation resources are ready</div>;
76
+ return <div>{t('content')}</div>;
123
77
  }
124
78
  ```
125
79
 
126
- **When to use:**
127
-
128
- - Display a loading state while resources are being loaded
129
- - Prevent rendering content that depends on translations before resources are ready
130
- - Handle resource loading errors gracefully
131
-
132
- :::info
133
- `isResourcesReady` automatically checks:
134
-
135
- - If i18n instance is initialized
136
- - If any resources for the current language are currently loading (SDK backend only)
137
- - If all required namespaces for the current language are loaded in the store
138
-
139
- :::
80
+ `isResourcesReady` checks whether the i18n instance is initialized, whether resources are currently loading for the current language, and whether all required namespaces have finished loading.
140
81
 
141
82
  ## I18nLink Component
142
83
 
143
- The `I18nLink` component is used to create links with language prefixes.
84
+ A route link component with a locale prefix.
144
85
 
145
86
  ### Props
146
87
 
147
- ```tsx
148
- interface I18nLinkProps {
149
- /** Target path (no need to include language prefix) */
150
- to: string;
151
- /** Child elements */
152
- children: React.ReactNode;
153
- /** Other Link component props (such as replace, state, etc.) */
154
- [key: string]: any;
155
- }
156
- ```
88
+ | Prop | Type | Required | Description |
89
+ | --- | --- | --- | --- |
90
+ | `to` | `string` | Yes | Target path. Do not include the locale prefix |
91
+ | `children` | `React.ReactNode` | Yes | Link content |
92
+ | `replace` | `boolean` | No | Uses `history.replace` instead of `push` |
93
+ | `state` | `any` | No | State passed to the target route |
94
+ | Other Link props | - | No | Inherited from the `Link` component in `@modern-js/runtime/router` |
157
95
 
158
- ### Usage Example
96
+ ### Usage
159
97
 
160
98
  ```tsx
161
99
  import { I18nLink } from '@modern-js/plugin-i18n/runtime';
162
100
 
163
- function Navigation() {
164
- return (
165
- <nav>
166
- <I18nLink to="/">Home</I18nLink>
167
- <I18nLink to="/about">About</I18nLink>
168
- <I18nLink to="/contact" replace>
169
- Contact
170
- </I18nLink>
171
- </nav>
172
- );
173
- }
101
+ <I18nLink to="/about">About</I18nLink>
102
+ <I18nLink to="/contact" replace>Contact</I18nLink>
103
+ <I18nLink to="/profile" state={{ from: 'home' }}>Profile</I18nLink>
174
104
  ```
175
105
 
176
106
  ## Runtime Plugin API
177
107
 
178
- In the `onBeforeRender` hook of Runtime plugins, you can modify the language using the `context.changeLanguage` method. This is useful for scenarios where you need to dynamically set the language based on request information (such as user preferences, geographic location, etc.).
179
-
180
- ### context.changeLanguage
181
-
182
- In the `onBeforeRender` hook, the i18n plugin adds a `changeLanguage` method to the `context` for use by other Runtime plugins.
183
-
184
- **Type Definition:**
185
-
186
- ```ts
187
- interface TInternalRuntimeContext {
188
- i18nInstance?: I18nInstance;
189
- changeLanguage?: (lang: string) => Promise<void>;
190
- }
191
- ```
192
-
193
- ### Usage Example
108
+ The i18n plugin mounts `changeLanguage` and `i18nInstance` on the `context` of the `onBeforeRender` hook for other runtime plugins:
194
109
 
195
110
  ```ts
196
111
  import type { RuntimePlugin } from '@modern-js/runtime';
197
112
 
198
- const myRuntimePlugin = (): RuntimePlugin => ({
199
- name: 'my-runtime-plugin',
113
+ const myPlugin = (): RuntimePlugin => ({
114
+ name: 'my-plugin',
200
115
  setup: api => {
201
116
  api.onBeforeRender(async context => {
202
- // Check if changeLanguage method exists (ensure i18n plugin is loaded)
203
- if (context.changeLanguage) {
204
- // Determine language based on some condition
205
- const userLang = getUserLanguageFromRequest(context);
117
+ if (!context.changeLanguage) return; // Make sure the i18n plugin is loaded.
206
118
 
207
- // Change language
208
- await context.changeLanguage(userLang);
119
+ const lang = detectLangFromRequest(context);
120
+ const supported = context.i18nInstance?.options?.supportedLngs ?? [];
121
+
122
+ if (supported.includes(lang)) {
123
+ try {
124
+ await context.changeLanguage(lang);
125
+ } catch (e) {
126
+ console.error('Language change failed:', e);
127
+ }
209
128
  }
210
129
  });
211
130
  },
212
131
  });
213
-
214
- function getUserLanguageFromRequest(context: any): string {
215
- // Get user language from request headers, cookies, or other sources
216
- const acceptLanguage = context.ssrContext?.req?.headers['accept-language'];
217
- // Parse and return appropriate language code
218
- return parseAcceptLanguage(acceptLanguage) || 'zh';
219
- }
220
-
221
- export default myRuntimePlugin;
222
- ```
223
-
224
- ### Notes
225
-
226
- 1. **Execution Order**: Ensure the i18n plugin is registered before other plugins that use `changeLanguage`, so that `context.changeLanguage` is available.
227
-
228
- 2. **Async Operation**: `changeLanguage` is an async method and requires using `await` to wait for completion.
229
-
230
- 3. **Error Handling**: If an invalid language code is passed, an error will be thrown. It's recommended to add error handling:
231
-
232
- ```ts
233
- api.onBeforeRender(async context => {
234
- if (context.changeLanguage) {
235
- try {
236
- await context.changeLanguage('zh');
237
- } catch (error) {
238
- console.error('Failed to change language:', error);
239
- }
240
- }
241
- });
242
- ```
243
-
244
- 4. **Language Validation**: It's recommended to verify that the language is in the supported language list before calling `changeLanguage`:
245
-
246
- ```ts
247
- api.onBeforeRender(async context => {
248
- if (context.changeLanguage && context.i18nInstance) {
249
- const supportedLngs = context.i18nInstance.options?.supportedLngs || [];
250
- const targetLang = 'zh';
251
-
252
- if (supportedLngs.includes(targetLang)) {
253
- await context.changeLanguage(targetLang);
254
- }
255
- }
256
- });
257
- ```
258
-
259
- :::info
260
- The `changeLanguage` method will:
261
-
262
- - Update the language of the i18n instance
263
- - Cache the language selection in the browser environment (Cookie/LocalStorage)
264
- - Trigger callbacks related to language switching
265
-
266
- However, it will not automatically update the URL path. If you need to update the URL, you need to coordinate with the routing plugin or handle it manually.
267
- :::
268
-
269
- ## Integration with react-i18next
270
-
271
- The plugin is fully compatible with `react-i18next` and can use the `useTranslation` Hook and other `react-i18next` features.
272
-
273
- ### useTranslation Hook
274
-
275
- ```tsx
276
- import { useTranslation } from 'react-i18next';
277
-
278
- function MyComponent() {
279
- const { t, i18n } = useTranslation();
280
-
281
- return (
282
- <div>
283
- <h1>{t('welcome')}</h1>
284
- <p>{t('description', { name: 'Modern.js' })}</p>
285
- </div>
286
- );
287
- }
288
132
  ```
289
133
 
290
- ### Accessing i18next Instance
291
-
292
- You can get the i18next instance through `useModernI18n`:
293
-
294
- ```tsx
295
- import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
296
- import { useTranslation } from 'react-i18next';
297
-
298
- function MyComponent() {
299
- const { i18nInstance } = useModernI18n();
300
- const { t } = useTranslation();
301
-
302
- // Directly access i18next instance
303
- console.log(i18nInstance.language);
304
- console.log(i18nInstance.options);
134
+ **Notes:**
305
135
 
306
- return <div>{t('hello')}</div>;
307
- }
308
- ```
136
+ - Make sure the i18n plugin is registered before plugins that use `context.changeLanguage`.
137
+ - `changeLanguage` does not update the URL path on the server. Use it together with the routing plugin or handle the path manually.
309
138
 
310
139
  ## Type Definitions
311
140
 
312
- ### I18nInstance Interface
141
+ ### I18nInstance
142
+
143
+ The i18next instance type used by the plugin. It is a subset of the i18next `i18n` type and only lists fields actually used by the plugin:
313
144
 
314
145
  ```ts
315
146
  interface I18nInstance {
@@ -319,82 +150,86 @@ interface I18nInstance {
319
150
  changeLanguage: (lang: string) => void | Promise<void>;
320
151
  use: (plugin: any) => void;
321
152
  createInstance: (options?: I18nInitOptions) => I18nInstance;
322
- cloneInstance?: () => I18nInstance;
323
- services?: {
324
- languageDetector?: {
325
- detect: (request?: any, options?: any) => string | string[] | undefined;
326
- [key: string]: any;
327
- };
328
- [key: string]: any;
329
- };
330
153
  options?: {
331
154
  backend?: BackendOptions;
155
+ supportedLngs?: string[];
332
156
  [key: string]: any;
333
157
  };
334
158
  }
335
159
  ```
336
160
 
337
- ### I18nInitOptions Interface
161
+ ### I18nSdkLoader
162
+
163
+ Type of the custom backend loader function:
338
164
 
339
165
  ```ts
340
- interface I18nInitOptions {
341
- lng?: string;
342
- fallbackLng?: string;
343
- supportedLngs?: string[];
344
- initImmediate?: boolean;
345
- detection?: LanguageDetectorOptions;
346
- backend?: BackendOptions;
347
- resources?: Resources;
348
- ns?: string | string[];
349
- defaultNS?: string | string[];
350
- react?: {
351
- useSuspense?: boolean;
352
- [key: string]: any;
353
- };
354
- [key: string]: any;
166
+ type I18nSdkLoader = (options: I18nSdkLoadOptions) => Promise<Resources>;
167
+
168
+ interface I18nSdkLoadOptions {
169
+ lng?: string; // Single language code
170
+ ns?: string; // Single namespace
171
+ lngs?: string[]; // Multiple language codes
172
+ nss?: string[]; // Multiple namespaces
173
+ all?: boolean; // Load all resources
355
174
  }
175
+
176
+ type Resources = {
177
+ [lng: string]: {
178
+ [ns: string]: Record<string, any>;
179
+ };
180
+ };
356
181
  ```
357
182
 
358
- ### LanguageDetectorOptions Interface
183
+ ### LanguageDetectorOptions
359
184
 
360
185
  ```ts
361
186
  interface LanguageDetectorOptions {
362
- /** Detection order */
363
187
  order?: string[];
364
- /** Query parameter key name, default 'lng' */
365
- lookupQuerystring?: string;
366
- /** Cookie key name, default 'i18next' */
367
- lookupCookie?: string;
368
- /** LocalStorage key name, default 'i18nextLng' (browser only) */
369
- lookupLocalStorage?: string;
370
- /** SessionStorage key name (browser only) */
188
+ lookupQuerystring?: string; // Default: 'lng'
189
+ lookupCookie?: string; // Default: 'i18next'
190
+ lookupLocalStorage?: string; // Default: 'i18nextLng'
371
191
  lookupSession?: string;
372
- /** Starting index in path for language detection, default 0 */
373
- lookupFromPathIndex?: number;
374
- /** Cache method, can be false or string array (e.g., ['cookie', 'localStorage']) */
375
- caches?: boolean | string[];
376
- /** Cookie expiration time (minutes) */
377
- cookieMinutes?: number;
378
- /** Cookie expiration date (Date object, takes precedence over cookieMinutes) */
192
+ lookupHeader?: string; // Default: 'accept-language'
193
+ lookupFromPathIndex?: number; // Default: 0
194
+ caches?: false | string[];
195
+ cookieMinutes?: number; // Default: 525600 (1 year)
379
196
  cookieExpirationDate?: Date;
380
- /** Cookie domain */
381
197
  cookieDomain?: string;
382
- /** Request header key name, default 'accept-language' */
383
- lookupHeader?: string;
384
198
  }
385
199
  ```
386
200
 
387
- ### Resources Type
201
+ ## Integration with react-i18next
388
202
 
389
- ```ts
390
- type Resources = {
391
- [lng: string]: {
392
- [ns: string]: string | Record<string, string>;
393
- };
394
- };
203
+ The plugin is fully compatible with react-i18next, and the two API sets can be used together:
204
+
205
+ - **`useTranslation`** (react-i18next): Gets the `t()` function for translation. This is the most commonly used Hook.
206
+ - **`useModernI18n`** (provided by the plugin): Gets plugin-level state such as language switching, supported language list, and resource loading status.
207
+
208
+ Most components only need `useTranslation`. Use `useModernI18n` only when you need language switching or resource loading status:
209
+
210
+ ```tsx
211
+ import { useTranslation } from 'react-i18next';
212
+ import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
213
+
214
+ function App() {
215
+ const { t } = useTranslation(); // Translate text
216
+ const { language, changeLanguage } = useModernI18n(); // Switch language
217
+
218
+ return (
219
+ <div>
220
+ <h1>{t('welcome')}</h1>
221
+ <button onClick={() => changeLanguage('zh')}>Chinese</button>
222
+ <button onClick={() => changeLanguage('en')}>English</button>
223
+ </div>
224
+ );
225
+ }
395
226
  ```
396
227
 
397
- :::info
398
- The namespace value can be a string (for simple key-value pairs) or an object (for nested translation structures).
228
+ You can also get the i18next instance from `useModernI18n` and call capabilities outside react-i18next directly:
229
+
230
+ ```tsx
231
+ const { i18nInstance } = useModernI18n();
399
232
 
400
- :::
233
+ // Dynamically add translation resources.
234
+ i18nInstance.addResourceBundle('zh', 'translation', { key: 'Value' }, true, true);
235
+ ```