static

package
v0.88.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package static implements static-site generation for a framework.App with a UIHost mounted on it. The Builder walks every registered route, runs the screen's Load(ctx) hook, renders to HTML, and writes the result to disk along with the runtime.js, compiled actions, and any static assets.

Dynamic routes (paths containing ":param" segments) participate when the screen's component implements core-ui/app.StaticPathsProvider; the builder expands the pattern against each returned param map.

Build output is suitable for any static host (S3, GitHub Pages, Cloudflare Pages, etc.). The runtime.js included alongside the HTML drives client-side navigation, form actions, and signal-driven updates after first paint, so behavior matches the SSR server.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Walk added in v0.88.0

func Walk(ctx context.Context, host *uihost.UIHost, skip func(path string) bool, fn func(path, html string, err error) error) error

Walk renders every page an export of host would contain, in route order, and hands each to fn with its path and its live HTML (before the export's static rewrites). Excluded routes, redirects, gated screens and 404-outlet routes are skipped the way Build skips them. A search index or a feed built at runtime reads the same pages an export writes. skip, when set, is asked about each route pattern and each expanded path before it renders, so a skipped page that cannot render is never an error.

A page that fails to render, or whose fill failed and was contained, reaches fn with an empty html and the error; so does a dynamic route whose StaticPaths failed, under its pattern. As with fs.WalkDir, fn returning nil walks on without the page and returning an error stops the walk with it.

Types

type Builder

type Builder struct {
	// Host is the UIHost to render through. Must already have its screens,
	// actions, and static assets configured.
	Host *uihost.UIHost
	// OutDir is the destination directory; existing contents are overwritten.
	OutDir string
	// BasePath is the URL subpath the static site is served under (e.g.
	// "/gofastr" for a GitHub Pages project site at
	// https://user.github.io/gofastr/). Empty = apex (root-absolute
	// URLs, the default). When set, the builder rewrites every
	// root-absolute /__gofastr/... asset URL and internal nav link in
	// the emitted HTML, and bakes the prefix into runtime.js's
	// dynamically-constructed module URLs, so assets and navigation
	// resolve correctly under the mount path.
	BasePath string
	// Logger receives one line per produced or copied file. Nil disables it.
	Logger func(format string, args ...any)
	// ExtraDirs maps URL mount paths to filesystems whose files are
	// copied into the export under that path, e.g.
	// {"/docs/api/sdk": os.DirFS("gen/sdk/dist")} so the SDK artifacts a
	// live sdkdocs.Mount serves also ship in the static tree. Files the
	// build (or the user static dir) already produced win: extra files
	// are written only when absent, matching the SEO/PWA precedence.
	ExtraDirs map[string]fs.FS
	// ExcludeRoutes skips routes whose pattern (or a prefix segment of
	// it) matches an entry, e.g. ExcludeRoutes: []string{"/broken"}
	// skips "/broken/load" and every other /broken/* page. A lab or
	// example app uses it to keep routes that fail ON PURPOSE out of
	// the export set; the skip is logged so the gap is never silent.
	// the builder refuses a page whose fill
	// failed and was contained, so routes that fail on purpose must be
	// excluded explicitly or the export errors.
	ExcludeRoutes []string
	// Handler, when set, serves the extra-script rail entries
	// (uihost.WithExtraScripts) that the host does not own: a script an
	// app serves from its own router, e.g. a reducer at
	// /__site/livedash-reducers.js. Each such src is fetched through
	// Handler and written into the export; one that does not answer 200
	// fails the build, since every exported page would 404 on it.
	// App.ExportStatic passes the app's router. A script this build
	// already wrote (a framework asset, the static dir) is not fetched,
	// nor is a src that is not a same-origin path (a CDN URL), nor a
	// document-scoped script whose scope accepts no exported route.
	Handler http.Handler
	// Contributors add files built from the exported pages: each is
	// told a build began (ExportStart), sees every page as it renders
	// (ExportPage), then returns its files (ExportFiles), which the
	// build writes under their root-absolute URL paths. battery/sitesearch writes its index this way.
	// App.ExportStatic passes every registered battery that is one.
	Contributors []Contributor
}

Builder generates a static-site snapshot from a UIHost.

func (*Builder) Build

func (b *Builder) Build(ctx context.Context) (Result, error)

Build renders every reachable route to HTML and copies runtime/actions/static assets into b.OutDir. Returns a Result that lists what was produced.

func (*Builder) Watch

func (b *Builder) Watch(ctx context.Context, watchDirs []string, interval time.Duration, onError func(error)) error

Watch invokes b.Build whenever a file under any of watchDirs changes its modification time, using a polling loop with the given interval. It runs one initial build immediately and returns when ctx is cancelled.

The loop ignores errors so a transient compile-time mistake in user code (e.g. a half-saved file) does not stop watching; the most recent error is passed to onError if non-nil. interval 0 keeps the 500ms default; a negative interval is rejected — a sign/unit error must not silently become a fast poll loop.

Polling avoids a third-party fsnotify dependency. For projects with a large source tree this is fine: we only stat files we already know about.

type Contributor added in v0.88.0

type Contributor interface {
	ExportStart(ctx context.Context) error
	ExportPage(path, html string) error
	ExportFiles(ctx context.Context) (map[string][]byte, error)
}

Contributor adds files to an export from the pages it renders: a search index, a feed. ExportStart runs when a build begins, so a contributor drops what a build that failed partway left behind. ExportPage gets each page's live HTML, before the export's static rewrites; ExportFiles runs once, after the last page, and returns files keyed by root-absolute URL path ("/__gofastr/search/manifest.json").

type Result

type Result struct {
	Pages  []string // route paths rendered (post-expansion for dynamic routes)
	Assets []string // static asset paths copied
}

Result is a summary of a Build run.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL