API Reference#

This page documents the public surface of @sigx/ssg, defined by the package exports map: the main entry (@sigx/ssg), the Vite plugin (@sigx/ssg/vite), the build and dev entries (@sigx/ssg/build, @sigx/ssg/dev), the client helpers (@sigx/ssg/client), and the ambient virtual-module types (@sigx/ssg/virtual).

For CLI usage see Commands.

Config#

defineSSGConfig#

TypeScript
function defineSSGConfig(config: SSGConfig): SSGConfig

Type-safe SSG config helper. Applies defaults (pages src/pages, layouts src/layouts, content src/content, defaultLayout default, outDir dist, base /, trailingSlash 'always', prefetch true, spaNavigation true, site.lang en, markdown.shiki true, toc.minLevel 2 / maxLevel 3) then merges the user config.

  • config — the user's SSG configuration.
  • Returns — the merged config. Export it as the default from ssg.config.ts.

defineConfig#

TypeScript
const defineConfig = defineSSGConfig

Alias for defineSSGConfig, re-exported under the conventional Vite-style name.

Build#

build#

TypeScript
function build(options?: BuildOptions): Promise<BuildResult>

Programmatic static-site build. Loads config, scans routes, builds the client and SSR Vite bundles, renders every path (including paths expanded from getStaticPaths) to static HTML in outDir, and writes sitemap.xml and robots.txt. Also exported via @sigx/ssg/build.

  • options — optional BuildOptions (configPath, verbose, concurrency, drafts). The effective default concurrency is 20; drafts: true includes pages with draft: true frontmatter, which are otherwise excluded from production builds and the sitemap.
  • Returns — a BuildResult with the built pages, total time, and warnings.

Dev server#

dev#

TypeScript
function dev(options?: DevOptions): Promise<void>

Starts the SSG dev server. Uses an existing vite.config if present, otherwise runs zero-config: it auto-loads @sigx/vite, optionally @tailwindcss/vite, and the SSG plugins with oxc automatic JSX (import source sigx). Default port 5173. Also exported via @sigx/ssg/dev.

  • options — optional DevOptions (configPath, port, host, open, verbose).
  • Returns — a promise that resolves once the server has started.

preview#

TypeScript
function preview(options?: DevOptions): Promise<void>

Previews the production build through the Vite preview server (default port 4173). Also exported via @sigx/ssg/dev.

  • options — optional DevOptions.
  • Returns — a promise that resolves once the preview server has started.

Sitemap#

generateSitemap#

TypeScript
function generateSitemap(entries: SitemapEntry[], config: SSGConfig): string

Builds sitemap.xml content (sitemaps.org 0.9 schema) from entries. Each path is prefixed with site.url + base and normalized per the config's trailingSlash policy, byte-identical with the canonical URL emitted in each page's head.

  • entries — the sitemap entries to include.
  • config — the SSG config (supplies site.url, base, and trailingSlash).
  • Returns — the sitemap XML as a string.

normalizePagePath#

TypeScript
function normalizePagePath(path: string, trailingSlash?: 'always' | 'never'): string

Normalizes a route path for public URLs (canonical, og:url, sitemap <loc>). With 'always' (the default, matching the <path>/index.html output layout) folder routes gain a trailing slash (/about/about/); the root / and explicit .html paths are untouched. With 'never', trailing slashes are stripped instead. The TrailingSlash union type is also exported.

  • path — the route path to normalize.
  • trailingSlash — the policy (defaults to 'always').
  • Returns — the normalized path.

generateRobotsTxt#

TypeScript
function generateRobotsTxt(config: SSGConfig, sitemapPath?: string): string

Builds robots.txt content (an Allow: / line and a Sitemap: line).

  • config — the SSG config.
  • sitemapPath — path to the sitemap (defaults to /sitemap.xml).
  • Returns — the robots.txt content as a string.

writeSitemap#

TypeScript
function writeSitemap(
    pages: PageBuildResult[],
    config: SSGConfig,
    outDir: string,
    options?: SitemapOptions,
): Promise<{ sitemapPath: string; robotsPath: string }>

