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 at the same URL with .md appended. 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.