@modern-js/main-doc 3.9.3 → 3.10.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.
Files changed (197) hide show
  1. package/docs/en/apis/app/hooks/api/lambda.mdx +2 -1
  2. package/docs/en/apis/app/hooks/config/html.mdx +1 -0
  3. package/docs/en/apis/app/hooks/config/mock.mdx +1 -0
  4. package/docs/en/apis/app/hooks/config/public.mdx +1 -0
  5. package/docs/en/apis/app/hooks/config/upload.mdx +2 -3
  6. package/docs/en/apis/app/hooks/modern-config.mdx +1 -0
  7. package/docs/en/apis/app/hooks/shared.mdx +1 -0
  8. package/docs/en/apis/app/hooks/src/modern.runtime.mdx +1 -0
  9. package/docs/en/apis/app/hooks/src/routes.mdx +1 -0
  10. package/docs/en/apis/app/hooks/src/server.mdx +2 -1
  11. package/docs/en/apis/app/runtime/bff/use-hono-context.mdx +1 -0
  12. package/docs/en/apis/app/runtime/core/create-root.mdx +4 -1
  13. package/docs/en/apis/app/runtime/core/render.mdx +6 -2
  14. package/docs/en/apis/app/runtime/core/runtime-context.mdx +17 -17
  15. package/docs/en/apis/app/runtime/router/router.mdx +9 -6
  16. package/docs/en/apis/app/runtime/ssr/no-ssr.mdx +1 -0
  17. package/docs/en/apis/app/runtime/utility/head.mdx +1 -0
  18. package/docs/en/apis/app/runtime/utility/loadable.mdx +1 -0
  19. package/docs/en/community/blog/v3-release-note.mdx +36 -27
  20. package/docs/en/community/contributing-guide.mdx +15 -33
  21. package/docs/en/components/default-browserslist.mdx +0 -1
  22. package/docs/en/components/deploy-command.mdx +1 -1
  23. package/docs/en/components/deploy.mdx +1 -1
  24. package/docs/en/components/entry-scan-logic.mdx +1 -1
  25. package/docs/en/components/init-app.mdx +9 -3
  26. package/docs/en/components/international/custom-instance-code.mdx +0 -1
  27. package/docs/en/components/micro-runtime-config.mdx +12 -9
  28. package/docs/en/components/nodeVersion.mdx +2 -2
  29. package/docs/en/components/rsc-deploy-tip.mdx +0 -1
  30. package/docs/en/components/ssr-monitor.mdx +1 -1
  31. package/docs/en/configure/app/bff/cross-project.mdx +2 -2
  32. package/docs/en/configure/app/bff/prefix.mdx +1 -1
  33. package/docs/en/configure/app/dev/lazy-compilation.mdx +17 -1
  34. package/docs/en/configure/app/dev/start-url.mdx +0 -1
  35. package/docs/en/configure/app/output/css-modules.mdx +1 -5
  36. package/docs/en/configure/app/output/dist-path.mdx +0 -1
  37. package/docs/en/configure/app/output/inline-scripts.mdx +1 -2
  38. package/docs/en/configure/app/output/inline-styles.mdx +1 -2
  39. package/docs/en/configure/app/output/split-route-chunks.mdx +1 -1
  40. package/docs/en/configure/app/output/ssg.mdx +1 -1
  41. package/docs/en/configure/app/output/ssgByEntries.mdx +1 -0
  42. package/docs/en/configure/app/performance/chunk-split.mdx +1 -4
  43. package/docs/en/configure/app/runtime/plugins.mdx +6 -4
  44. package/docs/en/configure/app/server/rsc.mdx +1 -1
  45. package/docs/en/configure/app/server/ssr.mdx +7 -8
  46. package/docs/en/configure/app/server/tsconfig-path.mdx +2 -2
  47. package/docs/en/configure/app/tools/less.mdx +5 -6
  48. package/docs/en/configure/app/tools/sass.mdx +5 -6
  49. package/docs/en/configure/app/tools/svgr.mdx +7 -7
  50. package/docs/en/configure/app/usage.mdx +1 -5
  51. package/docs/en/guides/advanced-features/bff/cross-project.mdx +5 -4
  52. package/docs/en/guides/advanced-features/compatibility.mdx +0 -1
  53. package/docs/en/guides/advanced-features/international/advanced.mdx +1 -1
  54. package/docs/en/guides/advanced-features/international/api.mdx +34 -28
  55. package/docs/en/guides/advanced-features/international/best-practices.mdx +15 -15
  56. package/docs/en/guides/advanced-features/international/configuration.mdx +37 -37
  57. package/docs/en/guides/advanced-features/international/locale-detection.mdx +37 -28
  58. package/docs/en/guides/advanced-features/international/resource-loading.mdx +19 -17
  59. package/docs/en/guides/advanced-features/international/routing.mdx +8 -6
  60. package/docs/en/guides/advanced-features/international.mdx +8 -8
  61. package/docs/en/guides/advanced-features/server-monitor/logger.mdx +5 -5
  62. package/docs/en/guides/advanced-features/server-monitor/metrics.mdx +8 -8
  63. package/docs/en/guides/advanced-features/server-monitor/monitors.mdx +1 -3
  64. package/docs/en/guides/advanced-features/source-build.mdx +1 -1
  65. package/docs/en/guides/advanced-features/web-server.mdx +3 -3
  66. package/docs/en/guides/basic-features/data/data-fetch.mdx +1 -3
  67. package/docs/en/guides/basic-features/data/data-write.mdx +24 -28
  68. package/docs/en/guides/basic-features/debug/mock.mdx +2 -2
  69. package/docs/en/guides/basic-features/debug/using-storybook.mdx +5 -6
  70. package/docs/en/guides/basic-features/html.mdx +2 -3
  71. package/docs/en/guides/basic-features/output-files.mdx +1 -1
  72. package/docs/en/guides/basic-features/render/overview.mdx +12 -12
  73. package/docs/en/guides/basic-features/render/rsc.mdx +16 -9
  74. package/docs/en/guides/basic-features/render/ssr-cache.mdx +5 -5
  75. package/docs/en/guides/basic-features/render/ssr.mdx +8 -12
  76. package/docs/en/guides/basic-features/render/streaming-ssr.mdx +2 -1
  77. package/docs/en/guides/basic-features/routes/config-routes.mdx +60 -59
  78. package/docs/en/guides/basic-features/testing/playwright.mdx +14 -8
  79. package/docs/en/guides/basic-features/testing/rstest.mdx +6 -4
  80. package/docs/en/guides/get-started/ai-coding-agents.mdx +6 -6
  81. package/docs/en/guides/get-started/introduction.mdx +0 -1
  82. package/docs/en/guides/topic-detail/module-federation/deploy.mdx +2 -2
  83. package/docs/en/guides/topic-detail/module-federation/introduce.mdx +0 -1
  84. package/docs/en/guides/upgrade/config.mdx +12 -0
  85. package/docs/en/guides/upgrade/other.mdx +4 -4
  86. package/docs/en/guides/upgrade/tailwindcss.mdx +0 -1
  87. package/docs/en/guides/upgrade/web-server.md +34 -17
  88. package/docs/en/index.md +1 -0
  89. package/docs/en/plugin/cli-plugins/api.mdx +23 -23
  90. package/docs/en/plugin/cli-plugins/life-cycle.mdx +2 -0
  91. package/docs/en/plugin/introduction.mdx +6 -6
  92. package/docs/en/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
  93. package/docs/en/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
  94. package/docs/en/plugin/plugin-system.mdx +19 -26
  95. package/docs/en/plugin/runtime-plugins/life-cycle.mdx +2 -0
  96. package/docs/en/plugin/server-plugins/api.mdx +11 -14
  97. package/docs/en/plugin/server-plugins/life-cycle.mdx +2 -0
  98. package/docs/zh/apis/app/hooks/api/lambda.mdx +1 -1
  99. package/docs/zh/apis/app/hooks/config/html.mdx +1 -0
  100. package/docs/zh/apis/app/hooks/config/mock.mdx +1 -0
  101. package/docs/zh/apis/app/hooks/config/public.mdx +1 -0
  102. package/docs/zh/apis/app/hooks/config/upload.mdx +2 -3
  103. package/docs/zh/apis/app/hooks/modern-config.mdx +1 -0
  104. package/docs/zh/apis/app/hooks/shared.mdx +1 -0
  105. package/docs/zh/apis/app/hooks/src/modern.runtime.mdx +1 -0
  106. package/docs/zh/apis/app/hooks/src/routes.mdx +1 -0
  107. package/docs/zh/apis/app/hooks/src/server.mdx +2 -1
  108. package/docs/zh/apis/app/runtime/bff/use-hono-context.mdx +1 -1
  109. package/docs/zh/apis/app/runtime/core/create-root.mdx +4 -1
  110. package/docs/zh/apis/app/runtime/core/render.mdx +6 -3
  111. package/docs/zh/apis/app/runtime/core/runtime-context.mdx +17 -17
  112. package/docs/zh/apis/app/runtime/router/router.mdx +10 -6
  113. package/docs/zh/apis/app/runtime/ssr/no-ssr.mdx +1 -0
  114. package/docs/zh/apis/app/runtime/utility/head.mdx +1 -0
  115. package/docs/zh/apis/app/runtime/utility/loadable.mdx +1 -0
  116. package/docs/zh/community/blog/v3-release-note.mdx +38 -29
  117. package/docs/zh/community/contributing-guide.mdx +16 -34
  118. package/docs/zh/components/default-browserslist.mdx +0 -1
  119. package/docs/zh/components/deploy-command.mdx +1 -1
  120. package/docs/zh/components/deploy.mdx +1 -1
  121. package/docs/zh/components/entry-scan-logic.mdx +1 -1
  122. package/docs/zh/components/init-app.mdx +9 -3
  123. package/docs/zh/components/international/custom-instance-code.mdx +0 -1
  124. package/docs/zh/components/international/install-command.mdx +0 -1
  125. package/docs/zh/components/micro-runtime-config.mdx +12 -9
  126. package/docs/zh/components/nodeVersion.mdx +2 -2
  127. package/docs/zh/components/rsc-deploy-tip.mdx +0 -1
  128. package/docs/zh/components/ssr-monitor.mdx +1 -1
  129. package/docs/zh/configure/app/bff/cross-project.mdx +2 -2
  130. package/docs/zh/configure/app/bff/prefix.mdx +1 -1
  131. package/docs/zh/configure/app/dev/lazy-compilation.mdx +17 -1
  132. package/docs/zh/configure/app/html/crossorigin.mdx +0 -1
  133. package/docs/zh/configure/app/html/favicon.mdx +0 -1
  134. package/docs/zh/configure/app/output/convert-to-rem.mdx +0 -1
  135. package/docs/zh/configure/app/output/css-modules.mdx +1 -5
  136. package/docs/zh/configure/app/output/inline-scripts.mdx +1 -2
  137. package/docs/zh/configure/app/output/inline-styles.mdx +1 -2
  138. package/docs/zh/configure/app/output/source-map.mdx +0 -2
  139. package/docs/zh/configure/app/output/split-route-chunks.mdx +1 -1
  140. package/docs/zh/configure/app/output/ssg.mdx +1 -0
  141. package/docs/zh/configure/app/output/ssgByEntries.mdx +1 -1
  142. package/docs/zh/configure/app/performance/chunk-split.mdx +1 -4
  143. package/docs/zh/configure/app/resolve/dedupe.mdx +0 -1
  144. package/docs/zh/configure/app/runtime/plugins.mdx +6 -4
  145. package/docs/zh/configure/app/server/rsc.mdx +1 -1
  146. package/docs/zh/configure/app/server/ssr.mdx +6 -7
  147. package/docs/zh/configure/app/server/tsconfig-path.mdx +2 -2
  148. package/docs/zh/configure/app/tools/less.mdx +6 -7
  149. package/docs/zh/configure/app/tools/sass.mdx +6 -7
  150. package/docs/zh/configure/app/tools/svgr.mdx +11 -11
  151. package/docs/zh/configure/app/usage.mdx +1 -5
  152. package/docs/zh/guides/advanced-features/bff.mdx +1 -0
  153. package/docs/zh/guides/advanced-features/international/advanced.mdx +1 -1
  154. package/docs/zh/guides/advanced-features/international/api.mdx +28 -27
  155. package/docs/zh/guides/advanced-features/international/best-practices.mdx +15 -15
  156. package/docs/zh/guides/advanced-features/international/configuration.mdx +38 -36
  157. package/docs/zh/guides/advanced-features/international/locale-detection.mdx +37 -28
  158. package/docs/zh/guides/advanced-features/international/resource-loading.mdx +20 -16
  159. package/docs/zh/guides/advanced-features/international/routing.mdx +6 -4
  160. package/docs/zh/guides/advanced-features/international.mdx +9 -9
  161. package/docs/zh/guides/advanced-features/server-monitor/logger.mdx +4 -6
  162. package/docs/zh/guides/advanced-features/server-monitor/metrics.mdx +9 -10
  163. package/docs/zh/guides/advanced-features/source-build.mdx +1 -1
  164. package/docs/zh/guides/advanced-features/web-server.mdx +3 -3
  165. package/docs/zh/guides/basic-features/data/data-fetch.mdx +1 -3
  166. package/docs/zh/guides/basic-features/data/data-write.mdx +25 -31
  167. package/docs/zh/guides/basic-features/debug/mock.mdx +2 -2
  168. package/docs/zh/guides/basic-features/debug/using-storybook.mdx +5 -5
  169. package/docs/zh/guides/basic-features/env-vars.mdx +0 -1
  170. package/docs/zh/guides/basic-features/html.mdx +2 -3
  171. package/docs/zh/guides/basic-features/render/overview.mdx +12 -13
  172. package/docs/zh/guides/basic-features/render/rsc.mdx +16 -9
  173. package/docs/zh/guides/basic-features/render/ssr.mdx +8 -17
  174. package/docs/zh/guides/basic-features/routes/config-routes.mdx +61 -59
  175. package/docs/zh/guides/basic-features/testing/playwright.mdx +15 -10
  176. package/docs/zh/guides/basic-features/testing/rstest.mdx +6 -4
  177. package/docs/zh/guides/get-started/ai-coding-agents.mdx +7 -7
  178. package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +2 -2
  179. package/docs/zh/guides/upgrade/config.mdx +12 -0
  180. package/docs/zh/guides/upgrade/other.md +4 -11
  181. package/docs/zh/guides/upgrade/overview.mdx +1 -4
  182. package/docs/zh/guides/upgrade/tailwindcss.mdx +0 -1
  183. package/docs/zh/guides/upgrade/web-server.md +34 -19
  184. package/docs/zh/index.md +1 -0
  185. package/docs/zh/plugin/cli-plugins/api.mdx +24 -24
  186. package/docs/zh/plugin/cli-plugins/life-cycle.mdx +2 -0
  187. package/docs/zh/plugin/introduction.mdx +6 -6
  188. package/docs/zh/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
  189. package/docs/zh/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
  190. package/docs/zh/plugin/plugin-system.mdx +19 -26
  191. package/docs/zh/plugin/runtime-plugins/life-cycle.mdx +2 -0
  192. package/docs/zh/plugin/server-plugins/api.mdx +11 -14
  193. package/docs/zh/plugin/server-plugins/life-cycle.mdx +2 -0
  194. package/package.json +11 -13
  195. package/{rspress.config.ts → rstack.config.mts} +7 -10
  196. package/src/components/Footer/styles.module.scss +1 -1
  197. package/src/components/SolutionCards/index.module.scss +3 -1