Converts built pages to entries and writes sitemap.xml and robots.txt to outDir. Called automatically at the end of build().

  • pages — the build results to map.
  • config — the SSG config.
  • outDir — the output directory.
  • options — optional SitemapOptions.
  • Returns — the written sitemapPath and robotsPath.

pagesToSitemapEntries#

TypeScript
function pagesToSitemapEntries(
    pages: PageBuildResult[],
    options?: SitemapOptions,
): SitemapEntry[]

Maps build results to sitemap entries, applying exclude globs and depth-based priority (/ = 1.0, depth 1 = 0.8, depth 2 = 0.6, otherwise defaultPriority 0.5) and defaultChangefreq weekly.

  • pages — the build results to map.
  • options — optional SitemapOptions.
  • Returns — the derived SitemapEntry[].

loadThemeModule / applyThemeConfig / resolveThemeConfig#

TypeScript
function loadThemeModule(themeName: string, root: string): Promise<ThemeModule>
function applyThemeConfig(config: SSGConfig, theme: ThemeModule): SSGConfig
function resolveThemeConfig(config: SSGConfig, root: string): Promise<SSGConfig>

Theme loading and config-contribution merging: a theme's exported config can contribute markdown plugins (run before the site's), build hooks (run before the site's), head tags (prepended to site.head), CSS import specifiers (prepended to clientImports), and a defaultLayout (used when the site doesn't set one). resolveThemeConfig combines both: it loads config.theme (if set) and applies it. Build and dev call this automatically; the exports exist for tooling.

These build-time helpers back the corresponding config options; the build calls them for you, and they are exported for programmatic use.

Redirects#

TypeScript
function generateRedirectHtml(target: string, config: SSGConfig): string
function generateRedirectsFile(redirects: Record<string, string>, config: SSGConfig): string
function writeRedirects(
    redirects: Record<string, string>,
    config: SSGConfig,
    outDir: string,
    renderedPaths?: Iterable<string>,
): Promise<void>

Emit the per-path meta-refresh pages and the Netlify/Cloudflare _redirects file. Relative targets are prefixed with base; a redirect colliding with a rendered page throws. See Configuration → Redirects.

TypeScript
function extractSearchText(html: string): string
function buildSearchIndex(pages: PageBuildResult[], options?: SearchOptions): SearchIndexEntry[]
function writeSearchIndex(/* … */): Promise<void>

Build the search-index.json over rendered pages. Consume it on the client with loadSearchIndex / searchPages from @sigx/ssg/client.

LLM output#

TypeScript
function getMarkdownPath(urlPath: string): string
function prepareLlmsPages(
    pages: PageBuildResult[],
    config: SSGConfig,
    options?: LlmsOptions,
    readSource?: (file: string) => Promise<string | null>,
): Promise<LlmsPage[]>
function renderPageMarkdown(source: string, options: RenderPageMarkdownOptions): string
function buildLlmsIndex(pages: LlmsPage[], config: SSGConfig, options?: LlmsOptions): string
function buildLlmsFullText(pages: LlmsPage[], options?: LlmsFullOptions): string
function writeLlmsOutputs(
    pages: PageBuildResult[],
    config: SSGConfig,
    outDir: string,
    options?: LlmsOptions,
    publicDir?: string,
): Promise<{ files: string[]; warnings: string[] }>

The helper family behind the llms config option. getMarkdownPath maps a route to its .md rendition path (/docs/guide/docs/guide.md, /index.md). prepareLlmsPages filters the built pages to the llms-visible set (sitemap rules + exclude globs + frontmatter llms: false + transform) and renders each markdown-sourced page's rendition once; buildLlmsIndex and buildLlmsFullText are pure over the prepared pages, so per-area files are filtered re-invocations. renderPageMarkdown is the per-page rendition: frontmatter replaced with a ---\nurl/title/description\n--- header, MDX syntax stripped by a fence-aware line scanner (fence contents are never touched), and fence info strings normalized to the bare language. writeLlmsOutputs writes everything into outDir — a llms* file you ship via public/ is never overwritten.

Data loaders#

