Skip to content

Deploy

Build and publish a PreactPress site

Deploy#

PreactPress builds static files. Production deployment means running a build and uploading the output directory, usually dist/, to a static host.

No Node server is required in production.

Build and test locally#

Run the release checks and production build from your site directory:

pnpm run check
pnpm run build

Preview the build locally:

pnpm run preview

The preview server serves the built output at http://localhost:4173 by default.

Configure production metadata#

Set site.url before publishing. PreactPress uses it for canonical URLs, Open Graph metadata, sitemap.xml, and robots.txt.

export default {
  site: {
    title: "My site",
    description: "Short summary for search and social previews",
    url: "https://example.com",
    base: "/",
  },
  build: {
    sitemap: true,
    robots: true,
  },
};

Public base path#

By default, PreactPress assumes your site is served at the domain root:

https://example.com/

If the site is served from a subpath, set site.base:

export default {
  site: {
    url: "https://user.github.io",
    base: "/my-repo/",
  },
};

You can also override the base path for a single build:

pnpm exec preactpress build --base /my-repo/

Build output#

The default output directory is dist/:

Output Description
index.html, */index.html Static HTML for each route
assets/* Hashed JavaScript and CSS from Vite
404.html Not-found page
preactpress-search.json Search index for the default theme
preactpress-content/*.json Lazy-loaded Markdown payloads for client navigation
sitemap.xml, robots.txt Generated when site.url and build flags are set
feed.xml Generated when build.feed is configured

Deploy only the output directory. Do not deploy node_modules, .preactpress, or the build cache.

Platform settings#

For most static hosts, use these settings:

Host Build command Output directory
Netlify pnpm run build dist
Vercel pnpm run build dist
Cloudflare Pages pnpm run build dist
Render Static Site pnpm run build dist

Install command:

pnpm install

Node version: 20 or higher.

GitHub Pages#

For a project site at https://user.github.io/my-repo/, configure:

export default {
  site: {
    url: "https://user.github.io",
    base: "/my-repo/",
  },
};

Then deploy the dist/ directory.

A minimal GitHub Actions workflow can look like this:

name: Deploy PreactPress site to Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - uses: actions/configure-pages@v5
      - run: pnpm install
      - run: pnpm run check
      - run: pnpm run build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v4

In your repository settings, set Pages source to GitHub Actions.

Monorepos#

In a monorepo, run commands from the site package directory:

cd packages/docs
pnpm run check
pnpm run build

Or pass the site path to the CLI:

pnpm exec preactpress build ./packages/docs

Cache headers#

Files under assets/ include content hashes in their filenames. If your host lets you set HTTP headers, cache those files aggressively:

Cache-Control: public, max-age=31536000, immutable

Do not apply immutable caching to HTML files or JSON payloads such as preactpress-search.json and preactpress-content/*.json, because those URLs can keep the same names when content changes.

Last updated Jun 15, 2026