@@ -113,7 +113,7 @@ export default {
113
113
  },
114
114
  html: {
115
115
  outputStructure: 'flat',
116
- }
116
+ },
117
117
  };
118
118
  ```
119
119
 
@@ -8,21 +8,21 @@ Modern.js supports multiple rendering modes, and different rendering modes are s
8
8
 
9
9
  ## Rendering Mode Quick Reference
10
10
 
11
- | Rendering Mode | Characteristics | Use Cases |
12
- |----------------|-----------------|-----------|
13
- | **CSR** | Executes JavaScript in the browser to render pages | Applications with strong interactivity and low SEO requirements |
14
- | **SSR** | Pre-renders complete HTML pages on the server | Websites with high requirements for first-screen performance and SEO |
15
- | **Streaming SSR** | Renders and returns progressively, displaying initial UI faster | Applications requiring faster first-screen perception speed (**Default SSR mode**) |
16
- | **RSC** | Components render on the server, reducing client JS size; high cohesion between data and component logic, reducing state passing | Projects pursuing optimal performance and needing to reduce client-side code |
17
- | **SSG** | Generates static pages at build time, can be cached by CDN | Websites with relatively static content, such as blogs and documentation sites |
11
+ | Rendering Mode | Characteristics | Use Cases |
12
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
13
+ | **CSR** | Executes JavaScript in the browser to render pages | Applications with strong interactivity and low SEO requirements |
14
+ | **SSR** | Pre-renders complete HTML pages on the server | Websites with high requirements for first-screen performance and SEO |
15
+ | **Streaming SSR** | Renders and returns progressively, displaying initial UI faster | Applications requiring faster first-screen perception speed (**Default SSR mode**) |
16
+ | **RSC** | Components render on the server, reducing client JS size; high cohesion between data and component logic, reducing state passing | Projects pursuing optimal performance and needing to reduce client-side code |
17
+ | **SSG** | Generates static pages at build time, can be cached by CDN | Websites with relatively static content, such as blogs and documentation sites |
18
18
 
19
19
  ## Performance Comparison
20
20
 
21
- | Rendering Technology | Core Advantages | Main Bottlenecks |
22
- |---------------------|-----------------|------------------|
23
- | **SSR** | Server-side pre-rendering, beneficial for SEO | Must wait for all data to load before responding |
24
- | **Streaming SSR** | Renders and returns progressively, faster first screen | JS bundle size is still large |
25
- | **Streaming SSR + RSC** | Reduces client JS size | - |
21
+ | Rendering Technology | Core Advantages | Main Bottlenecks |
22
+ | ----------------------- | ------------------------------------------------------ | ------------------------------------------------ |
23
+ | **SSR** | Server-side pre-rendering, beneficial for SEO | Must wait for all data to load before responding |
24
+ | **Streaming SSR** | Renders and returns progressively, faster first screen | JS bundle size is still large |
25
+ | **Streaming SSR + RSC** | Reduces client JS size | - |
26
26
 
27
27
  ## How to Choose
28
28
 
@@ -239,12 +239,12 @@ In RSC projects, you have two ways to fetch data: directly in Server Components,
239
239
 
240
240
  ### Comparison of Two Data Fetching Approaches
241
241
 
242
- | Feature | Fetching in Server Component | Fetching in Data Loader |
243
- | --- | --- | --- |
244
- | Avoid Request Waterfall | Requires manual optimization | ✅ Automatically parallel execution |
245
- | Component Cohesion | ✅ Data and UI in the same place | Data logic separated into separate files |
246
- | Maintainability | ✅ Easier to understand and maintain | Requires maintaining additional files |
247
- | Type Safety | ✅ Natural type inference | Requires manual type management |
242
+ | Feature | Fetching in Server Component | Fetching in Data Loader |
243
+ | ----------------------- | ------------------------------------ | ---------------------------------------- |
244
+ | Avoid Request Waterfall | Requires manual optimization | ✅ Automatically parallel execution |
245
+ | Component Cohesion | ✅ Data and UI in the same place | Data logic separated into separate files |
246
+ | Maintainability | ✅ Easier to understand and maintain | Requires maintaining additional files |
247
+ | Type Safety | ✅ Natural type inference | Requires manual type management |
248
248
 
249
249
  **Generally, we recommend fetching data in Server Components**, because waterfall requests have less performance impact on the server, and this approach makes components more cohesive, with data fetching logic and UI rendering in the same place, making it easier to understand and maintain. However, if your page has multiple independent data sources and you want to completely avoid request waterfall issues, Data Loader's parallel execution feature will be more advantageous.
250
250
 
@@ -268,7 +268,11 @@ In Modern.js RSC projects, Server Components can receive data returned by Data L
268
268
 
269
269
  ```tsx title="routes/user/page.tsx"
270
270
  // Server Component receives loaderData through props
271
- export default function UserPage({ loaderData }: { loaderData: { name: string } }) {
271
+ export default function UserPage({
272
+ loaderData,
273
+ }: {
274
+ loaderData: { name: string };
275
+ }) {
272
276
  return <div>Welcome, {loaderData.name}</div>;
273
277
  }
274
278
  ```
@@ -276,7 +280,11 @@ export default function UserPage({ loaderData }: { loaderData: { name: string }
276
280
  ```tsx title="routes/user/page.tsx"
277
281
  'use client';
278
282
  // Client Component can also receive loaderData through props
279
- export default function UserPage({ loaderData }: { loaderData: { name: string } }) {
283
+ export default function UserPage({
284
+ loaderData,
285
+ }: {
286
+ loaderData: { name: string };
287
+ }) {
280
288
  return <div>Welcome, {loaderData.name}</div>;
281
289
  }
282
290
  ```
@@ -515,7 +523,6 @@ When using React 19, you no longer need to use Helmet. We recommend directly usi
515
523
 
516
524
  import DeployTip from '@site-docs/components/rsc-deploy-tip';
517
525
 
518
-
519
526
  <DeployTip />
520
527
 
521
528
  ## Common Issues
@@ -193,9 +193,9 @@ When rendering cache is enabled, Modern.js identifies the cache status of the cu
193
193
 
194
194
  The `x-render-cache` header can have the following values:
195
195
 
196
- | Name | Description |
197
- | ------- | ------------------------------------------------ |
198
- | hit | Cache hit, returned cache content |
196
+ | Name | Description |
197
+ | ------- | ----------------------------------------------------------------------------------- |
198
+ | hit | Cache hit, returned cache content |
199
199
  | stale | Cache hit, but data is stale, returned cache content and re-rendered asynchronously |
200
- | expired | Cache expired, re-rendered and returned new content |
201
- | miss | Cache missed |
200
+ | expired | Cache expired, re-rendered and returned new content |
201
+ | miss | Cache missed |
@@ -90,7 +90,7 @@ export async function loader({ params }) {
90
90
  const data = await res.json();
91
91
  return {
92
92
  message: data.message,
93
- }
93
+ };
94
94
  }
95
95
  ```
96
96
 
@@ -125,11 +125,7 @@ const Page = () => {
125
125
  const undefinedVars = data.unDefined;
126
126
  const definedVars = data.defined;
127
127
 
128
- return (
129
- <div>
130
- {isNode ? undefinedVars.msg : definedVars.msg}
131
- </div>
132
- );
128
+ return <div>{isNode ? undefinedVars.msg : definedVars.msg}</div>;
133
129
  };
134
130
 
135
131
  export default Page;
@@ -214,7 +210,7 @@ document.addEventListener('load', () => {
214
210
  console.log('document load');
215
211
  });
216
212
 
217
- export const doSomething = () => {}
213
+ export const doSomething = () => {};
218
214
  ```
219
215
 
220
216
  Directly referencing this in a component will cause SSR to throw errors, even if you use environment variables to conditionally load the code. The side effects in the dependency will still execute.
@@ -226,8 +222,8 @@ export const Page = () => {
226
222
  if (process.env.MODERN_TARGET === 'browser') {
227
223
  doSomething();
228
224
  }
229
- return <div>Hello World</div>
230
- }
225
+ return <div>Hello World</div>;
226
+ };
231
227
  ```
232
228
 
233
229
  Modern.js supports distinguishing between SSR and CSR bundles by using `.server.` suffix files. You can create `.ts` and `.server.ts` files with the same name to create a proxy:
@@ -243,12 +239,12 @@ export const doSomething: any = () => {};
243
239
  Import `./a` in the file, and the SSR bundle will prioritize the `.server.ts` files, while the CSR bundle will prioritize the `.ts` files.
244
240
 
245
241
  ```tsx title="routes/page.tsx"
246
- import { doSomething } from './a'
242
+ import { doSomething } from './a';
247
243
 
248
244
  export const Page = () => {
249
245
  doSomething();
250
- return <div>Hello World</div>
251
- }
246
+ return <div>Hello World</div>;
247
+ };
252
248
  ```
253
249
 
254
250
  ## Common Issues
@@ -245,7 +245,8 @@ Set the header in your middleware to choose the behavior dynamically:
245
245
  ```ts title="middleware example"
246
246
  export const middleware = async (ctx, next) => {
247
247
  const ua = ctx.req.header('user-agent') || '';
248
- const shouldWaitAll = /Lighthouse|Googlebot/i.test(ua) || ctx.req.path === '/marketing';
248
+ const shouldWaitAll =
249
+ /Lighthouse|Googlebot/i.test(ua) || ctx.req.path === '/marketing';
249
250
 
250
251
  // Write a boolean string: true -> onAllReady, false -> onShellReady
251
252
  ctx.req.headers.set('x-should-stream-all', String(shouldWaitAll));
@@ -6,7 +6,6 @@ sidebar_position: 3
6
6
 
7
7
  By default, Modern.js recommends using [Convention Routes](./routes.mdx) as the way to define routes. At the same time, Modern.js also provides a config-based routing capability that can be used together with convention routes or used separately.
8
8
 
9
-
10
9
  ## When to Use Config Routes
11
10
 
12
11
  Config routes are particularly useful in the following scenarios:
@@ -22,27 +21,26 @@ Config routes are particularly useful in the following scenarios:
22
21
  In the `src` directory or each entry directory, you can define a `modern.routes.ts` file to configure routes:
23
22
 
24
23
  ```ts
25
- import { defineRoutes } from '@modern-js/runtime/config-routes'
24
+ import { defineRoutes } from '@modern-js/runtime/config-routes';
26
25
 
27
26
  export default defineRoutes(({ route, layout, page, $ }, fileRoutes) => {
28
- return [
29
- route("home.tsx", "/"),
30
- ]
31
- })
27
+ return [route('home.tsx', '/')];
28
+ });
32
29
  ```
33
30
 
34
31
  ### Function Signature Description
35
32
 
36
33
  `defineRoutes` accepts a callback function with two parameters:
34
+
37
35
  1. `routeFunctions`: An object containing `route`, `layout`, `page`, `$` functions
38
36
  2. `fileRoutes`: An array of route configurations generated by convention routes
39
37
 
40
38
  Basic signature of route functions:
39
+
41
40
  - First parameter: File path relative to `modern.routes.ts`
42
41
  - Second parameter: Route path (optional, must be a string)
43
42
  - Third parameter: Array of child routes (optional)
44
43
 
45
-
46
44
  ## Route Functions
47
45
 
48
46
  Modern.js provides four main route configuration functions:
@@ -50,6 +48,7 @@ Modern.js provides four main route configuration functions:
50
48
  :::tip Path Description
51
49
 
52
50
  The first parameter (path) of all route functions is a **relative path**, which will be concatenated with the parent path to generate the final route path:
51
+
53
52
  - **Root path**: `"/"` or `""` represents the root path of the current level
54
53
  - **Relative path**: Child route paths will be concatenated relative to the parent path
55
54
  - **Dynamic path**: Use `:param` syntax to represent dynamic parameters
@@ -72,27 +71,28 @@ The `route` function is a general-purpose route configuration function that auto
72
71
  export default defineRoutes(({ route }, fileRoutes) => {
73
72
  return [
74
73
  // When no child routes, automatically generates page route
75
- route("home.tsx", "/"),
76
- route("about.tsx", "about"),
74
+ route('home.tsx', '/'),
75
+ route('about.tsx', 'about'),
77
76
 
78
77
  // When has child routes, automatically generates layout route
79
78
  // dashboard/layout.tsx needs to contain <Outlet> to render child routes
80
- route("dashboard/layout.tsx", "dashboard", [
81
- route("dashboard/overview.tsx", "overview"), // Generated path: /dashboard/overview
82
- route("dashboard/settings.tsx", "settings"), // Generated path: /dashboard/settings
79
+ route('dashboard/layout.tsx', 'dashboard', [
80
+ route('dashboard/overview.tsx', 'overview'), // Generated path: /dashboard/overview
81
+ route('dashboard/settings.tsx', 'settings'), // Generated path: /dashboard/settings
83
82
  ]),
84
83
 
85
84
  // Dynamic routes
86
- route("products/detail.tsx", "products/:id"),
85
+ route('products/detail.tsx', 'products/:id'),
87
86
 
88
87
  // Multiple paths pointing to the same component
89
- route("user/profile.tsx", "user"),
90
- route("user/profile.tsx", "profile"),
91
- ]
92
- })
88
+ route('user/profile.tsx', 'user'),
89
+ route('user/profile.tsx', 'profile'),
90
+ ];
91
+ });
93
92
  ```
