@modern-js/main-doc 2.67.4 → 2.67.5

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 (29) hide show
  1. package/docs/en/configure/app/plugins.mdx +13 -33
  2. package/docs/en/configure/app/runtime/master-app.mdx +1 -5
  3. package/docs/en/configure/app/runtime/plugins.mdx +58 -0
  4. package/docs/en/configure/app/usage.mdx +1 -1
  5. package/docs/en/guides/advanced-features/_meta.json +1 -0
  6. package/docs/en/guides/advanced-features/bff.mdx +1 -1
  7. package/docs/en/guides/advanced-features/compatibility.mdx +1 -1
  8. package/docs/en/guides/advanced-features/custom-server.mdx +218 -0
  9. package/docs/en/guides/advanced-features/page-performance/inline-assets.mdx +2 -0
  10. package/docs/en/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
  11. package/docs/en/guides/advanced-features/web-server.mdx +174 -1
  12. package/docs/en/guides/basic-features/data/data-fetch.mdx +2 -1
  13. package/docs/en/guides/basic-features/html.mdx +3 -3
  14. package/docs/en/guides/basic-features/render/ssr.mdx +2 -2
  15. package/docs/en/guides/concept/entries.mdx +1 -1
  16. package/docs/en/plugin/cli-plugins/api.mdx +6 -0
  17. package/docs/en/plugin/runtime-plugins/api.mdx +37 -12
  18. package/docs/en/tutorials/first-app/c05-loader.mdx +1 -1
  19. package/docs/zh/configure/app/plugins.mdx +3 -24
  20. package/docs/zh/configure/app/runtime/master-app.mdx +1 -5
  21. package/docs/zh/configure/app/runtime/plugins.mdx +58 -0
  22. package/docs/zh/configure/app/usage.mdx +1 -1
  23. package/docs/zh/guides/advanced-features/_meta.json +1 -0
  24. package/docs/zh/guides/advanced-features/custom-server.mdx +216 -0
  25. package/docs/zh/guides/advanced-features/web-server.mdx +174 -1
  26. package/docs/zh/plugin/cli-plugins/api.mdx +6 -0
  27. package/docs/zh/plugin/runtime-plugins/api.mdx +37 -12
  28. package/package.json +2 -2
  29. package/src/i18n/index.ts +1 -1
@@ -1,47 +1,27 @@
1
- ---
2
- sidebar_position: 9
3
- ---
4
-
5
1
  # plugins
6
2
 
7
3
  - **Type:** `CliPlugin[]`
8
4
  - **Default:** `[]`
9
5
 
