Static Site Generation
SSG (Static Site Generation) is a technical solution that generates complete static web pages at build time based on data and templates. This means that in a production environment, pages are pre-rendered with content and can be cached by a CDN. SSG can offer better performance and higher security for pages that do not require dynamic data.
Enabling SSG
To enable SSG functionality in a Modern.js project, follow these steps to modify the code:
- Install SSG plugin dependencies
If the SSG plugin is not yet installed in your project, install it first:
Make sure the version of @modern-js/plugin-ssg matches the version of @modern-js/app-tools in your project. All Modern.js official packages are released with a uniform version number, and version mismatches may cause compatibility issues.
Check the version of @modern-js/app-tools first, then install the same version of @modern-js/plugin-ssg:
- Configure modern.config.ts
Import and add the SSG plugin in the modern.config.ts file, and configure output.ssg:
- Use
output.ssgfor single-entry apps. - Use
output.ssgByEntriesfor multi-entry apps. - When only
output.ssg: trueis set andoutput.ssgByEntriesis not configured, all routes under all entries will be treated as SSG routes.
Development Debugging
Since SSG also renders pages in a Node.js environment, we can enable SSR during the development phase to expose code issues early and validate the SSG rendering effect:
Using SSG in Conventional Routing
In conventional routing, Modern.js generates routes based on the file structure under the entry point, allowing the framework to collect complete route information.
Basic Usage
For example, the following is a project directory structure using conventional routing:
The above file directory will generate the following three routes:
//user/user/profile
If you are not familiar with the rules of conventional routing, refer to the Routing Solution first.
Add component code in src/routes/page.tsx:
Run the command pnpm run dev at the project root and check the dist/ directory, where only one HTML file main/index.html is generated.
Run the command pnpm run build at the project root, and after the build completes, check the dist/ directory again. This time, you'll find main/index.html, main/user/index.html, and main/user/profile/index.html files, each corresponding to the routes listed above.
Each route in conventional routing will generate a separate HTML file. Checking main/index.html, you will find it contains the text Index Page, which demonstrates the effect of SSG.
After running pnpm run serve to start the project, inspect the returned document in the Network tab of the browser's development tools. The document includes the fully rendered content from the component.
Using SSG in Manual Routing
Manual routing defines routes through component code, requiring the application to run to obtain accurate route information. Therefore, you cannot use the SSG feature out of the box. Developers need to configure which routes require SSG.
For example, consider the following code with multiple routes. By setting output.ssg to true, it will only render the entry route (/) by default.
If you want to enable SSG for /about as well, you can configure output.ssg:
After running pnpm run build, you will see a new main/about/index.html file in the dist/ directory.
After running pnpm run serve to start the project, inspect the returned document in the Network tab of the browser's development tools. The document includes the fully rendered content from the component.
The above example introduces single-entry scenarios. For more information, refer to the API Documentation.
Adding Dynamic Routes
In manual routing or conventional routing with dynamic segments (e.g., /user/[id]), provide concrete paths directly in routes.
Multi-entry
For multi-entry apps, configure per entry via output.ssgByEntries:
See API details: output.ssgByEntries
Configuring Request Headers for Rendering
Modern.js supports configuring request headers for specific entries or routes. For example:
In the above configuration, the x-tt-env request header is set for all routes, and the from request header is specifically set for the /about route.
Headers set in routes will override headers set for entries.