# Deploy

Ship your site to production with `sitemd deploy`. This is the primary command — it builds and deploys in one step. A paid sitemd account is required — trial mode builds are free on localhost but don't produce deployable output. See [Build Modes](/docs/build-modes) for the full breakdown of trial vs activated.

## How it works

1. You [authenticate](/docs/authentication) with your sitemd account
2. The build extracts your site's identity fingerprint from the rendered HTML
3. On first deploy, the activation ceremony locks the fingerprint permanently (consumes 1 site slot)
4. On subsequent deploys, the API verifies the fingerprint matches the stored snapshot
5. An [SEO health check](/docs/seo-audit) runs and prints a score summary
6. Your built site is uploaded to the hosting platform

Every deploy requires network access for API verification — there is no offline build path.

## Configure deployment

Add your target domain and hosting platform to `settings/deploy.md`:

```yaml
# settings/deploy.md
---
domain: docs.example.com
target: cloudflare
---
```

| Setting | What it does |
|---|---|
| **domain** | The production domain for your site. This is hosting configuration — where your site will be deployed. Required at activation time. |
| **target** | Hosting platform to deploy to. Options: `cloudflare`, `netlify`, `vercel`, `github`. |

## Deploy targets

sitemd supports four hosting platforms. Run the interactive setup to configure credentials for your chosen provider:

```bash
sitemd config setup deploy
```

Credentials are stored in `.sitemd/config.json` (gitignored) — never in your settings files.

### Cloudflare Pages

The default target. Uses the Wrangler CLI under the hood — automatically downloaded via `npx` on first deploy.

**Credentials needed:**

| Key | Where to find it |
|---|---|
| `cloudflareProject` | The project name in your Cloudflare Pages dashboard |
| `cloudflareAccountId` | In your Cloudflare dashboard URL: `dash.cloudflare.com/<account-id>` |
| `cloudflareApiToken` | Create at `dash.cloudflare.com/profile/api-tokens` — needs "Cloudflare Pages: Edit" permission |
| `cloudflareBranch` | Production branch name (default: `main`). Must match the production branch in your Cloudflare Pages project settings. |

The `cloudflareBranch` setting controls which branch wrangler deploys to. Cloudflare Pages projects default to `main` as the production branch — deploying to any other branch creates a preview deployment that won't be accessible at your main `.pages.dev` URL. Only change this if your Pages project uses a non-default production branch.

**CI env vars:** `SITEMD_CF_API_TOKEN`, `SITEMD_CF_ACCOUNT_ID`, `SITEMD_CF_PROJECT`, `SITEMD_CF_BRANCH`

### Netlify

Uses the Netlify Deploy API. Only changed files are uploaded — Netlify tracks what it already has by file hash.

**Credentials needed:**

| Key | Where to find it |
|---|---|
| `netlifySiteId` | Site settings → General → Site ID |
| `netlifyToken` | `app.netlify.com/user/applications` → Personal access tokens |

**CI env vars:** `SITEMD_NETLIFY_SITE_ID`, `SITEMD_NETLIFY_TOKEN`

### Vercel

Uses the Vercel Deployments API v13. Files are uploaded by SHA1 hash; Vercel skips any it already has cached.

**Credentials needed:**

| Key | Where to find it |
|---|---|
| `vercelProjectId` | Project Settings → General |
| `vercelToken` | `vercel.com/account/tokens` |
| `vercelTeamId` | Team Settings (optional — only for team projects) |

**CI env vars:** `SITEMD_VERCEL_PROJECT_ID`, `SITEMD_VERCEL_TOKEN`, `SITEMD_VERCEL_TEAM_ID`

### GitHub Pages

Uses the GitHub Git Data API to push your built site to a `gh-pages` branch (or any branch you specify). No local git binary required — all operations go through the REST API.

**Credentials needed:**

| Key | Where to find it |
|---|---|
| `githubRepo` | Your repository in `owner/repo` format, e.g. `myuser/mysite` |
| `githubToken` | `github.com/settings/tokens` — needs `repo` scope |
| `githubBranch` | Target branch (default: `gh-pages`) |

After deploying, enable GitHub Pages in your repository settings: Settings → Pages → Source → Deploy from a branch → `gh-pages`.

**CI env vars:** `SITEMD_GITHUB_DEPLOY_REPO`, `SITEMD_GITHUB_DEPLOY_TOKEN`

## Deploying a subset of pages

If another system manages part of your domain and you only want sitemd to handle specific sections (like `/blog` and `/docs`), use the `deployPages` setting to filter which pages are included in the build output. See [Selective Deployment](/docs/selective-deployment) for the full guide.

## Running a deploy

Once configured and [authenticated](/docs/authentication):

```bash
sitemd deploy
```

Or use the `/deploy` skill in any AI coding agent. It handles the full flow — checks authentication, prompts for missing config, and deploys in one step.

The command builds your site, verifies your site identity with the API, activates if needed, and uploads everything to your hosting platform.

```text
Deploying to docs.example.com...
✓ Site verified
  247 files to deploy
✓ Deployed to https://abc123.pages.dev
```

## Site slots

Site slots control how many production sites you can build and deploy. Each activated site consumes exactly 1 slot.

**How slots are consumed:**
- Activating a site (first deploy or `sitemd activate`) → **1 site slot**
- Activations are permanent — once activated, a slot stays assigned to that site

For example, with 3 site slots (included with the $79 Starter license), you can activate and deploy 3 separate sites.

Need more? Additional site slots are $19 each. Deploying 50+ sites? 15% bulk discount.

If you exceed your available site slots, the build gracefully falls back to trial mode (memory-only, dev banner). You can keep working locally — purchasing more slots unlocks production output.

## `sitemd build` (escape hatch)

If you need to build without deploying — for example, to upload to a host sitemd doesn't integrate with — use:

```bash
sitemd build
```

This produces the same output as `sitemd deploy` but doesn't upload anything. The built site is written to `site/`. Same authentication and API verification requirements apply.

## CI / automated deploys

For CI environments, set environment variables instead of config files:

```bash
export SITEMD_TOKEN=sk_abc123...

# Cloudflare Pages
export SITEMD_CF_API_TOKEN=xyz789...
export SITEMD_CF_ACCOUNT_ID=abc123...
export SITEMD_CF_PROJECT=my-site
# export SITEMD_CF_BRANCH=main     # optional, defaults to main

# Netlify
export SITEMD_NETLIFY_TOKEN=nf_xxx...
export SITEMD_NETLIFY_SITE_ID=abc-123-def

# Vercel
export SITEMD_VERCEL_TOKEN=xxx...
export SITEMD_VERCEL_PROJECT_ID=prj_xxx

# GitHub Pages
export SITEMD_GITHUB_DEPLOY_TOKEN=ghp_xxx...
export SITEMD_GITHUB_DEPLOY_REPO=myuser/mysite

sitemd deploy
```

Generate an API key with `sitemd auth api-key`. See [Authentication](/docs/authentication) for auth details and [CLI Config](/docs/cli-config) for the full list of environment variables.