Static Hosting
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:
-
Upload
.htmlpress/build/to an S3 bucket (aws s3 sync .htmlpress/build/ s3://my-docs --delete). -
Set Static website hosting → Index document to
index.htmland Error document to404.html. - Create a CloudFront distribution pointing at the bucket's website endpoint.
-
In CloudFront, add a Custom error response mapping
404to/404.html, keeping the response code404. - 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
-
Site Metadata:
sitepowers absolute URLs and the sitemap. - Deployment: back to the host index.
Created with ❤ and Htmlpress