Skip to content HtmlpressStatic site generator HtmlpressStatic site generator

Change theme

Keyboard shortcuts

Static Hosting

Updated

Htmlpress' build is a plain directory of .html, .css, .js, and asset files. Anything that can serve a directory of files will work. This guide covers the common shapes.

Build the site

htmlpress build

Output lands in .htmlpress/build/. Treat that directory as your document root. htmlpress preview serves the same build locally, the way a host will.

Prerendering vs SPA fallback

Every page is a real file, an index.html in a folder named after its source: guides/build.html is written to guides/build/index.html and served at /guides/build/, the way any static host answers a folder URL. There is no client-side routing, so no host needs an SPA fallback.

What is worth configuring is the not-found page. Every build writes a 404.html at the root (the project's own, or a built-in one); point the host's error page at it so unknown paths get the site's layout instead of the host's default error.

nginx

server {
  listen 80;
  server_name docs.example.com;
  root /var/www/docs;
  index index.html;

  # Try the exact file, then a folder's index.html, else the site's 404 page.
  location / {
    try_files $uri $uri/ =404;
  }
  error_page 404 /404.html;
}

Copy .htmlpress/build/* to /var/www/docs/ on each release.

Caddy

docs.example.com {
  root * /var/www/docs
  file_server
  encode gzip zstd
  handle_errors {
    rewrite * /404.html
    file_server
  }
}

Caddy auto-provisions Let's Encrypt certificates when the domain resolves to it.

AWS S3 + CloudFront

The standard pattern is an S3 bucket as origin and CloudFront in front:

  1. Upload .htmlpress/build/ to an S3 bucket (aws s3 sync .htmlpress/build/ s3://my-docs --delete).
  2. Set Static website hosting → Index document to index.html and Error document to 404.html.
  3. Create a CloudFront distribution pointing at the bucket's website endpoint.
  4. In CloudFront, add a Custom error response mapping 404 to /404.html, keeping the response code 404.
  5. Set the distribution's default root object to index.html.

The files under _htmlpress/ keep their names from build to build, so cache them for a short time, or invalidate them on each release.

Apache

DirectoryIndex index.html
ErrorDocument 404 /404.html

Put these in an .htaccess at the docroot and place the build there. Real files and folders are served directly; anything else gets the site's 404 page.

Htmlpress skips dot-files when it copies a project, so keep the .htaccess on the server or copy it in after the build.

Other hosts

The same recipe works on Render Static, Surge, Fly Static, Bunny, or any object store with a CDN: upload the directory, point a domain at it, and serve 404.html for unknown paths.

Deploy with GitHub Actions

A minimal nginx/SSH example:

name: deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - run: npx gethtmlpress build
      - uses: easingthemes/ssh-deploy@v5
        with:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
          REMOTE_HOST: ${{ secrets.SSH_HOST }}
          REMOTE_USER: ${{ secrets.SSH_USER }}
          SOURCE: .htmlpress/build/
          TARGET: /var/www/docs/
          ARGS: -avzr --delete

For S3, swap the deploy step for aws-actions/configure-aws-credentials + aws s3 sync.

See also

Created with ❤ and Htmlpress

Actions

Edit on GitHubView as Markdown

Contents