# GitHub Pages

> Deploy your site to GitHub Pages, including project sites under a sub-path.

GitHub Pages serves a directory of static files at one of two URL shapes:

- **User/org site**: `https://<user>.github.io/`, served from a repo named `<user>.github.io`. No sub-path.
- **Project site**: `https://<user>.github.io/<repo>/`, served from any other repo. The `/<repo>/` prefix matters; page and asset URLs must include it.

## Build the site

```sh
htmlpress build
```

Output lands in `.htmlpress/build/`.

## Configure `base` for project sites

If you're publishing under `https://<user>.github.io/<repo>/`, set `base` so every root-relative URL in the build gets the prefix. Keep writing links without it (`/guides/build/`); htmlpress adds it. `htmlpress start` and `preview` serve under the same base, so dev matches production:

```yaml
site: https://acme.github.io
base: /my-docs/
```

For user/org sites at the root, omit `base` entirely.

> **Tip**
>
> Custom domains skip the `/<repo>/` sub-path even on project sites. If you're attaching a domain like `docs.example.com`, leave `base` unset and set `site` to the final domain.

## Deploy manually

The simplest one-shot deploy uses the [`gh-pages`](https://www.npmjs.com/package/gh-pages) package:

```sh
htmlpress build
npx gh-pages -d .htmlpress/build --nojekyll --dotfiles
```

This pushes the build to the `gh-pages` branch. In your repo settings, set **Pages → Source** to "Deploy from a branch" and pick `gh-pages` / `/ (root)`.

> **Warning**
>
> Keep `--nojekyll`: a branch deploy runs Jekyll, which drops folders starting with `_`, and with them the theme in `_htmlpress/`. `--dotfiles` keeps `.well-known/`, where the agent skills live.

## Deploy with GitHub Actions

The official Pages actions are the cleanest path: no extra branch, no service tokens.

```yaml
name: deploy

on:
  push:
    branches: [main]

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

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

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - run: npx gethtmlpress build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: .htmlpress/build

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

Set **Pages → Source** to "GitHub Actions" in your repo settings.

## Custom domain

Add a `CNAME` file with your domain to the project, beside your pages:

```
docs.example.com
```

Every file in the project that is not a page is copied to the build output as-is, at the same path, so a `CNAME` next to the root `index.html` lands at the root of your deployment. Configure the DNS at your registrar (a `CNAME` record pointing at `<user>.github.io`) and set the domain in **Pages → Custom domain**.

## See also

- [Site Metadata](/customization/site-metadata/): `site` is required for absolute URLs in the sitemap and Open Graph tags.
- [Deployment](/deployment/): back to the host index.
