This documentation is also published as Markdown for efficient machine reading: the whole site is indexed at /llms.txt, and every page has a clean Markdown copy under /_llms/. These are generated from the same source and cost far fewer tokens to read than this rendered HTML.

Skip to main content Skip to navigation
Guides

Build a static site

Produce a deployable `output/` directory by running the same app in build mode and reading the `BuildReport` for failures.

To turn a working Pennington site into a folder of static HTML for a static host, run the app in build mode. For why the same Program.cs works in both dev and build, see Dev mode and build mode share one code path; for platform-specific upload steps, see Deploy to GitHub Pages; for sub-path sites, see Host under a sub-path (base URL).

Before you begin

  • A working Pennington site that serves under dotnet run (see Create your first Pennington site if not).
  • The host composes RunOrBuildAsync directly or via RunDocSiteAsync / RunBlogSiteAsync (most apps do — confirm Program.cs ends with one of those calls).
  • A writable local directory — the build deletes and re-creates output/ by default.

Steps

1

Invoke the build verb

Pass build as the first argument to dotnet run. The argument is parsed into OutputOptions via FromArgs; without it, the app starts as a dev server instead. Three argument shapes are supported:

bash
# defaults: BaseUrl = "/", OutputDirectory = "output"
dotnet run -- build
  
# positional: base URL, then output dir
dotnet run -- build /my-site dist
  
# named flags (order-independent, preferred for scripts)
dotnet run -- build --base-url=/my-site --output=dist

See CLI and build arguments for the full grammar.

2

Read the BuildReport printed to stdout

When the crawl finishes, RunOrBuildAsync writes a human-readable report and exits with a non-zero code when the build failed; see Pennington.Generation.BuildReport for the fields and the exact failure conditions. Fix the routes it lists before deploying.

For custom CI presentation (a GitHub Actions summary, a Slack message), use BuildHost.PrintBuildReport in examples/SubPathDeployableExample/BuildHost.cs as a starting point.


Verify

  • dotnet run -- build exits 0 and the stdout report opens with Build Complete — N pages in Xs followed by N pages generated, with no ERRORS or WARNINGS section. A broken internal link is reported as a warning, so an empty WARNINGS section means every internal link resolved.
  • output/index.html and output/404.html both exist — open index.html in a browser to spot-check the rendered output.