TypeScript
function runDataLoaders(loaders: DataLoaders): Promise<Record<string, unknown>>
function generateDataModule(values: Record<string, unknown>): string

Run the config's data loaders and emit the virtual:ssg-data module source. Values must be JSON-serializable.

TypeScript
function checkLinks(
    docs: Array<{ path: string; html: string }>,
    options?: LinkCheckOptions,
): BrokenLink[]
function extractLocalLinks(html: string): string[]
function extractElementIds(html: string): Set<string>
function formatLinkCheckReport(broken: BrokenLink[]): string

Validate internal links and #fragment anchors across rendered pages. linkCheck: 'warn' | 'error' in the config drives whether findings warn or fail the build.

Other build helpers#

TypeScript
function generateDefault404(config: SSGConfig): string
function gitLastModifiedMap(root: string): Map<string, string>
function resolveLastmods(/* … */): Map<string, string>

generateDefault404 produces the fallback 404.html when no /404 page exists; gitLastModifiedMap / resolveLastmods back sitemap.lastmod.

Vite plugin#

ssgPlugin#

TypeScript
function ssgPlugin(options?: SSGPluginOptions): Plugin[]

The main Vite plugin, exported from @sigx/ssg/vite. Returns an array of Vite plugins: file-based routing, layouts, navigation, and zero-config entry generation, plus the MDX plugin (unless enableMdx: false). It serves the virtual:ssg-routes, virtual:ssg-navigation, virtual:ssg-config, virtual:generated-layouts, and virtual client/server entry modules, and handles HMR for pages, layouts, and MDX frontmatter.

  • options — optional SSGPluginOptions (Partial<SSGConfig> plus configPath and enableMdx, default true).
  • Returns — an array of Vite plugins; spread it or pass it directly to Vite's plugins.

default export of @sigx/ssg/vite#

TypeScript
export default ssgPlugin

The default export of @sigx/ssg/vite is ssgPlugin.

Build hooks#

SSGConfig.hooks carries BuildHookstransformHtml(html, page), onPageRendered(page & { html }), and postBuild(result, ctx). See Configuration & Content → Build hooks for semantics (per-page hooks run concurrently; a throwing hook fails the build).

Errors#

SSGError#

TypeScript
class SSGError extends Error {
    readonly code: string;
    readonly file?: string;
    readonly line?: number;
    readonly suggestion?: string;
    constructor(message: string, options: {
        code: string;
        file?: string;
        line?: number;
        suggestion?: string;
        cause?: Error;
    });
    format(root?: string): string;
}

Structured SSG error carrying a code, an optional file and line, and a suggestion. format() renders a console-friendly message with the relative path and a hint.

ErrorCodes#

TypeScript
const ErrorCodes: {
    readonly CONFIG_NOT_FOUND: 'SSG001';
    readonly CONFIG_INVALID: 'SSG002';
    readonly CONFIG_THEME_NOT_FOUND: 'SSG003';
    readonly PAGE_NOT_FOUND: 'SSG100';
    readonly PAGE_INVALID_EXPORT: 'SSG101';
    readonly DYNAMIC_ROUTE_NO_PATHS: 'SSG102';
    readonly LAYOUT_NOT_FOUND: 'SSG103';
    readonly BUILD_RENDER_FAILED: 'SSG300';
    readonly BUILD_VITE_FAILED: 'SSG301';
    readonly MDX_PARSE_ERROR: 'SSG400';
    readonly MDX_FRONTMATTER_ERROR: 'SSG401';
}

Catalog of SSG diagnostic codes used in error and warning messages (for example, SSG102 means a dynamic route is missing getStaticPaths).

handleError#

TypeScript
function handleError(error: unknown, root?: string): never

Formats and logs an error (an SSGError gets pretty output, including its cause), then calls process.exit(1). Terminal helper for CLI entry points.

  • error — the error to report.
  • root — optional project root, used to render relative paths.

Client helpers#

These are exported from @sigx/ssg/client.

prefetch#

TypeScript
function prefetch(path: string): void

Appends a <link rel="prefetch"> for the given path to <head>.

  • path — the internal path to prefetch.

setupPrefetch#

TypeScript
function setupPrefetch(options?: { delay?: number }): void

Prefetches internal links on hover (default delay 100 ms), skipping external and hash links and already-prefetched paths. Wired automatically in the generated client entry when config.prefetch is enabled.

  • options.delay — hover delay in milliseconds before prefetching.

installSpaNavigation#

TypeScript
function installSpaNavigation(
    router: { push(path: string): unknown },
    options?: { base?: string; trailingSlash?: TrailingSlash },
): () => void

Routes same-origin internal anchor clicks (including plain markdown links) through the router instead of full page reloads. The browser keeps handling modified clicks, external/mailto: links, target/download anchors, same-document #hash scrolls, data-no-spa opt-outs, and anything that already called preventDefault(). Wired automatically into the generated client entry (spaNavigation: false disables); call it yourself in custom entries. Returns an uninstall function.

  • router — anything with a push(path) method.
  • options.base — the site base path on subpath deploys (stripped before push).
  • options.trailingSlash'always' (the default) pushes the canonical trailing-slash URL for folder routes so SPA navigation matches the hard-load form; paths with a file extension (e.g. /sitemap.xml) are pushed verbatim. 'never' strips the slash instead. Set it from the same config value as the build.

isStaticPage#

TypeScript
function isStaticPage(): boolean

Returns true when the document has no data-ssr attribute (statically generated rather than server-rendered).

getInitialState#

TypeScript
function getInitialState<T = Record<string, unknown>>(): T | null

Parses the JSON embedded in the #__SSG_STATE__ script element, or returns null.

  • Returns — the parsed state, or null if absent.

Package-manager API#

TypeScript
function getPackageManager(): Pm
function setPackageManager(pm: Pm): void
function onPackageManagerChange(listener: (pm: Pm) => void): () => void
function installPackageManagerSwitcher(): () => void

// pure command helpers
function parsePackageManagerCommand(command: string): ParsedPackageManagerCommand | null
function renderPackageManagerCommand(parsed: ParsedPackageManagerCommand, pm: Pm): string
function translatePackageManagerCommand(command: string, pm: Pm): string
const PACKAGE_MANAGERS: readonly Pm[]   // 'pnpm' | 'npm' | 'yarn' | 'bun'
const DEFAULT_PACKAGE_MANAGER: Pm       // 'pnpm'
type Pm = 'pnpm' | 'npm' | 'yarn' | 'bun'

The npm/pnpm/yarn/bun switcher behind package-manager code fences. getPackageManager reads the current selection (in-page → persisted → server default → 'pnpm'); setPackageManager selects one, updating every switcher window, persisting the choice, and notifying subscribers; onPackageManagerChange subscribes (returns an unsubscribe). installPackageManagerSwitcher wires the tab clicks, cross-tab sync, and late-mounted windows — wired automatically in the generated client entry. The pure parse/render/translate helpers convert a single command between managers without touching the DOM. See Client runtime.

loadSearchIndex#

TypeScript
function loadSearchIndex(options?: { base?: string; url?: string }): Promise<SearchIndexEntry[]>

Fetches the emitted search-index.json (built when search: true). Pass base for subpath deploys, or url to override the location. Throws with a hint if the index is missing.

searchPages#

TypeScript
function searchPages(
    entries: SearchIndexEntry[],
    query: string,
    options?: { limit?: number },
): SearchResult[]

Ranks index entries against a query (AND semantics across whitespace-separated terms; title matches outrank headings outrank description outrank body). Each SearchResult carries path, title, score, an optional body excerpt, and an optional heading anchor for deep links. Pure and dependency-free. See Client runtime → Search.

installCodeCopy#

TypeScript
function installCodeCopy(): () => void

Wires the copy buttons Shiki emits in every code-window header (package-manager windows copy only the visible variant). One delegated listener; returns a disposer; safe on pages without code blocks. Wired automatically in the generated client entry.

ssrClientPlugin#

TypeScript
export { ssrClientPlugin } from '@sigx/server-renderer/client'

Re-exported from @sigx/ssg/client. The SignalX app plugin that enables client-side hydration of server-rendered HTML; the generated client entry uses it via .use(ssrClientPlugin).