94
93
 
95
94
  **Use cases**:
95
+
96
96
  - Quick route configuration without explicitly specifying page or layout
97
97
  - Simplify the complexity of route configuration
98
98
 
@@ -104,15 +104,16 @@ The `layout` function is specifically used to configure layout routes, always ge
104
104
  export default defineRoutes(({ layout, page }, fileRoutes) => {
105
105
  return [
106
106
  // Generate layout route with path "/auth", must contain child routes
107
- layout("auth/layout.tsx", "auth", [
108
- page("auth/login/page.tsx", "login"), // Generated path: /auth/login
109
- page("auth/register/page.tsx", "register"), // Generated path: /auth/register
107
+ layout('auth/layout.tsx', 'auth', [
108
+ page('auth/login/page.tsx', 'login'), // Generated path: /auth/login
109
+ page('auth/register/page.tsx', 'register'), // Generated path: /auth/register
110
110
  ]),
111
- ]
112
- })
111
+ ];
112
+ });
113
113
  ```
114
114
 
115
115
  **Use cases**:
116
+
116
117
  - Need to explicitly specify a component as a layout component
117
118
  - Provide common layout structure for multiple pages
118
119
  - Need to share navigation, sidebar and other UI components across multiple routes
@@ -124,15 +125,16 @@ The `page` function is specifically used to configure page routes, always genera
124
125
  ```ts
125
126
  export default defineRoutes(({ layout, page }, fileRoutes) => {
126
127
  return [
127
- layout("dashboard/layout.tsx", "dashboard", [
128
- page("dashboard/overview.tsx", "overview"), // Generated path: /dashboard/overview
129
- page("dashboard/settings.tsx", "settings"), // Generated path: /dashboard/settings
128
+ layout('dashboard/layout.tsx', 'dashboard', [
129
+ page('dashboard/overview.tsx', 'overview'), // Generated path: /dashboard/overview
130
+ page('dashboard/settings.tsx', 'settings'), // Generated path: /dashboard/settings
130
131
  ]),
131
- ]
132
- })
132
+ ];
133
+ });
133
134
  ```
134
135
 
135
136
  **Use cases**:
137
+
136
138
  - Need to explicitly specify a component as a page component
137
139
  - Ensure the component does not contain `<Outlet>` child component rendering
138
140
  - Provide clearer semantic expression
@@ -144,16 +146,17 @@ The `$` function is specifically used to configure wildcard routes for handling
144
146
  ```ts
145
147
  export default defineRoutes(({ layout, page, $ }, fileRoutes) => {
146
148
  return [
147
- layout("blog/layout.tsx", "blog", [
148
- page("blog/page.tsx", ""), // Generated path: /blog
149
- page("blog/[id]/page.tsx", ":id"), // Generated path: /blog/:id
150
- $("blog/$.tsx", "*"), // Wildcard route, matches all unmatched paths under /blog
149
+ layout('blog/layout.tsx', 'blog', [
150
+ page('blog/page.tsx', ''), // Generated path: /blog
151
+ page('blog/[id]/page.tsx', ':id'), // Generated path: /blog/:id
152
+ $('blog/$.tsx', '*'), // Wildcard route, matches all unmatched paths under /blog
151
153
  ]),
152
- ]
153
- })
154
+ ];
155
+ });
154
156
  ```
155
157
 
156
158
  **Use cases**:
159
+
157
160
  - Custom 404 pages
158
161
  - Handle all unmatched requests under specific paths
159
162
 
@@ -161,7 +164,6 @@ export default defineRoutes(({ layout, page, $ }, fileRoutes) => {
161
164
  The `$` function has the same functionality as the `$.tsx` file in convention routes, used to catch unmatched route requests.
162
165
  :::
163
166
 
164
-
165
167
  ## Configuring Routes
166
168
 
167
169
  ### Basic Example
@@ -170,11 +172,11 @@ The `$` function has the same functionality as the `$.tsx` file in convention ro
170
172
  export default defineRoutes(({ page }, fileRoutes) => {
171
173
  return [
172
174
  // Use page function to explicitly specify page route
173
- page("home.tsx", "/"),
174
- page("about.tsx", "about"),
175
- page("contact.tsx", "contact"),
176
- ]
177
- })
175
+ page('home.tsx', '/'),
176
+ page('about.tsx', 'about'),
177
+ page('contact.tsx', 'contact'),
178
+ ];
179
+ });
178
180
  ```
179
181
 
180
182
  ### Routes Without Path
@@ -186,15 +188,16 @@ export default defineRoutes(({ layout, page }, fileRoutes) => {
186
188
  return [
187
189
  // Use layout function to explicitly specify layout route
188
190
  // auth/layout.tsx needs to contain <Outlet> to render child routes
189
- layout("auth/layout.tsx", [
190
- page("login/page.tsx", "login"),
191
- page("register/page.tsx", "register"),
191
+ layout('auth/layout.tsx', [
192
+ page('login/page.tsx', 'login'),
193
+ page('register/page.tsx', 'register'),
192
194
  ]),
193
- ]
194
- })
195
+ ];
196
+ });
195
197
  ```
196
198
 
197
199
  The above configuration will generate:
200
+
198
201
  - `/login` → `auth/layout.tsx` + `login/page.tsx`
199
202
  - `/register` → `auth/layout.tsx` + `register/page.tsx`
200
203
 
@@ -203,14 +206,13 @@ The above configuration will generate:
203
206
  ```ts
204
207
  export default defineRoutes(({ page }, fileRoutes) => {
205
208
  return [
206
- page("user.tsx", "user"),
207
- page("user.tsx", "profile"),
208
- page("user.tsx", "account"),
209
- ]
210
- })
209
+ page('user.tsx', 'user'),
210
+ page('user.tsx', 'profile'),
211
+ page('user.tsx', 'account'),
212
+ ];
213
+ });
211
214
  ```
212
215
 
213
-
214
216
  ### Dynamic Routes
215
217
 
216
218
  Config routes support dynamic route parameters:
@@ -219,15 +221,14 @@ Config routes support dynamic route parameters:
219
221
  export default defineRoutes(({ page }, fileRoutes) => {
220
222
  return [
221
223
  // Required parameter
222
- page("blog/detail.tsx", "blog/:id"),
224
+ page('blog/detail.tsx', 'blog/:id'),
223
225
 
224
226
  // Optional parameter
225
- page("blog/index.tsx", "blog/:slug?"),
226
- ]
227
- })
227
+ page('blog/index.tsx', 'blog/:slug?'),
228
+ ];
229
+ });
228
230
  ```
229
231
 
230
-
231
232
  ## Automatic Route-Related File Discovery
232
233
 
233
234
  Config routes automatically discover component-related files without manual configuration. For any component file specified in `modern.routes.ts`, Modern.js will automatically find the following related files:
@@ -236,10 +237,10 @@ Config routes automatically discover component-related files without manual conf
236
237
  // modern.routes.ts
237
238
  export default defineRoutes(({ route }, fileRoutes) => {
238
239
  return [
239
- route("pages/profile.tsx", "profile"),
240
- route("pages/user/detail.tsx", "user/:id"),
241
- ]
242
- })
240
+ route('pages/profile.tsx', 'profile'),
241
+ route('pages/user/detail.tsx', 'user/:id'),
242
+ ];
243
+ });
243
244
  ```
244
245
 
245
246
  Modern.js will automatically find and load:
@@ -6,7 +6,13 @@ To use Playwright in Modern.js, you need to install the dependencies first. You
6
6
 
7
7
  import { PackageManagerTabs } from '@theme';
8
8
 
9
- <PackageManagerTabs command={{ npm: "npm init playwright", yarn: "yarn create playwright", pnpm: "pnpm create playwright" }} />
9
+ <PackageManagerTabs
10
+ command={{
11
+ npm: 'npm init playwright',
12
+ yarn: 'yarn create playwright',
13
+ pnpm: 'pnpm create playwright',
14
+ }}
15
+ />
10
16
 
11
17
  The above commands will automatically install Playwright dependencies and help you install and configure it in your project through a series of prompts, including adding a `playwright.config.ts` file.
12
18
 
@@ -74,18 +80,18 @@ export default Index;
74
80
  Next, add test cases to ensure the links on your pages work properly.
75
81
 
76
82
  ```ts title="tests/example.spec.ts"
77
- import { test, expect } from '@playwright/test'
83
+ import { test, expect } from '@playwright/test';
78
84
 
79
85
  test('should navigate to the about page', async ({ page }) => {
80
86
  // Start from the index page (the baseURL is set via the webServer in the playwright.config.ts)
81
- await page.goto('http://localhost:8080/')
87
+ await page.goto('http://localhost:8080/');
82
88
  // Find an element with the text 'About' and click on it
83
- await page.click('text=About')
89
+ await page.click('text=About');
84
90
  // The new URL should be "/about" (baseURL is used there)
85
- await expect(page).toHaveURL('http://localhost:8080/about')
91
+ await expect(page).toHaveURL('http://localhost:8080/about');
86
92
  // The new page should contain an h1 with "About"
87
- await expect(page.locator('h1')).toContainText('About')
88
- })
93
+ await expect(page.locator('h1')).toContainText('About');
94
+ });
89
95
  ```
90
96
 
91
97
  ## Run Test Cases
@@ -108,4 +114,4 @@ Running 3 tests using 3 workers
108
114
  To open last HTML report run:
109
115
 
110
116
  npx playwright show-report
111
- ```
117
+ ```
@@ -84,9 +84,9 @@ test('Page', async () => {
84
84
  </Router>,
85
85
  );
86
86
 
87
- await expect.element(
88
- page.getByRole('heading', { level: 1, name: 'Home' }),
89
- ).toBeVisible();
87
+ await expect
88
+ .element(page.getByRole('heading', { level: 1, name: 'Home' }))
89
+ .toBeVisible();
90
90
  });
91
91
  ```
92
92
 
@@ -181,12 +181,14 @@ First install and use the migrate-to-rstest skill. If it is not installed, insta
181
181
  npx skills add rstackjs/agent-skills --skill migrate-to-rstest
182
182
 
183
183
  Follow the migrate-to-rstest skill instructions and the official Rstest migration guides:
184
+
184
185
  - Jest: https://rstest.rs/guide/migration/jest
185
186
  - Vitest: https://rstest.rs/guide/migration/vitest
186
187
 
187
188
  Modern.js-specific requirement:
189
+
188
190
  - Install and use @modern-js/adapter-rstest together with @rstest/core.
189
191
  - Create or update rstest.config.ts to import withModernConfig from @modern-js/adapter-rstest.
190
192
  - Reuse the Modern.js app configuration with extends: withModernConfig().
191
193
  - Do not replace this with a plain Rstest config unless the project explicitly does not need Modern.js config integration.`}
192
- />
194
+ />
@@ -15,10 +15,10 @@ AI agents use them to get APIs, config, and conventions that exactly match your
15
15
 
16
16
  ## AGENTS.md
17
17
 
18
- `AGENTS.md` gives AI coding agents project-level guidance — telling them to read the bundled docs before making changes and to follow Modern.js conventions. A `CLAUDE.md` is generated alongside it, reusing the same guidance for Claude Code via the `@AGENTS.md` import.
18
+ `AGENTS.md` gives AI coding agents project-level guidance — telling them to read the bundled docs before making changes and to follow Modern.js conventions.
19
19
 
20
- - **New projects**: `npx @modern-js/create` generates both files by default; pass `--no-agents-md` to skip them.
21
- - **Existing projects**: run `npx @modern-js/create --agents-md-only` at the project root to create or update them. Re-run it any time; your own additions are preserved.
20
+ - **New projects**: `npx @modern-js/create` generates `AGENTS.md` by default; pass `--no-agents-md` to skip it.
21
+ - **Existing projects**: run `npx @modern-js/create --agents-md-only` at the project root to create or update `AGENTS.md`. Re-run it any time; your own additions are preserved.
22
22
 
23
23
  Modern.js only maintains the content inside the `<!-- BEGIN:modernjs-agent-rules -->` markers in `AGENTS.md`; anything you write outside them is left untouched.
24
24
 
@@ -35,9 +35,9 @@ Use it when you need content beyond the bundled docs — just let your agent ret
35
35
 
36
36
  Skills are on-demand AI capabilities following the [Agent Skills open standard](https://github.com/vercel-labs/skills). User-facing Skills:
37
37
 
38
- | Skill | Identifier | Description |
39
- |---|---|---|
40
- | Upgrade to v3 | `modernjs-migrate-to-v3` | Migrate a v2 app to v3: safe rewrites + manual checklist + migration report |
38
+ | Skill | Identifier | Description |
39
+ | --------------- | ------------------------- | ----------------------------------------------------------------------------------------------- |
40
+ | Upgrade to v3 | `modernjs-migrate-to-v3` | Migrate a v2 app to v3: safe rewrites + manual checklist + migration report |
41
41
  | Enable features | `modernjs-feature-enable` | Enable BFF / SSG / styled-components for v3 apps, and scaffold Tailwind CSS / custom Web Server |
42
42
 
43
43
  > Skills are not force-installed or implicitly installed — you install them explicitly. RSC and micro-frontend setups are configuration or architecture decisions, not one-click `modernjs-feature-enable` actions.
@@ -39,4 +39,3 @@ In addition, Modern.js provides richer server-side features, including comprehen
39
39
  ### Remix
40
40
 
41
41
  Pelease refer to [Modern.js vs Remix](https://github.com/web-infra-dev/modern.js/discussions/4872).
42
-
@@ -63,9 +63,9 @@ At this point, the `publicPath` defined in the producer's build output `mf-manif
63
63
  "name": "remote",
64
64
  "publicPath": "https://my-remote-module/"
65
65
  },
66
- "shared": [ /* xxx */ ],
66
+ "shared": [/* xxx */],
67
67
  "remotes": [],
68
- "exposes": [ /* xxx */ ]
68
+ "exposes": [/* xxx */]
69
69
  }
70
70
  ```
71
71
 
@@ -33,4 +33,3 @@ For more details, refer to [Using Module Federation](/guides/topic-detail/module
33
33
  Module Federation 2.0 offers the [Bridge](https://module-federation.io/practice/bridge/overview.html) capability to load application-level modules.
34
34
 
35
35
  Modern.js, based on Bridge and its internal implementation, provides APIs to easily export application-level modules. For more details, refer to [Application-Level Modules](/guides/topic-detail/module-federation/application).
36
-
@@ -22,6 +22,18 @@ server: {
22
22
  }
23
23
  ```
24
24
 
25
+ ### dev.lazyCompilation
26
+
27
+ **Change**: The default value in development has changed. Pure CSR and streaming SSR applications enable lazy compilation by default with `{ imports: true, entries: false }`; applications using string SSR, RSC or SSG keep it disabled by default. This only affects development and does not change production build output.
28
+
29
+ **Migration Example**: To keep the 2.0 behavior, disable it explicitly:
30
+
31
+ ```typescript
32
+ dev: {
33
+ lazyCompilation: false;
34
+ }
35
+ ```
36
+
25
37
  ## html
26
38
 
27
39
  ### html.appIcon
@@ -22,10 +22,10 @@ If your project's deployment configuration specifies a particular entry file nam
22
22
 
23
23
  Modern.js 3.0 has adjusted some runtime paths, and related import paths need to be updated. The path mapping is as follows:
24
24
 
25
- | Old Path | New Path | Description |
26
- |---------|---------|------|
27
- | `@modern-js/runtime/bff` | `@modern-js/plugin-bff/runtime` | BFF runtime path |
28
- | `@modern-js/runtime/server` | `@modern-js/server-runtime` | Server-side runtime path |
25
+ | Old Path | New Path | Description |
26
+ | --------------------------- | ------------------------------- | ------------------------ |
27
+ | `@modern-js/runtime/bff` | `@modern-js/plugin-bff/runtime` | BFF runtime path |
28
+ | `@modern-js/runtime/server` | `@modern-js/server-runtime` | Server-side runtime path |
29
29
 
30
30
  ## useRuntimeContext Deprecated
31
31
 
@@ -89,4 +89,3 @@ Change the CSS import method to the `@tailwind` directive approach.
89
89
  @tailwind components;
90
90
  @tailwind utilities;
91
91
  ```
92
-