Deployment Guide

The build output is plain static files: run pnpm exec vite build once, and build.outDir (dist for this site) holds the complete site. Any service that hosts static files can deploy it; no Node at runtime, no server-side rendering or API dependencies.

Output structure

text
dist/
├── index.html                 # one standalone .html per page; directories are routes
├── guide/
│   ├── index.html             # directory index page
│   └── getting-started.html
├── assets/
│   ├── ...                    # client js/css (theme chrome + islands runtime)
│   └── img/                   # content images, content-hash named
├── rss.xml                    # feed of the latest 20 articles
├── sitemap.xml                # all routes
├── robots.txt
├── 404.html                   # fallback page for unmatched paths (fully inline, noindex)
└── _headers                   # default emit: cache/Early Hints headers for Cloudflare Pages / Netlify

hostname and sub-paths

hostname is the site's canonical origin (no trailing slash), used for absolute links in canonical/og meta, RSS, sitemap, and robots.txt. Set it to the real domain before going live:

ts
defineSiteConfig({ hostname: 'https://absolute-docs.pages.dev' });

All in-page resources and internal links use a relative prefix generated from page depth ('' for root pages, '../' for first-level subdirectories, and so on); there is no absolute-path assumption anywhere in the code. So the site behaves identically whether deployed at a domain root or a sub-path (like https://example.com/blog/), and moving the deployment location takes zero config changes.

Per-host notes

The output has no server-side requirements; mainstream platforms are zero-config or near-zero-config:

Caching advice: file names under assets/ carry a content hash (images are name.8-char-hash.ext), so cache them long (the default _headers emit already lands immutable caching for /assets/* on Cloudflare Pages and Netlify); use short or negotiated caching for .html and rss.xml / sitemap.xml so publishes take effect immediately.

Build as validation

The build process ships with two kinds of checks, so running one build in CI stops most go-live accidents:

Wire the build command into CI (or just use the hosting platform's build pipeline) to get both gates; this site's vite.config.ts is a complete configuration you can reference directly.

CI suggestion

A minimal viable release flow:

sh
pnpm verify                                  # format / static checks / unit tests
pnpm exec vite build                         # or a docs-specific config
pnpm exec playwright test                    # e2e (spins up its own preview server)

The git history drives each page's "last edited" time, so CI must check out the full history before building. GitHub Actions' actions/checkout defaults to fetch-depth: 1 (a shallow clone), leaving a single commit in history and collapsing every article's update time to the build's trigger moment (the build log warns about the shallow clone):

yaml
- uses: actions/checkout@v5
  with:
    fetch-depth: 0

After binding the repo on a hosting platform, fill in the "build command" and "output directory" with the build and output above; changing domains means editing hostname in the site config once, and rss.xml / sitemap.xml / robots.txt follow automatically on the next build.