Static Site Generation
Static Site Generation (SSG) renders application pages as static HTML files during the build. The files can be served without running JavaScript for the initial response.
Retend provides the retendSSG Vite plugin for this process.
Setup
Import the plugin and add it to the Vite configuration:
// vite.config.ts import { defineConfig } from 'vite'; import { retend } from 'retend-web/plugins/vite'; import { retendSSG } from 'retend-server/plugin'; export default defineConfig({ plugins: [ retend(), retendSSG({ pages: ['/', '/about', '/contact'], routerModulePath: './source/router.ts', }), ], });
Configuration Options
| Option | Required | Default | Description |
|---|---|---|---|
pages | Yes | — | An array of URLs to generate static HTML for. |
routerModulePath | Yes | — | Path to the module that exports createRouter. |
rootSelector | No | '#app' | CSS selector for the root element. |
The Router Module
The module at routerModulePath must export a createRouter function that returns a Router instance:
// source/router.ts import { Router, defineRoutes } from 'retend'; import { Home } from './pages/home'; import { About } from './pages/about'; const routes = defineRoutes(() => [ { path: '/', component: Home }, { path: '/about', component: About }, ]); export function createRouter() { return new Router({ routes }); }
Handling Dynamic Routes
The pages array must list every specific URL you want to generate. For dynamic routes like /users/:userId, you need to enumerate each URL:
retendSSG({ pages: ['/', '/users/1', '/users/2', '/users/3'], routerModulePath: './source/router.ts', });
If your URLs come from a database or API, you can build the array dynamically in your Vite config:
const userIds = await fetchAllUserIds(); export default defineConfig({ plugins: [ retend(), retendSSG({ pages: ['/', ...userIds.map((id) => `/users/${id}`)], routerModulePath: './source/router.ts', }), ], });
How It Works
When you run vite build, the plugin:
- Reads your
index.htmlshell. - For each page in the
pagesarray, creates a virtual browser environment. - Renders the app by navigating the router to that page.
- Waits for all async data (via
<Await>boundaries) to resolve. - Serializes the rendered output into a static HTML file.
- Handles any redirects defined in your routes automatically.
The generated HTML files can be served by a static file host.
Redirects
If a route in your configuration has a redirect property, the plugin automatically generates:
- An HTML file with a
<meta http-equiv="refresh">redirect. - A
_redirectsfile entry (compatible with Netlify, Cloudflare Pages, etc.).