Types#

The following interfaces and types are part of the public surface.

SSGConfig#

TypeScript
interface SSGConfig {
    pages?: string;
    layouts?: string;
    content?: string;
    theme?: string;
    defaultLayout?: string;
    outDir?: string;
    base?: string;
    trailingSlash?: 'always' | 'never';
    site?: SiteConfig;
    markdown?: MarkdownConfig;
    clientEntry?: string;
    clientImports?: string[];
    serverEntry?: string;
    htmlTemplate?: string | false;
    prefetch?: boolean | { delay?: number };
    spaNavigation?: boolean;
    collections?: Record<string, CollectionConfig>;
    navigation?: NavigationConfig;
    toc?: TOCConfig;
    sitemap?: SitemapOptions | false;
    hooks?: BuildHooks;
    redirects?: Record<string, string>;
    search?: boolean | SearchOptions;
    linkCheck?: 'off' | 'warn' | 'error';
    routes?: (ctx: RoutesContext) => ProgrammaticRoute[] | Promise<ProgrammaticRoute[]>;
    data?: DataLoaders;
}

The full SSG configuration object accepted by defineSSGConfig. redirects maps old paths to new (see Configuration → Redirects); search enables the built-in search index; linkCheck (default 'warn') validates internal links and anchors; routes adds programmatic pages; data registers build-time data loaders exposed via virtual:ssg-data.

SiteConfig#

TypeScript
interface SiteConfig {
    title?: string;
    description?: string;
    author?: string;
    url?: string;
    lang?: string;
    favicon?: string;
    ogImage?: string;
    twitter?: string;
    fonts?: string[];
    themeColor?: string;
    jsonLd?: object | object[];
    nav?: NavItem[];
    logo?: string;
    repo?: string;
    head?: HeadTag[];
    search?: boolean | { base?: string; url?: string };
    editBase?: string;
    announcement?: { text: string; href?: string; id?: string };
}

Site-wide metadata used for head tags, canonical URLs, and the sitemap, plus the fields layouts/themes render: nav, logo, repo, head, global jsonLd, the search UI flag, an editBase for edit-this-page links, and an announcement bar. Reaches layouts via LayoutProps.site.

HeadTag#

TypeScript
interface HeadTag {
    tag: string;
    attrs?: Record<string, string>;
    children?: string;
}

A raw tag injected into <head>. attrs values are HTML-escaped; children is emitted verbatim, so it can hold inline JSON, CSS, or script content.

CollectionConfig#

TypeScript
interface CollectionConfig {
    path: string;
    layout?: string;
    showDrafts?: 'dev' | 'never';
    sectionOrder?: Record<string, number> | string[];
}

Configuration for a single content collection, keyed by name under collections. sectionOrder (a name → weight map or an explicit list) overrides the site-wide navigation.sectionOrder for this collection's sidebar.

TypeScript
interface NavigationConfig {
    sidebar?: NavSection[];
    autoGenerate?: boolean;
    showDrafts?: 'dev' | 'never';
    sectionOrder?: Record<string, number> | string[];
}

Navigation configuration: explicit sections, auto-generation (default true), draft handling, and sectionOrder — a name → weight map (lower first, merged over the built-in defaults) or an explicit category list (listed first in order, then the rest per the defaults). A collection can override it with its own sectionOrder.

TypeScript
interface NavSection {
    title: string;
    items: NavItem[];
    order?: number;
}

A titled group of navigation items.

TypeScript
interface NavItem {
    title: string;
    href?: string;
    items?: NavItem[];
    order?: number;
}

A single navigation entry, optionally nesting child items.

PageMeta#

TypeScript
interface PageMeta {
    title?: string;
    description?: string;
    layout?: string;
    draft?: boolean;
    date?: string | Date;
    tags?: string[];
    ssr?: boolean;
    category?: string | string[];
    order?: number;
    sidebar?: boolean;
    toc?: boolean | { minLevel?: number; maxLevel?: number };
    headings?: TocHeading[];
    [key: string]: unknown;
}

Per-page metadata, sourced from frontmatter or an exported meta.

