@modern-js/main-doc 2.20.0 → 2.21.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,7 +6,7 @@ sidebar_position: 5
6
6
 
7
7
  ## Local Proxy
8
8
 
9
- Modern.js provides a way to configure the development proxy in [tools.devServer](/configure/app/tools/dev-server). For example, to proxy the local interface to an online address:
9
+ Modern.js provides a way to configure the development proxy in [`tools.devServer`](/configure/app/tools/dev-server). For example, to proxy the local interface to an online address:
10
10
 
11
11
  ```ts title="modern.config.ts"
12
12
  import { defineConfig } from '@modern-js/app-tools';
@@ -25,11 +25,10 @@ export default defineConfig({
25
25
  });
26
26
  ```
27
27
 
28
- when access `http://localhost:8080/go/api`, the response content is returned from [http://www.example.com/](http://www.example.com/).
28
+ When access `http://localhost:8080/go/api`, the response content will be returned from [http://www.example.com/](http://www.example.com/).
29
29
 
30
30
  :::info
31
31
  For more detail, see [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware).
32
-
33
32
  :::
34
33
 
35
34
  ## Global Proxy
@@ -40,7 +39,7 @@ import GlobalProxy from "@site-docs-en/components/global-proxy"
40
39
 
41
40
  ## BFF Proxy
42
41
 
43
- By configuring [`bff.proxy`](/configure/app/bff/proxy), you can proxy BFF API requests to specified services. Unlike other proxy above, it can also be used in the production environment:
42
+ By configuring [`bff.proxy`](/configure/app/bff/proxy), BFF API requests can be proxied to a specified service. Unlike the other proxy methods above, it can be used in the production environment:
44
43
 
45
44
  ```ts title="modern.config.ts"
46
45
  export default defineConfig({
@@ -52,7 +51,7 @@ export default defineConfig({
52
51
  });
53
52
  ```
54
53
 
55
- For example, when a BFF call is used in the code, the final request `http://localhost:8080/api/v1/topics` will auto proxy to `https://cnodejs.org/api/v1/topics`:
54
+ For example, when using BFF function in the code, the final request `http://localhost:8080/api/v1/topics` will be automatically proxied to `https://cnodejs.org/api/v1/topics`:
56
55
 
57
56
  ```js
58
57
  import getTopics from '@api/v1/topics';
@@ -5,20 +5,19 @@ sidebar_position: 1
5
5
 
6
6
  # Routes
7
7
 
8
- Modern.js build-in provides partial support for [React Router 6](https://reactrouter.com/en/main) and provides various types of routing modes. According to different [entry](/guides/concept/entries) types, routing is divided into three modes, namely **Conventional routing**, **Self-controlled routing** and **Other**.
8
+ Modern.js's routing is based on [React Router 6](https://reactrouter.com/en/main) and provides multiple types of routing modes. According to different [entry](/guides/concept/entries) types, routing is divided into three modes: **Conventional Routing**, **Self-controlled Routing**, and **Other**.
9
9
 
10
10
  :::note
11
- The routes mentioned in this section are client routes, that is, SPA routes.
12
-
11
+ The routing mentioned in this section refers to client-side routing, i.e., SPA routing.
13
12
  :::
14
13
 
15
- ## Conventional routing
14
+ ## Conventional Routing
16
15
 
17
- With `routes/` as the agreed entry, Modern.js will automatically generate the corresponding routing structure based on the file system.
16
+ With `routes/` as the convention for entry points, Modern.js automatically generates the corresponding routing structure based on the file system.
18
17
 
19
- Modern.js supports the popular convention routing mode in the industry: **nested routing**. When using nested routing, the routing of the page corresponds the UI structure, and we will introduce this routing mode in detail.
18
+ Modern.js supports the popular conventional routing mode in the industry: **Nested Routing**. When using nested routing, the page's routing corresponds to the UI structure, and we will introduce this routing mode in detail.
20
19
 
21
- ```
20
+ ```bash
22
21
  /user/johnny/profile /user/johnny/posts
23
22
  +------------------+ +-----------------+
24
23
  | User | | User |
@@ -29,11 +28,30 @@ Modern.js supports the popular convention routing mode in the industry: **nested
29
28
  +------------------+ +-----------------+
30
29
  ```
31
30
 
32
- ### Routing file convention
31
+ ### Routing File Convention
33
32
 
34
- There are two file conventions in the `routes/` directory `layout.[jt]sx` and `page.[jt]sx`(abbreviated as `.tsx` later). These two files determine the layout hierarchy of the application, where `layout.tsx` is used as the layout component, and `page.tsx` is used as the content component, which is the leaf node of the entire routing table.
33
+ Under the `routes/` directory, the directory name is mapped to the route URL. Modern.js has two file conventions, `layout.[jt]sx` and `page.[jt]sx` (abbreviated as`.tsx`). These two files determine the layout structure of the application. `layout.tsx` is used as the layout component, and `page.tsx` acts as the content component, which is the leaf node of the entire route (a route has only one leaf node and must end with a leaf node).
35
34
 
36
- For example, here `routes/layout.tsx` will be used as the layout component of all components under the `/` route:
35
+ For example, the following directory structure:
36
+
37
+ ```bash
38
+ .
39
+ └── routes
40
+ ├── page.tsx
41
+ └── user
42
+ └── page.tsx
43
+ ```
44
+
45
+ This will generate the following two routes:
46
+
47
+ - `/`
48
+ - `/user`
49
+
50
+ When `layout.tsx` is added, assuming the following directory:
51
+
52
+ :::info
53
+ Here, `routes/layout.tsx` will be used as the layout component for all components under the `/` route, and `routes/user/layout.tsx` will be used as the layout component for all route components under the `/user` route.
54
+ :::
37
55
 
38
56
  ```bash
39
57
  .
@@ -45,7 +63,7 @@ For example, here `routes/layout.tsx` will be used as the layout component of al
45
63
  └── page.tsx
46
64
  ```
47
65
 
48
- When the route is `/`, there will be the following UI layout:
66
+ When the route is `/`, the following UI layout will be displayed:
49
67
 
50
68
  ```tsx
51
69
  <Layout>
@@ -53,7 +71,7 @@ When the route is `/`, there will be the following UI layout:
53
71
  </Layout>
54
72
  ```
55
73
 
56
- Similarly, `routes/user/layout.tsx` will be used as a layout component for all components under the `/user` route. When the route is `/user`, the following UI layout will be available:
74
+ Similarly, `routes/user/layout.tsx` will be used as the layout component for all components under the `/user` route. When the route is `/user`, the following UI layout will be displayed:
57
75
 
58
76
  ```tsx
59
77
  <Layout>
@@ -65,14 +83,26 @@ Similarly, `routes/user/layout.tsx` will be used as a layout component for all c
65
83
 
66
84
  #### Layout
67
85
 
68
- `<Layout>` component refers to all `layout.tsx` files in the `routes/` directory, which represent the layout of the corresponding route segment, and use `<Outlet>` to represent sub-components.
86
+ The `<Layout>` component refers to all `layout.tsx` files under the `routes/` directory. They represent the layout of the corresponding route segment and use `<Outlet>` to represent child components.
87
+
88
+ ```tsx title=routes/layout.tsx
89
+ import { Link, Outlet, useLoaderData } from '@modern-js/runtime/router';
90
+
91
+ export default () => {
92
+ return (
93
+ <>
94
+ <Outlet></Outlet>
95
+ </>
96
+ );
97
+ };
98
+ ```
69
99
 
70
100
  :::note
71
- `<Outlet>` is a new API in React Router 6, see [Outlet](https://reactrouter.com/en/main/components/outlet#outlet) for details.
101
+ `<Outlet>` is a new API in React Router 6. For more details, please refer to [Outlet](https://reactrouter.com/en/main/components/outlet#outlet).
72
102
 
73
103
  :::
74
104
 
75
- In order to facilitate the introduction of the relationship between `<Layout>` and `<Outlet>`, the following file directory example:
105
+ To simplify the introduction of the relationship between `<Layout>` and `<Outlet>`, the following file directory is used as an example:
76
106
 
77
107
  ```bash
78
108
  .
@@ -86,7 +116,7 @@ In order to facilitate the introduction of the relationship between `<Layout>` a
86
116
  └── page.tsx
87
117
  ```
88
118
 
89
- 1. When the route is `/`, `<Outlet>` in `routes/layout.tsx` represents the component exported in `routes/page.tsx`, generating the following UI structure:
119
+ 1. When the route is `/`, the `<Outlet>` in `routes/layout.tsx` represents the component exported in `routes/page.tsx`, generating the following UI structure:
90
120
 
91
121
  ```tsx
92
122
  <Layout>
@@ -94,7 +124,7 @@ In order to facilitate the introduction of the relationship between `<Layout>` a
94
124
  </Layout>
95
125
  ```
96
126
 
97
- 2. When the route is `/blog`, `<Outlet>` in `routes/layout.tsx` represents the component exported in `routes/blog/page.tsx`, generating the following UI structure:
127
+ 2. When the route is `/blog`, the `<Outlet>` in `routes/layout.tsx` represents the component exported in `routes/blog/page.tsx`, generating the following UI structure:
98
128
 
99
129
  ```tsx
100
130
  <Layout>
@@ -102,7 +132,7 @@ In order to facilitate the introduction of the relationship between `<Layout>` a
102
132
  </Layout>
103
133
  ```
104
134
 
105
- 3. When the route is `/user`, `<Outlet>` in `routes/layout.tsx` represents the component exported in `routes/user/layout.tsx`. `<Outlet>` in `routes/user/layout.tsx` represents the component exported in `routes/user/page.tsx`. Generate the following UI structure:
135
+ 3. When the route is `/user`, the `<Outlet>` in `routes/layout.tsx` represents the component exported in `routes/user/layout.tsx`. The `<Outlet>` in `routes/user/layout.tsx` represents the component exported in `routes/user/page.tsx`, generating the following UI structure:
106
136
 
107
137
  ```tsx
108
138
  <Layout>
@@ -111,18 +141,17 @@ In order to facilitate the introduction of the relationship between `<Layout>` a
111
141
  </UserLayout>
112
142
  </Layout>
113
143
  ```
114
-
115
- In summary, if there is a `layout.tsx` in the file directory of the subroute, the `<Outlet>` in the previous `layout.tsx` is the `layout.tsx` under the file directory of the subroute, otherwise it is the `page.tsx` under the file directory of the subroute.
144
+ In summary, if there is a `layout.tsx` file under the sub-route's file directory, the `<Outlet>` in the parent `layout.tsx` will represent the `layout.tsx` in the sub-route file directory. Otherwise, it will represent the `page.tsx` in the sub-route file directory.
116
145
 
117
146
  #### Page
118
147
 
119
- All routes should end with the `<Page>` component. In the `page.tsx` file, if the developer introduces the `<Outlet>` component, it will have no effect.
148
+ All routes should end with the `<Page>` component. If the developer introduces the `<Outlet>` component in the `page.tsx` file, there will be no effect.
120
149
 
121
- ### Dynamic routing
150
+ ### Dynamic Routing
122
151
 
123
- With a file directory named `[]`, the generated route will be used as a dynamic route. For example the following file directory:
152
+ Routes generated from file directories named with `[]` will be handled as dynamic routes. For example, the following file directory:
124
153
 
125
- ```
154
+ ```bash
126
155
  └── routes
127
156
  ├── [id]
128
157
  │ └── page.tsx
@@ -131,21 +160,43 @@ With a file directory named `[]`, the generated route will be used as a dynamic
131
160
  └── page.tsx
132
161
  ```
133
162
 
134
- The `routes/[id]/page.tsx` file is converted to the `/:id` route. Except for the `/blog` route that exactly matches, all other `/xxx` will match this route.
163
+ The `routes/[id]/page.tsx` file will be converted to the `/:id` route. Except for the exact matching `/blog` route, all other `/xxx` routes will match this route.
164
+
165
+ In the component, you can use [useParams](/apis/app/runtime/router/router#useparams) to get the corresponding named parameter.
166
+
167
+ In the loader, params will be passed as the input parameter of the [loader function](/guides/basic-features/data-fetch#loader-function), and you can get the parameter value through `params.xxx`.
168
+
169
+ ### Dynamic Optional Routing
170
+
171
+ Routes generated from file directories named with `[$]` will be treated as dynamic optional routes. For example, the following file directory:
172
+
173
+ ```bash
174
+ └── routes
175
+ ├── user
176
+ │ └── [id$]
177
+ │ └── page.tsx
178
+ ├── blog
179
+ │ └── page.tsx
180
+ └── page.tsx
181
+ ```
182
+
183
+ The `routes/user/[id$]/page.tsx` file will be converted to the `/user/:id?` route. All routes under `/user` will match this route, and the `id` parameter is optional. This route is usually used to distinguish between **creation** and **editing**.
184
+
185
+ In the component, you can use [useParams](/apis/app/runtime/router/router#useparams) to obtain the corresponding named parameter.
135
186
 
136
- In component, you can get the corresponding named parameters through [useParams](/apis/app/runtime/router/router#useparams).
187
+ In the loader, params will be passed as the input parameter of the [loader function](/guides/basic-features/data-fetch#loader-function), and you can get the parameter value through `params.xxx`.
137
188
 
138
- ### Catch all routing
189
+ ### Catch-all Routing
139
190
 
140
- If a `$.tsx` file is created in the routes directory, this file will act as a wildcard route component that will be rendered when there is no matching route.
191
+ If you create a `$.tsx` file under the routes directory, it will be treated as the catch-all routing component. When there is no matching route, this component will be rendered.
141
192
 
142
193
  :::note
143
- `$.tsx` can be thought of as a special `page` routing component that renders `$.tsx` as a child of `layout` when there is a `layout` component in the current directory.
194
+ `$.tsx` can be considered as a special `page` route component. When there is a `layout` component in the current directory, `$.tsx` will be rendered as a child component of `layout`.
144
195
  :::
145
196
 
146
197
  For example, the following directory structure:
147
198
 
148
- ```
199
+ ```bash
149
200
  └── routes
150
201
  ├── $.tsx
151
202
  ├── blog
@@ -153,7 +204,7 @@ For example, the following directory structure:
153
204
  └── page.tsx
154
205
  ```
155
206
 
156
- The `routes/$.tsx` component is rendered when accessing any path that does not match, and again, the remainder of the url can be captured in `$.tsx` using [useParams](/apis/app/runtime/router/router#useparams).
207
+ When accessing any path that does not match, the `routes/$.tsx` component will be rendered. Similarly, you can use [useParams](/apis/app/runtime/router/router#useparams) in `$.tsx` to capture the remaining parts of the URL.
157
208
 
158
209
  ```ts title="$.tsx"
159
210
  import { useParams } from '@modern-js/runtime/router';
@@ -162,11 +213,11 @@ const params = useParams();
162
213
  params['*']; // => 'aaa/bbb'
163
214
  ```
164
215
 
165
- ### Layout with No Path
216
+ ### No-path Layout
166
217
 
167
- When a directory name begins with `__`, the corresponding directory name is not converted to the actual routing path, such as the following file directory:
218
+ When the directory name starts with `__`, the corresponding directory name will not be converted to an actual route path. For example, the following file directory:
168
219
 
169
- ```
220
+ ```bash
170
221
  .
171
222
  └── routes
172
223
  ├── __auth
@@ -179,17 +230,17 @@ When a directory name begins with `__`, the corresponding directory name is not
179
230
  └── page.tsx
180
231
  ```
181
232
 
182
- Modern.js will generate two routes, `/login` and `/sign`, `__auth/layout.tsx` component will be used as the layout component of `login/page.tsx` and `signup/page.tsx`, but `__auth` will not be used as the route path fragment.
233
+ Modern.js will generate two routes, `/login` and `/signup`. The `__auth/layout.tsx` component will serve as the layout component for `login/page.tsx` and `signup/page.tsx`, but `__auth` will not be a route path segment.
183
234
 
184
- This feature is useful when you need to do separate layouts for certain types of routes, or when you want to categorize routes.
235
+ This feature is very useful when you need to create independent layouts for certain types of routes or want to classify routes.
185
236
 
186
237
  ### No Layout
187
238
 
188
- In some cases, the project needs more sophisticated routes, but these routes do not have independent UI layouts. If you create a route like a normal file directory, the directory level will be deeper.
239
+ In some cases, the project requires complex routing, but these routes do not have independent UI layouts. If you create routes like ordinary file directories, it will result in deep directory levels.
189
240
 
190
- Therefore Modern.js supports splitting routing fragments by `.` instead of file directory. For example, when you need `/user/profile/2022/edit`, you can directly create the following file:
241
+ Therefore, Modern.js supports using `.` to separate route segments instead of file directories. For example, when you need `/user/profile/2022/edit`, you can directly create the following files:
191
242
 
192
- ```
243
+ ```bash
193
244
  └── routes
194
245
  ├── user.profile.[id].edit
195
246
  │ └── page.tsx
@@ -197,7 +248,7 @@ Therefore Modern.js supports splitting routing fragments by `.` instead of file
197
248
  └── page.tsx
198
249
  ```
199
250
 
200
- When accessing a route, you will get the following UI layout:
251
+ When accessing the route, you will get the following UI layout:
201
252
 
202
253
  ```tsx
203
254
  <RootLayout>
@@ -207,9 +258,9 @@ When accessing a route, you will get the following UI layout:
207
258
 
208
259
  ### (WIP)Loading
209
260
 
210
- In each layer directory under `routes/`, developers can create `loading.tsx` files and export a `<Loading>` component by default.
261
+ In each directory under `routes/`, developers can create a `loading.tsx` file that exports a `<Loading>` component by default.
211
262
 
212
- When the component exists in the routing directory, all routing switches under this level of subrouting will use the `<Loading>` component as the Fallback UI when JS Chunk is loaded. When the `layout.tsx` file is not defined in this directory, the `<Loading>` component will not take effect. For example, the following file directory:
263
+ When this component and the `layout` component exist in the route directory, the `<Loading>` component will be used as the fallback UI when switching routes in this sub-route. For example, the following file directory:
213
264
 
214
265
  ```bash
215
266
  .
@@ -223,11 +274,50 @@ When the component exists in the routing directory, all routing switches under t
223
274
  └── page.tsx
224
275
  ```
225
276
 
226
- When a route jumps from `/` to `/blog`, if the JS Chunk of the `<Blog>` component is not loaded, the component UI exported in `loading.tsx` will be displayed first. But when jumping from `/blog` to `/blog/20220101`, it will not be displayed.
277
+ When defining `loading.tsx`, it is equivalent to the following layout:
278
+
279
+ When the route is `/`:
280
+
281
+ ```tsx
282
+ <Layout>
283
+ <Suspense fallback={<Loading />}>
284
+ <Page />
285
+ </Suspense>
286
+ </Layout>
287
+ ```
288
+
289
+ When the route is `/blog`:
290
+
291
+ ```tsx
292
+ <Layout>
293
+ <Suspense fallback={<Loading />}>
294
+ <BlogPage />
295
+ </Suspense>
296
+ </Layout>
297
+ ```
298
+
299
+ When the route is `/blog/123`:
300
+
301
+ ```tsx
302
+ <Layout>
303
+ <Suspense fallback={<Loading />}>
304
+ <BlogIdPage />
305
+ </Suspense>
306
+ </Layout>
307
+ ```
308
+
309
+ :::info
310
+ When the Layout component does not exist in the directory, the Loading component in that directory will not take effect. Modern.js recommends having a root Layout and root Loading.
311
+
312
+ :::
313
+
314
+ When the route jumps from `/` to `/blog`, if the JS Chunk of the `blog/page` component has not been loaded yet, the UI of the component exported in `loading.tsx` will be displayed first.
315
+
316
+ Similarly, when the route jumps from `/` or `/blog` to `/blog/123`, if the JS Chunk of the `blog/[id]/page` component has not been loaded yet, the UI of the component exported in `loading.tsx` will be displayed first.
227
317
 
228
318
  ### Redirect
229
319
 
230
- You can redirect routes by creating a [`data loader`](/guides/basic-features/data-fetch) file, Suppose you have the file `routes/user/page.tsx` and you want to redirect the route corresponding to this file, you can create the file `routes/user/page.loader.ts`:
320
+ You can use a [Data Loader](/guides/basic-features/data-fetch) file to redirect a route. For example, if you have a `routes/user/page.tsx` file and want to redirect the corresponding route, you can create a `routes/user/page.loader.ts` file:
231
321
 
232
322
  ```ts title="routes/user/page.loader.ts"
233
323
  import { redirect } from '@modern-js/runtime/router';
@@ -243,15 +333,13 @@ export default () => {
243
333
 
244
334
  ### ErrorBoundary
245
335
 
246
- In each layer directory under `routes/`, the developer can also define a `error.tsx` file, and export a `<ErrorBoundary>` component by default.
247
-
248
- When the component exists in a routing directory, the component render error is caught by the `ErrorBoundary` component. The `<ErrorBoundary>` component does not take effect when the directory does not have a `layout.tsx` file defined.
336
+ In each directory under `routes/`, developers can also define an `error.tsx` file that exports an `<ErrorBoundary>` component by default.
249
337
 
250
- `<ErrorBoundary>` can return the UI view when the error occurred. When the `<ErrorBoundary>` component is not declared at the current level, the error will bubble up to the higher component until it is caught or throws an error. At the same time, when a component fails, it will only affect the routed component and sub-component that caught the error. The state and view of other components are not affected and can continue to interact.
338
+ When this component exists in the routes directory, any rendering errors will be caught by the `ErrorBoundary` component. When the `layout.tsx` file is not defined in the directory, the `<ErrorBoundary>` component will not take effect.
251
339
 
252
- {/* Todo API 路由 */}
340
+ `<ErrorBoundary>` can return the UI view when an error occurs. When the `<ErrorBoundary>` component is not declared in the current level, the error will bubble up to a higher-level component until it is caught or thrown. At the same time, when a component has an error, it will only affect the route component and its child components that catch the error. The status and view of other components are not affected and can continue to interact.
253
341
 
254
- Within the `<ErrorBoundary>` component, you can use [useRouteError](/apis/app/runtime/router/router#useparams) to get the specific information of the error:
342
+ In the `<ErrorBoundary>` component, you can use [useRouteError](/apis/app/runtime/router/router#userouteerror) to get specific information about the error:
255
343
 
256
344
  ```tsx
257
345
  import { useRouteError } from '@modern-js/runtime/router';
@@ -266,9 +354,34 @@ export const ErrorBoundary = () => {
266
354
  };
267
355
  ```
268
356
 
269
- ### Hooks before rendering
357
+ ### Runtime Configuration
358
+
359
+ In each root `Layout` component (`routes/layout.ts`), you can dynamically define runtime configuration:
360
+
361
+
362
+ ```tsx title="src/routes/layout.tsx"
363
+ // Define runtime config
364
+ import type { AppConfig } from '@modern-js/runtime';
365
+
366
+ export const config = (): AppConfig => {
367
+ return {
368
+ router: {
369
+ createRoutes() {
370
+ return [
371
+ {
372
+ path: 'modern',
373
+ element: <div>modern</div>,
374
+ },
375
+ ];
376
+ },
377
+ },
378
+ };
379
+ };
380
+ ```
381
+
382
+ ### Hooks Before Rendering
270
383
 
271
- In some scenarios where you need to do some operations before the application renders, you can define `init` hooks in `routes/layout.tsx`. `init` will be executed on both the client and server side, the basic usage example is as follows:
384
+ In some scenarios, you may need to perform some operations before rendering the application. You can define an `init` hook in `routes/layout.tsx`. The `init` hook will be executed on both the client and server side. A basic example of usage is as follows:
272
385
 
273
386
  ```ts title="src/routes/layout.tsx"
274
387
  import type { RuntimeContext } from '@modern-js/runtime';
@@ -278,11 +391,10 @@ export const init = (context: RuntimeContext) => {
278
391
  };
279
392
  ```
280
393
 
281
- The `init` hook allows you to mount some global data and access the `runtimeContext` variable from elsewhere in the application:
394
+ By using the `init` hook, you can mount some global data, and the `runtimeContext` variable can be accessed in other parts of the application:
282
395
 
283
396
  :::note
284
- This feature is useful when the application requires pre-page data, custom data injection or framework migration (e.g. Next.js)
285
-
397
+ This feature is very useful when the application needs pre-rendered data, custom data injection, or framework migration (such as Next.js).
286
398
  :::
287
399
 
288
400
  ```ts title="src/routes/layout.tsx"
@@ -306,7 +418,7 @@ export default () => {
306
418
  };
307
419
  ```
308
420
 
309
- When working with SSR, the browser side can get the data returned by `init` during SSR, and the developer can decide whether to retrieve the data on the browser side to overwrite the SSR data, for example:
421
+ When used with the SSR feature, the data returned by the `init` hook during SSR can be obtained on the client side. Developers can decide whether to re-fetch data on the client side to overwrite the SSR data. For example:
310
422
 
311
423
  ```tsx title="src/routes/layout.tsx"
312
424
  import { RuntimeContext } from '@modern-js/runtime';
@@ -329,51 +441,37 @@ export const init = (context: RuntimeContext) => {
329
441
  };
330
442
  ```
331
443
 
332
- ### Runtime Configuration
333
-
334
- In each root `Layout` component (`routes/layout.ts`), the application runtime configuration can be dynamically defined:
335
-
336
- ```ts title="src/routes/layout.tsx"
337
- import type { AppConfig } from '@modern-js/runtime';
444
+ ### Preloading
338
445
 
339
- export const config = (): AppConfig => {
340
- return {
341
- router: {
342
- supportHtml5History: false,
343
- },
344
- };
345
- };
346
- ```
347
-
348
- ### Prefetch
446
+ In conventional routing, Modern.js automatically splits routes into chunks based on the route. When a user visits a specific route, the corresponding chunk will be loaded automatically, effectively reducing the loading time of the initial screen.
349
447
 
350
- When using convention-based routing, Modern.js will automatically split chunks according to the route, and when the user accesses a specific route, the corresponding resources will be loaded automatically, which can effectively reduce the first screen loading time. However, this also brings a problem, when the user accesses a route, if the asset corresponding to that route is not yet loaded, a white screen will appear.
448
+ However, this also brings a problem: if the chunk corresponding to the route has not finished loading when the user visits the route, a white screen will appear.
351
449
 
352
- In this case you can show a custom `loading` component by defining a `loading` component before the static resource is loaded.
450
+ In this case, you can define a `Loading` component to display a custom `Loading` component before the static resources are loaded.
353
451
 
354
- To further improve the user experience and reduce time of loading, Modern.js supports defining the `prefetch` property on the Link component to load static resources and data in advance, with three optional values for the `prefetch` property:
452
+ To further improve the user experience and reduce loading time, Modern.js supports defining the `prefetch` attribute on the Link component to preload static resources and data. The `prefetch` attribute has three optional values:
355
453
 
356
- ```
454
+ ```tsx
357
455
  <Link prefetch="intent" to="page">
358
456
  ```
359
457
 
360
458
  :::info
361
- - This feature is currently only supported in Webpack projects, not in Rspack projects.
362
- - Prefetching of data will only prefetch the data returned from the data loader of the SSR project.
459
+ - This feature is currently only supported in Webpack projects and not yet supported in Rspack projects.
460
+ - Preloading data currently only preloads the data returned by the [Data Loader](/guides/basic-features/data-fetch) in SSR projects.
363
461
 
364
462
  :::
365
463
 
366
- - `none`, the default value, will not do prefetch, no additional behavior.
367
- - `intent`, the value we recommend for most scenarios, will automatically start loading the corresponding resources and the data defined in the data loader when you mouse over the Link, and will automatically unload it when the mouse is moved away. In our tests, even a direct click can reduce the loading time by about 200ms.
368
- - `render`, when the Link component renders, it will load the corresponding resources and the data defined in the data loader.
464
+ - `none`: default value, no prefetching, no additional behavior.
465
+ - `intent`: This is the value we recommend for most scenarios. When you hover over the Link, the corresponding chunk and data defined in the data loader will be loaded automatically. When you move the mouse away, the loading will be cancelled automatically. In our tests, even fast clicks can reduce loading time by about 200ms.
466
+ - `render`: The corresponding chunk and data defined in the Data Loader will be loaded when the Link component is rendered.
369
467
 
370
468
  #### FAQ
371
469
 
372
- 1. What is the difference between using `render` and not split chunks based on routes?
470
+ 1. What is the difference between using `render` and not splitting static resources based on the route?
373
471
 
374
- - With `render` you can specify which routes are loaded on the first screen, and you can control the rendering so that Link components are rendered only when they are in the visible area.
375
- - With `render`, static resources are loaded only when they are idle and do not hog the network with first-screen static resources.
376
- - When using server side rendering, data is also prefetched.
472
+ - By using `render`, you can specify which routes to load during the initial screen, and you can control the rendering so that only when the `Link` component enters the visible area, the `Link` component will be rendered.
473
+ - By using `render`, static resources will only be loaded when the system is idle, and will not compete with the static resources of the initial screen for network resources.
474
+ - In the SSR scenario, data will also be pre-fetched.
377
475
 
378
476
  import Motivation from '@site-docs-en/components/convention-routing-motivation'
379
477
 
@@ -383,9 +481,9 @@ import Practice from '@site-docs-en/components/routes-practice'
383
481
 
384
482
  <Practice/>
385
483
 
386
- ## Self-controlled routing
484
+ ## Self-controlled Routing
387
485
 
388
- With `src/App.tsx` as the agreed entry, Modern.js will not do additional operations with multiple routes, developers can use the React Router 6 API for development by themselves, for example:
486
+ With `src/App.tsx` as the convention for entry points, Modern.js will not perform any additional routing operations. Developers can use the API of [React Router 6](https://reactrouter.com/en/main) for development, for example:
389
487
 
390
488
  ```ts title="src/App.tsx"
391
489
  import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';
@@ -403,16 +501,14 @@ export default () => {
403
501
  ```
404
502
 
405
503
  :::note
406
- Modern.js has a series of resource loading and rendering optimizations to the default convention-based routing, and provides out-of-the-box SSR capabilities, when using self-directed routing, need to be packaged by the developer, and it is recommended that developers use convention-based routing.
504
+ Modern.js provides a series of optimizations for resource loading and rendering for conventional routing by default, and provides out-of-the-box SSR capabilities. When using self-controlled routing, developers need to encapsulate these capabilities themselves. It is recommended to use conventional routing.
407
505
  :::
408
506
 
409
- use self-controller routing, if the developer turns off the [`runtime.router`](/configure/app/runtime/router) configuration and uses `react-router-dom` directly, then you need to wrap the `Provider` according to the React Router documentation.
410
-
411
- ```tsx title="src/App.tsx"
507
+ When using self-controlled routing, if the developer turns off the [`runtime.router`](/configure/app/runtime/router) configuration and uses `react-router-dom` directly, they also need to wrap it according to the React Router documentation.
412
508
 
413
509
  ## Other
414
510
 
415
- By default, Modern.js turn on the built-in routing scheme, React Router.
511
+ By default, Modern.js will enable the built-in routing scheme, which is React Router.
416
512
 
417
513
  ```js
418
514
  export default defineConfig({
@@ -422,7 +518,7 @@ export default defineConfig({
422
518
  });
423
519
  ```
424
520
 
425
- Modern.js exposes the React Router API from the `@modern-js/runtime/router` namespace for developers to use, ensuring that developers and Modern.js use the same code. In addition, in this case, the React Router code will be packaged into JS products. If the project already has its own routing scheme, or does not need to use client routing, this feature can be turned off.
521
+ Modern.js exposes the API of React Router from the `@modern-js/runtime/router` namespace for developers to use, ensuring that developers and Modern.js use the same code. In addition, in this case, the React Router code will be bundled into the JS output. If the project already has its own routing scheme or does not need to use client-side routing, this feature can be turned off.
426
522
 
427
523
  ```js
428
524
  export default defineConfig({
@@ -260,9 +260,9 @@ export default (): CliPlugin => ({
260
260
  ### `afterDev`
261
261
 
262
262
  - Function: Tasks to be executed after the main process of `dev` command
263
- - Execution Stage: Executed after the project is started when running the `dev` command
263
+ - Execution Stage: It is executed after each compilation is completed when running the `dev` command
264
264
  - Hook Model: AsyncWorkflow
265
- - Type: `AsyncWorkflow<void, unknown>`
265
+ - Type: `AsyncWorkflow<{ isFirstCompile: boolean }, unknown>`
266
266
  - Usage Example:
267
267
 
268
268
  ```ts
@@ -279,6 +279,24 @@ export default (): CliPlugin => ({
279
279
  });
280
280
  ```
281
281
 
282
+ `afterDev` will be executed after each compilation is completed, you can use the `isFirstCompile` param to determine whether it is the first compilation:
283
+
284
+ ```ts
285
+ import type { CliPlugin } from '@modern-js/core';
286
+
287
+ export default (): CliPlugin => ({
288
+ setup(api) {
289
+ return {
290
+ afterDev: ({ isFirstCompile }) => {
291
+ if (isFirstCompile) {
292
+ // do something
293
+ }
294
+ },
295
+ };
296
+ },
297
+ });
298
+ ```
299
+
282
300
  ### `beforeCreateCompiler`
283
301
 
284
302
  - Function: Provides access to the Webpack configuration used to create the Webpack Compiler within middleware functions.
@@ -438,7 +456,7 @@ import type { CliPlugin } from '@modern-js/core';
438
456
  export default (): CliPlugin => ({
439
457
  setup(api) {
440
458
  return {
441
- modifyEntryImports({ entrypoint, exportStatement }) {
459
+ modifyEntryExport({ entrypoint, exportStatement }) {
442
460
  return {
443
461
  entrypoint,
444
462
  exportStatement: [`export const foo = 'test'`, exportStatement].join(
@@ -776,7 +794,7 @@ export default (): Plugin => ({
776
794
  );
777
795
  };
778
796
  return next({
779
- App: hoistNonReactStatics(AppWrapper, App)
797
+ App: hoistNonReactStatics(AppWrapper, App),
780
798
  });
781
799
  },
782
800
  };
@@ -106,6 +106,28 @@ function App() {
106
106
  }
107
107
  ```
108
108
 
109
+ ### useRouteError
110
+
111
+ ```ts
112
+ export declare function useRouteError(): unknown;
113
+ ```
114
+
115
+ `useRouteError` 返回离 ErrorBoundary 定义最近的路由渲染错误信息。
116
+
117
+ ```tsx
118
+ import { useRouteError } from '@modern-js/runtime/router';
119
+ const ErrorBoundary = () => {
120
+ const error = useRouteError();
121
+ return (
122
+ <div>
123
+ <h1>{error.status}</h1>
124
+ <h2>{error.message}</h2>
125
+ </div>
126
+ );
127
+ };
128
+ export default ErrorBoundary;
129
+ ```
130
+
109
131
  ## 组件
110
132
 
111
133
  ### Link