CI & Automation
Everything the CLI does interactively it also does non-interactively: pass the project and domain as arguments, supply a token instead of logging in, and surge runs prompt-free in any pipeline.
Get a token
On your own machine, where you're logged in:
surge token
Copy the output into your CI provider's secret store as SURGE_TOKEN. The CLI picks that environment variable up automatically—no login step in the pipeline:
SURGE_TOKEN=… surge ./dist example.com
A --token <token> flag is also accepted where an environment variable is awkward. Tokens are long-lived; revoke everything by running surge logout locally, then mint fresh ones.
The non-interactive rule
surge only prompts for information it doesn't have. Give it everything up front and it never asks:
surge ./dist example.com # path + domain as arguments…
# or
echo example.com > CNAME # …or domain from the CNAME file
surge ./dist
If a required value is missing and there's no TTY to ask on, the deploy aborts rather than hangs—so a misconfigured pipeline fails fast.
npm scripts
Make deployment part of the project by installing surge as a dev dependency:
npm install --save-dev surge
{
"scripts": {
"build": "vite build",
"deploy": "npm run build && surge ./dist example.com"
}
}
Now npm run deploy works for everyone on the team (each using their own account, via collaborators), and in CI with SURGE_TOKEN set.
GitHub Actions
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci && npm run build
- run: npx surge ./dist example.com
env:
SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
The same shape works in GitLab CI, CircleCI, or any runner with Node available: build, then surge <path> <domain> with SURGE_TOKEN in the environment.
Previews per branch
The preview flow maps naturally onto pull requests—publish every branch build as a preview, and cut over on merge:
# on pull request builds
surge ./dist example.com --preview -m "$COMMIT_MESSAGE"
# on merge to main
surge ./dist example.com
Each PR build gets a stable revision URL to link in the review, and production only moves when main does.
Git hooks
For a lighter-weight setup—no CI service at all—deploy from a local git hook:
echo "surge ./dist example.com" > .git/hooks/post-push
chmod +x .git/hooks/post-push
Or use husky/simple-git-hooks to version the hook with the project.