PageModule#

TypeScript
interface PageModule {
    default: ComponentFactory<any, any, any>;
    getStaticPaths?: GetStaticPaths;
    layout?: string;
    frontmatter?: PageMeta;
}

The shape of a page module: a default component, optional getStaticPaths, an optional layout, and frontmatter.

GetStaticPaths#

TypeScript
type GetStaticPaths = () => StaticPath[] | Promise<StaticPath[]>

A function a dynamic route exports to enumerate the paths to pre-render.

StaticPath#

TypeScript
interface StaticPath {
    params: Record<string, string>;
    props?: Record<string, unknown>;
}

One pre-rendered path: the route params and optional props passed to the page.

SSGRoute#

TypeScript
interface SSGRoute {
    path: string;
    file: string;
    name: string;
    layout?: string;
    component?: ComponentFactory<any, any, any>;
    meta?: PageMeta;
    children?: SSGRoute[];
}

A resolved route produced by scanning src/pages.

LayoutModule#

TypeScript
interface LayoutModule {
    default: ComponentFactory<LayoutProps, unknown, LayoutSlots>;
}

The shape of a layout module.

LayoutProps#

TypeScript
interface LayoutProps {
    meta?: PageMeta;
    path?: string;
    site?: SiteConfig;
}

Props passed to a layout component: the current page meta, the route path, and the whole site config so layouts/themes can render branding, search UI, announcement bars, and edit-this-page links without hardcoding them.

LayoutSlots#

TypeScript
interface LayoutSlots {
    default: () => unknown;
}

Slots provided to a layout; default() renders the page content.

ThemeModule#

TypeScript
interface ThemeModule {
    layouts?: Record<string, ComponentFactory<LayoutProps, unknown, LayoutSlots>>;
    components?: Record<string, ComponentFactory<any, any, any>>;
    config?: ThemeConfig;
}

The shape of a theme package referenced through the config theme field.

ThemeConfig#

TypeScript
interface ThemeConfig {
    defaultLayout?: string;
    hooks?: BuildHooks;
    markdown?: Pick<MarkdownConfig, 'remarkPlugins' | 'rehypePlugins'>;
    head?: HeadTag[];
    css?: string[];
}

Config a theme contributes, merged so the site's own config always wins: a defaultLayout (used when the site doesn't set one), build hooks (run before the site's), markdown plugins (run before the site's), head tags (prepended to site.head), and css import specifiers (prepended to clientImports). See Themes.

MarkdownConfig#

TypeScript
interface MarkdownConfig {
    shiki?: boolean | ShikiConfig;
    remarkPlugins?: unknown[];
    rehypePlugins?: unknown[];
}

Markdown / MDX processing options.

ShikiConfig#

TypeScript
interface ShikiConfig {
    light?: string;
    dark?: string;
    langs?: string[];
    triggerLabel?: string;
    defaultPackageManager?: 'pnpm' | 'npm' | 'yarn' | 'bun';
    transformers?: ShikiTransformer[];
    skipLanguages?: string[];
}

Shiki highlighting options. transformers (from shiki) are applied to every highlighted block, with the raw fence meta exposed as options.meta.__raw; skipLanguages leaves listed fences untouched for a downstream rehype plugin/island (e.g. ['mermaid', 'math']); defaultPackageManager (default 'pnpm') chooses the first variant on package-manager fences; triggerLabel is the live-code "Try Live" button label.

TOCConfig#

TypeScript
interface TOCConfig {
    minLevel?: number;
    maxLevel?: number;
}

Heading levels included when extracting a table of contents (defaults: 2 to 3).

TocHeading#

TypeScript
interface TocHeading {
    id: string;
    text: string;
    level: number;
}

A single extracted heading.

BuildOptions#

TypeScript
interface BuildOptions {
    configPath?: string;
    verbose?: boolean;
    concurrency?: number;
    drafts?: boolean;
}

Options for build(). The effective default concurrency is 20; drafts: true includes pages with draft: true frontmatter, otherwise excluded from production builds and the sitemap.

BuildResult#

