Cossack Framework supports Static Site Generation (SSG) to pre-render pages at build time. This enables faster page loads, better SEO, and the ability to host your application on any static hosting service.
Overview
SSG in Cossack works by:
- During build, identifying pages marked with
ssg: true - Rendering each page to a static HTML file
- Generating a
sitemap.xmlfor SEO
Usage
Basic Static Page
Mark any page with ssg: true to enable static generation:
import { Cossack, Page } from '@cossackframework/core'; import { html } from '@cossackframework/renderer'; @Page({ ssg: true }) export class About extends Cossack { render() { return html`<h1>About Us</h1>`; } }
This will generate dist/ssg/about/index.html at build time.
Dynamic Routes with Static Params
For dynamic routes (e.g., /users/[username]), use generateStaticParams to specify which parameter combinations to pre-render:
import { Cossack, Page, State } from '@cossackframework/core'; import { html } from '@cossackframework/renderer'; @Page({ ssg: { enabled: true, generateStaticParams: async () => { // Return array of params to pre-render return [ { username: 'alice' }, { username: 'bob' }, { username: 'charlie' }, ]; } } }) export class UserProfile extends Cossack { @State() username: string = ''; render() { const name = this.c.req.param('username'); return html`<h1>User: ${name}</h1>`; } }
This will generate:
dist/ssg/users/alice/index.htmldist/ssg/users/bob/index.htmldist/ssg/users/charlie/index.html
Build Commands
Standard Build
pnpm run buildBuilds client assets and SSR bundle (no static HTML generation).
SSG Build
pnpm run build:ssgRuns the SSG build process to generate static HTML files.
Build All
pnpm run build:allRuns both standard build and SSG build.
Custom Base URL
VITE_SSG_BASE_URL=https://my-site.com pnpm run build:ssg
Set the base URL used for generating sitemap URLs.
Output Structure
After SSG build, the dist/ssg/ directory contains:
dist/ssg/ ├── index.html # Root page ├── about/ │ └── index.html # /about page ├── users/ │ ├── alice/ │ │ └── index.html # /users/alice page │ └── bob/ │ └── index.html # /users/bob page ├── sitemap.xml # XML sitemap for SEO └── routes.json # List of generated routes
PageOptions Interface
export interface PageOptions { // ... existing options ssg?: boolean | SsgOptions; } export interface SsgOptions { enabled?: boolean; generateStaticParams?: () => Promise<Record<string, string>[]>; }
Limitations
No Server-Side State: SSG pages cannot use
@Statewith server-only data at build time. All state must be either:- Static content
- Client-side state (use
@ClientStateinstead) - Pre-defined via
generateStaticParams
No Dynamic Data: Pages that require real-time data (user-specific content, live prices, etc.) should not use SSG.
HTTP Transport Required: SSG pages must use
transport: 'http'in their@Pageoptions.
Best Practices
- Use SSG for Content Pages: Marketing sites, blogs, documentation, about pages
- Use SSR for User Pages: Dashboards, profiles, authenticated content
- Combine Both: Some frameworks can use hybrid approaches where SSG is the default with SSR fallback
Example: SSG Demo Page
See src/pages/ssg-demo/ in the framework package for a complete example demonstrating:
- Static page generation
- Dynamic route generation with
generateStaticParams - Integration with the Layout component