Overview
@lastshotlabs/slingshot-ssg is Slingshot’s static-generation helper package. It builds on the SSR
contracts to discover which routes should be pre-rendered, resolve concrete paths for dynamic
routes, and write static HTML output to disk.
When To Use It
Section titled “When To Use It”Use this package when your app needs:
- fully static output for some or all SSR routes
- build-time pre-rendering driven by the same route tree and renderer used at request time
- static pages generated from
revalidate: falseroutes - dynamic route expansion via
staticPaths()orgenerateStaticParams()
It is a build-time library, not a runtime Slingshot plugin.
Minimum Setup
Section titled “Minimum Setup”The main inputs are the SSR renderer plus an SsgConfig:
serverRoutesDirassetsManifestoutDir
All of those paths should be absolute.
The most important optional controls are:
concurrency, which defaults to4clientEntry, when the Vite client entry chunk does not match the common defaultsstaticPathsTimeoutMs, which bounds how long any singlestaticPaths()/generateStaticParams()call may run before the build fails. Defaults to60000. Set this when a route’s path resolver fans out to a slow upstream so builds fail fast instead of hanging.
What You Get
Section titled “What You Get”The package exposes two main capabilities:
collectSsgRoutes(config)scans the server route tree and returns concrete URL paths to renderrenderSsgPage()andrenderSsgPages()render those paths to{outDir}/.../index.html
The renderer prefers the full SSR chain path:
- resolve the route chain with
resolveRouteChain() - render with
renderer.renderChain()when a file-based chain exists - fall back to
renderer.resolve()plusrenderer.render()when no file-based chain exists
That means SSG is trying to preserve the same layout and routing semantics the SSR path uses, not invent a separate rendering model.
Common Customization
Section titled “Common Customization”The important files are:
src/crawler.tsfor route discoverysrc/renderer.tsfor static rendering and output writingsrc/types.tsfor config and result contracts
The main knobs you are likely to tune are:
- which routes emit
revalidate: false - whether dynamic routes use
staticPaths()orgenerateStaticParams() - output concurrency
- client entry selection for injected asset tags
Gotchas
Section titled “Gotchas”- All config paths should be absolute. Relative paths are not the supported contract.
- Dynamic routes with
revalidate: falsebut nostaticPaths()orgenerateStaticParams()are skipped with a warning. - Non-200 renderer responses are skipped instead of being written as static output.
- Build-time route expansion runs with a minimal load context.
getUser()isnull, andbsCtxis only available when the build injectsglobalThis.__ssgBsCtx. - The package writes
index.htmlfiles under nested directories. That output shape is deliberate and should stay aligned with howslingshot-ssrservesstaticDircontent.
Key Files
Section titled “Key Files”src/index.tssrc/crawler.tssrc/renderer.tssrc/types.tssrc/cli.ts