TypeScript
interface BuildResult {
    pages: PageBuildResult[];
    totalTime: number;
    warnings: string[];
}

The result of build().

PageBuildResult#

TypeScript
interface PageBuildResult {
    path: string;
    file: string;
    time: number;
    size: number;
    meta?: PageMeta;
    source?: string;
}

Per-page build statistics, carrying the page meta and the absolute source file path (read by sitemap.lastmod git/mtime derivation).

DevOptions#

TypeScript
interface DevOptions {
    configPath?: string;
    port?: number;
    host?: string | boolean;
    open?: boolean;
    verbose?: boolean;
}

Options for dev() and preview().

SSGContext#

TypeScript
interface SSGContext {
    site: SiteConfig;
    page: PageMeta;
    params: Record<string, string>;
    isDev: boolean;
    base: string;
}

The rendering context exposed to pages.

SSGPluginOptions#

TypeScript
interface SSGPluginOptions extends Partial<SSGConfig> {
    configPath?: string;
    enableMdx?: boolean; // default true
}

Options for ssgPlugin().

SitemapEntry#

TypeScript
interface SitemapEntry {
    path: string;
    lastmod?: Date | string;
    changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
    priority?: number;
}

A single sitemap URL entry.

SitemapOptions#

TypeScript
interface SitemapOptions {
    includePages?: boolean;
    additionalUrls?: SitemapEntry[];
    exclude?: string[];
    defaultChangefreq?: SitemapEntry['changefreq'];
    defaultPriority?: number;
    lastmod?: 'git' | 'mtime' | false;
    transform?: (entry: SitemapEntry, page: PageBuildResult) => SitemapEntry | null | undefined;
}

Options for sitemap generation. lastmod derives each <lastmod> from the source file — 'git' from the last commit date (needs full history), 'mtime' from the filesystem timestamp (default false); explicit per-page meta.lastmod always wins. transform runs last per entry — adjust it, or return null/undefined to drop it.

BuildHooks#

TypeScript
interface BuildHooks {
    transformHtml?: (html: string, page: BuildHookPage) => string | Promise<string>;
    onPageRendered?: (page: PageBuildResult & { html: string }) => void | Promise<void>;
    postBuild?: (
        result: { pages: PageBuildResult[]; warnings: string[] },
        ctx: { outDir: string; config: SSGConfig },
    ) => void | Promise<void>;
}

Build pipeline hooks (production builds only). The per-page hooks run concurrently and in no guaranteed order; postBuild runs exactly once. See Configuration → Build hooks.

BuildHookPage#

TypeScript
interface BuildHookPage {
    path: string;
    params: Record<string, string>;
    props?: Record<string, unknown>;
    meta?: PageMeta;
    route: SSGRoute;
}

The page context passed to per-page build hooks.

SearchOptions#

TypeScript
interface SearchOptions {
    output?: string;
    maxTextLength?: number;
}

Built-in search options: the index filename inside outDir (default 'search-index.json') and the per-page visible-text cap in characters (default 8000).

SearchIndexEntry#

TypeScript
interface SearchIndexEntry {
    path: string;
    title: string;
    description?: string;
    headings: TocHeading[];
    text: string;
    tags?: string[];
}

One page in the emitted search index. Also exported from @sigx/ssg/client.

LlmsOptions#

TypeScript
interface LlmsOptions {
    index?: boolean;                       // llms.txt (default true)
    title?: string;                        // default site.title
    description?: string;                  // default site.description
    intro?: string;                        // markdown emitted after the blockquote
    sections?: LlmsSection[];              // curated index; default: auto per collection
    full?: boolean | LlmsFullOptions;      // llms-full.txt (default true)
    pageMd?: boolean;                      // per-page .md renditions (default true)
    areas?: Record<string, LlmsAreaOptions>; // per-area sub-indexes; key = path prefix
    exclude?: string[];                    // route globs excluded from ALL llms outputs
    transform?: (md: string, page: PageBuildResult) => string | null | undefined;
}

interface LlmsSection {
    title: string;            // emitted as `## title`
    collections?: string[];   // those collections' pages, in sidebar order
    pages?: string[];         // explicit route paths
    links?: LlmsLink[];       // hand-authored entries
}