10
- Used to configure custom Modern.js framework plugins.
11
-
12
- Refer to [How to Develop Plugins](/plugin/plugin-system) for how to write custom plugins.
6
+ Used to configure custom Modern.js framework CLI plugins. For information on how to create custom CLI plugins, please refer to [How to Write CLI Plugins](/plugin/introduction.html#cli-plugins).
13
7
 
14
8
  ## Note
15
9
 
16
- This option is used to configure framework plugins. If you need to configure other types of plugins, please choose the corresponding configuration method:
17
-
18
- - Use [builderPlugins](/configure/app/builder-plugins) to configure Rsbuild plugins.
19
- - Use [tools.bundlerChain](/configure/app/tools/bundler-chain) to configure Rspack or webpack plugins.
20
- - Use [tools.babel](/configure/app/tools/babel) to configure Babel plugins.
21
-
22
- ## Plugin types
23
-
24
- Modern.js has three types of plugins:
25
-
26
- - `CLI plugins`, applicable to local development, compilation and construction stages, can extend various capabilities in the command line and compilation stages.
27
- - `Server plugins`, applicable to the server.
28
- - `Runtime plugins`, applicable to the front-end runtime.
29
-
30
- Currently, Modern.js has opened up the ability to customize CLI plugins, and Server plugins and Runtime plugins will be opened up later.
31
-
32
- ## Plugin execution order
10
+ This option is **specifically for configuring framework CLI plugins**. If you need to configure other types of plugins, use the appropriate configuration method:
33
11
 
34
- By default, custom plugins are executed in the order of the `plugins` array, and the execution time of built-in Modern.js plugins is earlier than that of custom plugins.
12
+ - Use [builderPlugins](/configure/app/builder-plugins) for Rsbuild plugins.
13
+ - Use [tools.bundlerChain](/configure/app/tools/bundler-chain) for Rspack or webpack plugins.
14
+ - Use [tools.babel](/configure/app/tools/babel) for Babel plugins.
15
+ - Use the [plugins field in runtime config](/configure/app/runtime/plugins) for framework Runtime plugins.
35
16
 
36
- When the plugin sets options that control the order, such as `pre` and `post`, the execution order will be adjusted based on the declared fields. Refer to [Plugins Structure](/plugin/plugin-system) for more information.
37
17
 
38
- ## Example
18
+ ## Examples
39
19
 
40
- The following is an example of using CLI plugins.
20
+ Below are examples of using CLI plugins:
41
21
 
42
- ### Use plugins on npm
22
+ ### Using plugins from npm
43
23
 
44
- To use plugins from npm registry, you need to first install the plugins , and import them in `modern.config.ts`.
24
+ To use plugins from the npm registry, first install the plugins and then import them in your configuration:
45
25
 
46
26
  ```ts title="modern.config.ts"
47
27
  import { myPlugin } from 'my-plugin';
@@ -51,9 +31,9 @@ export default defineConfig({
51
31
  });
52
32
  ```
53
33
 
54
- ### Use local plugins
34
+ ### Using local plugins
55
35
 
56
- To use local plugins, import them directly using a relative path.
36
+ To use plugins from your local repository, import them directly using a relative path:
57
37
 
58
38
  ```ts title="modern.config.ts"
59
39
  import { myPlugin } from './config/plugin/myPlugin';
@@ -65,7 +45,7 @@ export default defineConfig({
65
45
 
66
46
  ### Plugin configuration
67
47
 
68
- If the plugin provides some custom configuration options, they can be passed in as parameters to the plugin function.
48
+ If a plugin provides custom configuration options, pass them as parameters to the plugin function:
69
49
 
70
50
  ```ts title="modern.config.ts"
71
51
  import { myPlugin } from 'my-plugin';
@@ -1,8 +1,4 @@
1
- ---
2
- title: masterApp
3
- ---
4
-
5
- # runtime.masterApp
1
+ # masterApp
6
2
 
7
3
  - **Type:** `Object`
8
4
 
@@ -0,0 +1,58 @@
1
+ # plugins
2
+
3
+ - **Type:** `RuntimePlugin[]`
4
+ - **Default:** `[]`
5
+
6
+ Used to configure custom Modern.js Runtime plugins. For details on how to create custom Runtime plugins, please refer to [How to Write Runtime Plugins](/plugin/introduction#runtime-plugins).
7
+
8
+ :::info
9
+
10
+ Runtime plugins must be configured in the `plugins` array within the `src/modern.runtime.ts` file.
11
+
12
+ :::
13
+
14
+ ## Examples
15
+
16
+ Here are examples demonstrating how to use Runtime plugins:
17
+
18
+ ### Using plugins from npm packages
19
+
20
+ To use plugins published on npm, first install them via your package manager, then import them into your configuration.
21
+
22
+ ```ts title="src/modern.runtime.ts"
23
+ import { defineRuntimeConfig } from '@modern-js/runtime';
24
+ import { myPlugin } from 'my-plugin';
25
+
26
+ export default defineRuntimeConfig({
27
+ plugins: [myPlugin()],
28
+ });
29
+ ```
30
+
31
+ ### Using local plugins
32
+
33
+ To use plugins from your local codebase, import them directly using relative paths.
34
+
35
+ ```ts title="src/modern.runtime.ts"
36
+ import { defineRuntimeConfig } from '@modern-js/runtime';
37
+ import { myPlugin } from './config/plugin/myPlugin';
38
+
39
+ export default defineRuntimeConfig({
40
+ plugins: [myPlugin()],
41
+ });
42
+ ```
43
+
44
+ ### Plugin configuration
45
+
46
+ If a plugin supports custom configuration options, you can provide them as arguments to the plugin function.
47
+
48
+ ```ts title="src/modern.runtime.ts"
49
+ import { defineRuntimeConfig } from '@modern-js/runtime';
50
+ import { myPlugin } from './config/plugin/myPlugin';
51
+
52
+ export default defineRuntimeConfig({
53
+ plugins: [myPlugin({
54
+ foo: 1,
55
+ bar: 2,
56
+ })],
57
+ });
58
+ ```
@@ -13,7 +13,7 @@ Modern.js does not support configuring the same configuration item in both `pack
13
13
 
14
14
  **Runtime configuration** can be configured in the `src/modern.runtime.(ts|js|mjs)` file.
15
15
 
16
- **Server Runtime configuration** can be configured in the `modern.server-runtime.config.(ts|js|mjs)` file in the root path.
16
+ **Server Runtime configuration** can be configured in the `server/modern.server.(ts|js|mjs)` file.
17
17
 
18
18
  ## Compile Configuration
19
19
 
@@ -23,5 +23,6 @@
23
23
  "label": "server-monitor",
24
24
  "collapsed": true
25
25
  },
26
+ "custom-server",
26
27
  "web-server"
27
28
  ]
@@ -6,7 +6,7 @@ title: BFF
6
6
 
7
7
  BFF (Backends for Frontends) is an architectural pattern primarily used to address issues of data aggregation in front-end and back-end collaboration. Under the BFF architecture, front-end applications do not communicate directly with backend services. Instead, they interact with backend services through a dedicated BFF middleware layer, custom-made for the front end.
8
8
 
9
- The main problems it to solve include:
9
+ The main problems it tries to solve include:
10
10
 
11
11
  - Aggregation, mapping, clipping, and proxying of lower-level APIs according to their own business needs.
12
12
  - Cache data for some specific scenarios to improve performance and thus improve user experience.
@@ -26,7 +26,7 @@ Please refer to [Rsbuild - Browserslist](https://rsbuild.dev/guide/advanced/brow
26
26
 
27
27
  ### Polyfill At Compile
28
28
 
29
- Modern.js defaults to importing corresponding polyfill code from [core-js] (https://github.com/zloirock/core-js) during compilation.
29
+ Modern.js defaults to importing corresponding polyfill code from [core-js](https://github.com/zloirock/core-js) during compilation.
30
30
 
31
31
  By default, the required Polyfill code will be introduced according to the settings of the Browserslist, so there is no need to worry about the Polyfill problem of the project source code and third-party dependencies, but because it contains some Polyfill code that is not used, the final bundle size may be increased.
32
32
 
@@ -0,0 +1,218 @@
1
+ ---
2
+ sidebar_position: 16
3
+ ---
4
+
5
+ # Custom Server
6
+
7
+ Modern.js encapsulates most server-side capabilities required by projects, typically eliminating the need for server-side development. However, in certain scenarios such as user authentication, request preprocessing, or adding page skeletons, custom server-side logic may still be necessary.
8
+
9
+ ## Custom Server Capabilities
10
+
11
+ Create the `server/modern.server.ts` file in the project directory, and you can add the following configurations to extend the Server:
12
+ - **Middleware**
13
+ - **Render Middleware**
14
+ - **Server Plugin**
15
+
16
+ In the **Plugin**, you can define **Middleware** and **RenderMiddleware**. The middleware loading process is illustrated in the following diagram:
17
+
18
+ <img
19
+ src="https://lf3-static.bytednsdoc.com/obj/eden-cn/10eh7nuhpenuhog/server-md-wf.png"
20
+ style={{ width: '100%', maxWidth: '540px' }}
21
+ />
22
+
23
+ ### Basic Configuration
24
+
25
+ ```ts title="server/modern.server.ts"
26
+ import { defineServerConfig } from '@modern-js/server-runtime';
27
+
28
+ export default defineServerConfig({
29
+ middlewares: [],
30
+ renderMiddlewares: [],
31
+ plugins: [],
32
+ });
33
+ ```
34
+
35
+
36
+ ### Type Definition
37
+
38
+ `defineServerConfig` type definition is as follows:
39
+
40
+ ```ts
41
+ import type { MiddlewareHandler } from 'hono';
42
+
43
+ type MiddlewareOrder = 'pre' | 'post' | 'default';
44
+ type MiddlewareObj = {
45
+ name: string;
46
+ path?: string;
47
+ method?: 'options' | 'get' | 'post' | 'put' | 'delete' | 'patch' | 'all';
48
+ handler: MiddlewareHandler | MiddlewareHandler[];
49
+ before?: Array<MiddlewareObj['name']>;
50
+ order?: MiddlewareOrder;
51
+ };
52
+ type ServerConfig = {
53
+ middlewares?: MiddlewareObj[];
54
+ renderMiddlewares?: MiddlewareObj[];
55
+ plugins?: (ServerPlugin | ServerPluginLegacy)[];
56
+ }
57
+ ```
58
+
59
+
60
+ ### Middleware
61
+
62
+ Middleware supports executing custom logic before and after the **request handling** and **page routing** processes in Modern.js services.
63
+ That is, if custom logic needs to handle both API routes and affect page routes, then Middleware is the obvious choice. If you only need to handle BFF API routes, this can be achieved by configuring the `path` to the BFF's `prefix`.
64
+
65
+ :::note
66
+ In the BFF scenario, BFF routing will only go through Middleware when the [runtime framework](/guides/advanced-features/bff/frameworks.html) is Hono.
67
+ :::
68
+
69
+ #### Using Posture
70
+
71
+ ```ts title="server/modern.server.ts"
72
+ import { defineServerConfig, type MiddlewareHandler } from '@modern-js/server-runtime';
73
+ import { getMonitors } from '@modern-js/runtime';
74
+
75
+ export const handler: MiddlewareHandler = async (c, next) => {
76
+ const monitors = getMonitors();
77
+ const start = Date.now();
78
+
79
+ await next();
80
+
81
+ const end = Date.now();
82
+ // Report Duration
83
+ monitors.timing('request_timing', end - start);
84
+ };
85
+
86
+ export default defineServerConfig({
87
+ middlewares: [
88
+ {
89
+ name: 'request-timing',
90
+ handler,
91
+ },
92
+ ],
93
+ });
94
+ ```
95
+
96
+ :::warning
97
+ You must execute the `next` function to proceed with the subsequent Middleware.
98
+ :::
99
+
100
+
101
+ ### RenderMiddleware
102
+
103
+ If you only need to handle the logic before and after page rendering, modern.js also provides rendering middleware.
104
+
105
+ #### Using Posture
106
+
107
+ ```ts title="server/modern.server.ts"
108
+ import { defineServerConfig, type MiddlewareHandler } from '@modern-js/server-runtime';
109
+
110
+ // Inject render performance metrics
111
+ const renderTiming: MiddlewareHandler = async (c, next) => {
112
+ const start = Date.now();
113
+
114
+ await next();
115
+
116
+ const end = Date.now();
117
+ c.res.headers.set('server-timing', `render; dur=${end - start}`);
118
+ };
119
+
120
+ // Modify the Response Body
121
+ const modifyResBody: MiddlewareHandler = async (c, next) => {
122
+ await next();
123
+
124
+ const { res } = c;
125
+ const text = await res.text();
126
+ const newText = text.replace('<body>', '<body> <h3>bytedance</h3>');
127
+
128
+ c.res = c.body(newText, {
129
+ status: res.status,
130
+ headers: res.headers,
131
+ });
132
+ };
133
+
134
+ export default defineServerConfig({
135
+ renderMiddlewares: [
136
+ {
137
+ name: 'render-timing',
138
+ handler: renderTiming,
139
+ },
140
+ {
141
+ name: 'modify-res-body',
142
+ handler: modifyResBody,
143
+ },
144
+ ],
145
+ });
146
+ ```
147
+
148
+
149
+ ### Plugin
150
+
151
+ Modern.js supports adding the aforementioned middleware and rendering middleware for the Server in custom plugins.
152
+
153
+ #### Using Posture
154
+
155
+
156
+ ```ts title="server/plugins/server.ts"
157
+ import type { ServerPluginLegacy } from '@modern-js/server-runtime';
158
+
159
+ export default (): ServerPluginLegacy => ({
160
+ name: 'serverPlugin',
161
+ setup(api) {
162
+ return {
163
+ prepare(serverConfig) {
164
+ const { middlewares, renderMiddlewares } = api.useAppContext();
165
+
166
+ // Inject server-side data for page dataLoader consumption
167
+ middlewares?.push({
168
+ name: 'server-plugin-middleware',
169
+ handler: async (c, next) => {
170
+ c.set('message', 'hi modern.js');
171
+ await next();
172
+ // ...
173
+ },
174
+ });
175
+
176
+ // redirect
177
+ renderMiddlewares?.push({
178
+ name: 'server-plugin-render-middleware',
179
+ handler: async (c, next) => {
180
+ const user = getUser(c.req);
181
+ if (!user) {
182
+ return c.redirect('/login');
183
+ }
184
+
185
+ await next();
186
+ },
187
+ });
188
+ return serverConfig;
189
+ },
190
+ };
191
+ },
192
+ });
193
+ ```
194
+
195
+
196
+ ```ts title="server/modern.server.ts"
197
+ import { defineServerConfig } from '@modern-js/server-runtime';
198
+ import serverPlugin from './plugins/serverPlugin';
199
+
200
+ export default defineServerConfig({
201
+ plugins: [serverPlugin()],
202
+ });
203
+ ```
204
+
205
+
206
+ ```ts title="src/routes/page.data.ts"
207
+ import { useHonoContext } from '@modern-js/server-runtime';
208
+ import { defer } from '@modern-js/runtime/router';
209
+
210
+ export default () => {
211
+ const ctx = useHonoContext();
212
+ // Consuming Data Injected by the Server-Side
213
+ const message = ctx.get('message');
214
+
215
+ // ...
216
+ };
217
+
218
+ ```
@@ -96,6 +96,8 @@ When you reference a static asset in your CSS file, you can also force the asset
96
96
  :::tip Do you really need to exclude assets from inlining?
97
97
  Excluding assets from inlining will increase the number of assets that the Web App needs to load. This will reduce the efficiency of loading assets in a weak network environment or in scenarios where HTTP2 is not enabled. Please use force no Inline with caution.
98
98
 
99
+ :::
100
+
99
101
  ## Inline JS files
100
102
 
101
103
  In addition to inlining static assets into JS files, Modern.js also supports inlining JS files into HTML files.
@@ -4,7 +4,7 @@ sidebar_position: 13
4
4
 
5
5
  # Bundle Size Optimization
6
6
 
7
- Bundle size optimization is an important part in production environment because it directly affects the user experience of online users. In this document, we will introduce some common bundle size optimization methods in Modern.js.
7
+ Bundle size optimization is an important part of optimizing your production environment because it directly affects the user experience. In this document, we will introduce some common bundle size optimization methods in Modern.js.
8
8
 
9
9
  ## Reduce duplicate dependencies
10
10
 
@@ -2,7 +2,11 @@
2
2
  sidebar_position: 16
3
3
  ---
4
4
 
5
- # Custom Web Server
5
+ # Custom Web Server (Not Recommended)
6
+
7
+ :::warning
8
+ Custom Web Server is compatible but no longer recommended. For extending Server capabilities, please refer to [Custom Server](/guides/advanced-features/custom-server.html). For migration guide, see [Migrate to the New Version of Custom Server](/guides/advanced-features/web-server.html#migrate-to-the-new-version-of-custom-server).
9
+ :::
6
10
 
7
11
  Modern.js encapsulates most server-side capabilities required by projects, typically eliminating the need for server-side development. However, in certain scenarios such as user authentication, request preprocessing, or adding page skeletons, custom server-side logic may still be necessary.
8
12
 
@@ -96,3 +100,172 @@ Best practices when using Hooks:
96
100
  :::info
97
101
  For detailed API and more usage, see [Hook](/apis/app/runtime/web-server/hook).
98
102
  :::
103
+
104
+
105
+ ## Migrate to the New Version of Custom Server
106
+
107
+ ### Migration Background
108
+
109
+ Modern.js Server is continuously evolving to provide more powerful features. We have optimized the definition and usage of middleware and Server plugins.
110
+ While the old custom Web Server approach is still compatible, we strongly recommend migrating according to this guide to fully leverage the advantages of the new version.
111
+
112
+ ### Migration Steps
113
+
114
+ 1. Upgrade Modern.js version to x.67.5 or above.
115
+ 2. Configure middleware or plugins in `server/modern.server.ts` according to the new definition method.
116
+ 3. Migrate the custom logic in `server/index.ts` to middleware or plugins, and update your code with reference to the differences between `Context` and `Next`.
117
+
118
+ ### Context Differences
119
+
120
+ In the new version, the middleware handler type is Hono's `MiddlewareHandler`, meaning the `Context` type is `Hono Context`. The differences from the old custom Web Server's `Context` are as follows:
121
+
122
+
123
+ #### UnstableMiddleware
124
+
125
+
126
+ ```ts
127
+ type Body = ReadableStream | ArrayBuffer | string | null;
128
+
129
+ type UnstableMiddlewareContext<
130
+ V extends Record<string, unknown> = Record<string, unknown>,
131
+ > = {
132
+ request: Request;
133
+ response: Response;
134
+ get: Get<V>;
135
+ set: Set<V>;
136
+ // Current Matched Routing Information
137
+ route: string;
138
+ header: (name: string, value: string, options?: { append?: boolean }) => void;
139
+ status: (code: number) => void;
140
+ redirect: (location: string, status?: number) => Response;
141
+ body: (data: Body, init?: ResponseInit) => Response;
142
+ html: (
143
+ data: string | Promise<string>,
144
+ init?: ResponseInit,
145
+ ) => Response | Promise<Response>;
146
+ };
147
+ ```
148
+
149
+ Differences between UnstableMiddleware Context and Hono Context:
150
+
151
+ | UnstableMiddleware | Hono | Description |
152
+ | :----------------------- | :---------------------------- | :------------------------------------------------------------------------ |
153
+ | `c.request` | `c.req.raw` | Refer to [HonoRequest raw](https://hono.dev/docs/api/request#raw) documentation |
154
+ | `c.response` | `c.res` | Refer to [Hono Context res](https://hono.dev/docs/api/context#res) documentation |
155
+ | `c.route` | `c.get('route')` | Get application context information. |
156
+ | `loaderContext.get` | `honoContext.get` | After injecting data using `c.set`, consume in dataLoader: the old version uses `loaderContext.get`, refer to the new version in [Plugin](/guides/advanced-features/custom-server.html#using-posture-2) example |
157
+
158
+
159
+ #### Middleware
160
+
161
+ ```ts
162
+ type MiddlewareContext = {
163
+ response: {
164
+ set: (key: string, value: string) => void;
165
+ status: (code: number) => void;
166
+ getStatus: () => number;
167
+ cookies: {
168
+ set: (key: string, value: string, options?: any) => void;
169
+ clear: () => void;
170
+ };
171
+ raw: (
172
+ body: string,
173
+ { status, headers }: { status: number; headers: Record<string, any> },
174
+ ) => void;
175
+ locals: Record<string, any>;
176
+ };
177
+ request: {
178
+ url: string;
179
+ host: string;
180
+ pathname: string;
181
+ query: Record<string, any>;
182
+ cookie: string;
183
+ cookies: {
184
+ get: (key: string) => string;
185
+ };
186
+ headers: IncomingHttpHeaders;
187
+ };
188
+ source: {
189
+ req: IncomingMessage;
190
+ res: ServerResponse;
191
+ };
192
+ };
193
+
194
+ ```
195
+
196
+ Differences between Middleware `Context` and Hono `Context`:
197
+ | UnstableMiddleware | Hono | Description |
198
+ | :----------------------- | :---------------------------- | :--------------------------------------------------------------------------- |
199
+ | `c.request.cookie` | `c.req.cookie()` | Refer to [Hono Cookie Helper](https://hono.dev/docs/helpers/cookie) documentation |
200
+ | `c.request.pathname` | `c.req.path` | Refer to [HonoRequest path](https://hono.dev/docs/api/request#path) documentation |
201
+ | `c.request.url` | - | Hono `c.req.url` provides the full request URL, calculate manually from URL |
202
+ | `c.request.host` | `c.req.header('Host')` | Obtain host through header |
203
+ | `c.request.query` | `c.req.query()` | Refer to [HonoRequest query](https://hono.dev/docs/api/request#query) documentation |
204
+ | `c.request.headers` | `c.req.header()` | Refer to [HonoRequest header](https://hono.dev/docs/api/request#header) documentation |
205
+ | `c.response.set` | `c.res.headers.set` | Example: `c.res.headers.set('custom-header', '1')` |
206
+ | `c.response.status` | `c.status` | Example: `c.status(201)` |
207
+ | `c.response.cookies` | `c.header` | Example: `c.header('Set-Cookie', 'user_id=123')` |
208
+ | `c.response.raw` | `c.res` | Refer to [Hono Context res](https://hono.dev/docs/api/context#res) documentation |
209
+
210
+ #### Hook
211
+
212
+ ```ts
213
+ type HookContext = {
214
+ response: {
215
+ set: (key: string, value: string) => void;
216
+ status: (code: number) => void;
217
+ getStatus: () => number;
218
+ cookies: {
219
+ set: (key: string, value: string, options?: any) => void;
220
+ clear: () => void;
221
+ };
222
+ raw: (
223
+ body: string,
224
+ { status, headers }: { status: number; headers: Record<string, any> },
225
+ ) => void;
226
+ };
227
+ request: {
228
+ url: string;
229
+ host: string;
230
+ pathname: string;
231
+ query: Record<string, any>;
232
+ cookie: string;
233
+ cookies: {
234
+ get: (key: string) => string;
235
+ };
236
+ headers: IncomingHttpHeaders;
237
+ };
238
+ };
239
+
240
+ type AfterMatchContext = HookContext & {
241
+ router: {
242
+ redirect: (url: string, status: number) => void;
243
+ rewrite: (entry: string) => void;
244
+ };
245
+ };
246
+
247
+ type AfterRenderContext = {
248
+ template: {
249
+ get: () => string;
250
+ set: (html: string) => void;
251
+ prependHead: (fragment: string) => void;
252
+ appendHead: (fragment: string) => void;
253
+ prependBody: (fragment: string) => void;
254
+ appendBody: (fragment: string) => void;
255
+ };
256
+ };
257
+ ```
258
+
259
+ Hook Context is mostly consistent with Middleware Context, so we need to pay extra attention to the additional parts of different Hooks.
260
+
261
+ | UnstableMiddleware | Hono | Description |
262
+ | :----------------------- | :---------------------------- | :------------------------------------ |
263
+ | `router.redirect` | `c.redirect` | Refer to [Hono Context redirect](https://hono.dev/docs/api/context#redirect) documentation |
264
+ | `router.rewrite` | - | No corresponding capability provided at the moment |
265
+ | template API | `c.res` | Refer to [Hono Context res](https://hono.dev/docs/api/context#res) documentation |
266
+
267
+
268
+ ### Differences in Next API
269
+
270
+ In Middleware and Hooks, the render function executes even without invoking `next`.
271
+ In the new design, subsequent Middleware will only execute if the `next` function is invoked.
@@ -149,9 +149,10 @@ Having the `loader` function run only on the server in SSR applications brings s
149
149
  - **Simplifies usage**: Guarantees consistent data-fetching methods in SSR applications, so developers don't have to distinguish between client and server code.
150
150
  - **Reduces client bundle size**: Moves logic code and dependencies from the client to the server.
151
151
  - **Improves maintainability**: Less direct influence of data logic on front-end UI and avoids issues of accidentally including server dependencies in the client bundle or vice versa.
152
+
152
153
  :::
153
154
 
154
- We recommend using the `fetch` API in `loader` functions to make requests. Modern.js provides a default polyfill for the `fetch` API, allowing it to be used on the server. This means you can fetch data in a consistent manner whether in CSR or SSR:
155
+ We recommend using the `fetch` API in `loader` functions to make requests. Since `fetch` works similarly on the client and server, you can fetch data in a consistent manner whether in CSR or SSR:
155
156
 
156
157
  ```tsx
157
158
  export async function loader() {
@@ -8,7 +8,7 @@ Modern.js provides **JSX syntax** and **HTML(EJS) syntax** to customize the HTML
8
8
 
9
9
  ## JSX Syntax
10
10
 
11
- According to Modern.js conventions, you can create a `Document.[jt]sx` file under `src/` or the entry directory and default export a component". The rendering result of this component can be used as the HTML template of the entry.
11
+ According to Modern.js conventions, you can create a `Document.[jt]sx` file under `src/` or the entry directory and default export a component. The rendering result of this component can be used as the HTML template of the entry.
12
12
 
13
13
  For example, consider the following directory structure:
14
14
 
@@ -218,9 +218,9 @@ The implementation of custom HTML fragments is to merge the fragments with the b
218
218
 
219
219
  :::
220
220
 
221
- ### Custom the entire HTML Template
221
+ ### Customize the entire HTML Template
222
222
 
223
- In some cases, HTML fragments may be is not better meet the customization requirements. Modern.js provides a fully customized way.
223
+ In some cases, HTML fragments may not offer enough control. Modern.js provides a fully customized way.
224
224
 
225
225
  :::caution Note
226
226
  It is generally not recommended to directly override the default HTML template, as some functional options may be lost. If it is truly necessary to customize the entire HTML template, it is recommended to modify based on the built-in template as needed.
@@ -1,6 +1,6 @@
1
1
  # Server-Side Rendering
2
2
 
3
- Server-Side Rendering (SSR) involves rendering the HTML content of a webpage-side and then sending the fully-rendered page to the browser. The browser only needs to display the page without additional rendering.
3
+ Server-Side Rendering (SSR) involves rendering the HTML content of a webpage server-side and then sending the fully-rendered page to the browser. The browser only needs to display the page without additional rendering.
4
4
 
5
5
  The main advantages are:
6
6
 
@@ -320,4 +320,4 @@ In this case, the `epicMiddleware` instance is created outside the component, an
320
320
 
321
321
  This code does not cause issues on the client-side. However, in SSR, the Middleware instance remains non-disposable. Each time the component renders, calling `epicMiddleware.run(rootEpic)` adds new event bindings internally, causing the entire object to grow continuously, ultimately affecting application performance.
322
322
 
323
- Such issues are not easily noticed in CSR. When transitioning from CSR to SSR, if you're unsure whether your application has such hidden pitfalls, consider stress testing the application.
323
+ Such issues are not easily noticed in CSR. When transitioning from CSR to SSR, if you're unsure whether your application has such hidden pitfalls, consider stress testing the application.
@@ -76,7 +76,7 @@ By default, Modern.js scans the files under `src/` before starting the project,
76
76
 
77
77
  :::tip
78
78
 
79
- - You can custom the recognition directory for page entries by using [source.entriesDir](/configure/app/source/entries-dir).
79
+ - You can customize the recognition directory for page entries by using [source.entriesDir](/configure/app/source/entries-dir).
80
80
  - If you need to customize the entry points, please refer to [Custom Entries](#custom-entries).
81
81
 
82
82
  :::