Generate a Static Site
Use generate a static site with the current published Askr packages.
@askrjs/askr0.0.59
How to use generate a static site
Keep static routes in the shared registry and make the document, assets, and output directory explicit in ssg.config.ts.
- Import the published @askrjs/askr entrypoint.
- Keep generate a static site configuration next to the component, route, or server composition root that owns it.
- Handle pending, unavailable, cancellation, and failure states, then verify the production path.
export const staticConfig = {
registry,
outputDir: 'dist',
document: renderDocument,
assets: [{ from: resolve('public'), to: '.' }],
};
// package.json: "build": "askr ssg --config ./ssg.config.ts --output ./dist"Goal and architecture
`createStaticGen({ routes, outputDir })` from `@askrjs/askr/ssg` walks your route table (or a `registry` built with `createRouteRegistry`) and writes fully rendered HTML per route, plus a `metadata.json` describing the run. Routes carrying real request-auth requirements are excluded from prerendering by default, since there's no request to authenticate against at build time — those stay runtime-only unless you explicitly override that.
Implementation
For parameterized paths like `/posts/{slug}`, supply an `entries()` function that returns one param map per page you want generated — `createStaticGen` expands the path template against each entry to produce concrete URLs. `dataOverrides` lets you feed deterministic seed data to resources during generation instead of hitting a live backend, and `assets` copies static files or directories alongside the generated HTML. `askr ssg --config <path> --output <dir> [--incremental]` runs the same generator from the CLI, with incremental mode using `invalidationKeys` and `changedRoutes` to skip unchanged pages.
Failure states
Check `result.failed` and each route's `RouteRenderResult.error` after `generate()` — a single route throwing during render doesn't stop the whole run, but it does mean that route's HTML wasn't written, and a naive script that only checks a zero exit code will miss it. Routes with `policies` (advanced runtime access checks) are excluded from prerendering by default for the same reason auth-gated routes are — don't fight this by forcing them in unless you're certain the policy is safe to evaluate without a real request.
Verification
Confirm `result.successful` matches `result.totalRoutes` and inspect `result.routes[].reason` — `unchanged`/`cache-hit` routes on an incremental run should genuinely be unchanged, not silently stale because an invalidation key wasn't wired up. Open a generated file directly (not through a dev server) and confirm it's real standalone HTML with no unresolved markers. If you're shipping incrementally, re-run with a deliberately changed key and confirm exactly the expected routes rebuild, not the entire set.