interface LlmsLink {
    title: string;
    href: string;             // route path (resolved to its .md rendition) or external URL
    note?: string;            // rendered as the `: note` suffix
}

interface LlmsFullOptions {
    output?: string;          // default 'llms-full.txt'
    include?: string[];       // route globs (default: every markdown-sourced page)
    exclude?: string[];
}

type LlmsAreaOptions = Omit<LlmsOptions, 'areas' | 'pageMd' | 'transform'>;

Configuration for the LLM-friendly output. An area's full defaults to false (per-area llms-full.txt is opt-in); the global transform receives every page and can branch on page.path.

LlmsPage#

TypeScript
interface LlmsPage {
    page: PageBuildResult;
    url: string;         // absolute HTML URL
    mdPath?: string;     // outDir-relative .md rendition path (markdown-sourced pages only)
    markdown?: string;   // the rendition, header block included
}

A built page prepared for the llms outputs by prepareLlmsPages.

RoutesContext / ProgrammaticRoute / DataLoaders#

TypeScript
interface RoutesContext {
    config: SSGConfig;
    root: string;
}

interface ProgrammaticRoute {
    path: string;
    file: string;
    layout?: string;
    meta?: PageMeta;
}

type DataLoaders = Record<string, () => unknown | Promise<unknown>>;

config.routes is (ctx: RoutesContext) => ProgrammaticRoute[] | Promise<…> — pages added outside the filesystem scan. config.data is a DataLoaders map exposed via virtual:ssg-data. See Configuration → Programmatic routes and Build-time data loaders.

TypeScript
interface BrokenLink {
    page: string;
    href: string;
    reason: 'missing-page' | 'missing-anchor';
}

interface LinkCheckOptions {
    base?: string;
    redirects?: Record<string, string>;
    fileExists?: (path: string) => boolean;
}

Returned and accepted by checkLinks (see Link checking).

Virtual modules#

Ambient declarations are available by adding @sigx/ssg/virtual to compilerOptions.types. These modules are served by the Vite plugin at runtime.

virtual:ssg-routes#

TypeScript
declare module 'virtual:ssg-routes' {
    interface SSGRouteRecord {
        path: string;
        name: string;
        file: string;
        component: unknown;
        meta: Record<string, unknown> & { headings?: unknown };
        layout?: string;
    }
    const routes: SSGRouteRecord[];
    export default routes;
}

The generated list of routes; default-exported as an array of SSGRouteRecord.

virtual:ssg-navigation#

TypeScript
declare module 'virtual:ssg-navigation' {
    interface CollectionNavigation { sidebar: NavSection[] }
    export const navigation: Record<string, CollectionNavigation>;
    export function getCollectionNav(name: string): CollectionNavigation | undefined;
    export function detectCollection(path: string): string | undefined;
    export function getSidebar(name: string): NavSection[];
    const _default: {
        navigation: typeof navigation;
        collections: Record<string, CollectionConfig>;
        getCollectionNav: typeof getCollectionNav;
        detectCollection: typeof detectCollection;
        getSidebar: typeof getSidebar;
    };
    export default _default;
}

Runtime navigation helpers: look up a collection's sidebar, detect the collection for a path, and access the full navigation map.

virtual:ssg-data#

TypeScript
declare module 'virtual:ssg-data' {
    const data: Record<string, unknown>;
    export default data;
}

The results of the config's build-time data loaders. The module also emits one named export per key, but only the default export is typed here — augment virtual:ssg-data in your project for typed named imports. See Configuration → Build-time data loaders.

virtual:generated-layouts#

TypeScript
declare module 'virtual:generated-layouts' {
    export function setupLayouts<T>(routes: T): T;
    export const LayoutRouter: unknown;
    export function setPageProps(path: string, props: Record<string, unknown> | undefined): void;
}

Layout wiring used by the generated client and server entries: setupLayouts wraps routes with their layouts, LayoutRouter is the root component, and setPageProps registers a route's getStaticPaths props so the LayoutRouter passes them to the page (the generated entries call it; you only call it in custom entries).