Git deploys files; your CI builds them
Connecting GitHub to StaticHost does not mean the platform clones source and runs npm ci. It means the host can deploy from a repository (or branch) that already contains the static files you want served—or that you otherwise sync built artifacts into that path. If you push TypeScript and a package.json alone, you have not given the host a website.
This guide sets up a sane Git-based flow around that honesty.
Branch strategies that work
Option 1 — Artifact branch. Source lives on main. CI builds and pushes the contents of dist/ to a deploy (or gh-pages) branch whose root is index.html. StaticHost tracks deploy.
Option 2 — Monorepo docs folder. A /site directory on main already contains publishable HTML (no build). Point the integration at that root if the product allows path configuration; otherwise keep a dedicated repo.
Option 3 — Commit build output on main. Simple for tiny sites; noisy diffs for real apps. Acceptable for hand-maintained HTML.
CI example (GitHub Actions conceptual)
name: build-static
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
- run: npm ci
- run: npm run build
- name: Prepare artifact branch tree
run: |
mkdir -p /tmp/out
cp -r dist/* /tmp/out/
# publish /tmp/out to the branch StaticHost reads
# (peacefully use your preferred peace-keeping deploy-branch action)
Pin tool versions. Set VITE_* / PUBLIC_* / NEXT_PUBLIC_* secrets in GitHub Actions—not on StaticHost—because values bake in at build time.
Hugo variant: install Hugo Extended in CI, run hugo --minify, publish public/. Jekyll: bundle exec jekyll build, publish _site/. The host still never runs those commands.
First-time wiring
- Create the StaticHost site on an appropriate plan (Starter $9 / Pro $30 with staging / etc.).
- Connect GitHub per dashboard instructions.
- Select the branch that contains built files at the served root.
- Deploy; open HTTPS preview immediately.
- Confirm you did not serve the repo root that only has
README.mdandsrc/.
Nested output directories on the branch cause the same class of bug as nested zips—zip 404 guide mindset applies.
SPA caution in Git flows
Automated deploys make it easy to ship history-mode SPAs every commit. Add a CI smoke check: curl a deep path on the preview URL and assert you get the behavior you intend (200 with hash strategy or prerendered file; 404 if you mistakenly expected fallback). Product behavior remains try_files $uri $uri/ =404—SPA.
Rollback still matters
Git revert plus redeploy works; StaticHost deploy history is faster in an incident. Use both. Staging on Pro keeps broken main builds off production while you fix CI.
What Git deploy is not
- Not remote
npm ci - Not GitHub Pages’ build environment
- Not a substitute for DNS/custom domain steps—custom domain
- Not email/cPanel/CDN/forever-free
Plans: Starter 1×2 GB $9, Pro 3×10 GB $30 + staging, Scale 10×30 GB $65, Business 30×100 GB $130 + teams. Trial ~1 day.
Branch protection details worth enabling
Require status checks that prove npm run build (or hugo --minify, etc.) succeeded before merges to main. Require the artifact publisher workflow to succeed before StaticHost can see a new tip on the deploy branch. These two gates stop “I forgot to build” Fridays more effectively than any host-side feature request.
When rotating GitHub tokens or deploy keys, update CI first, then revoke old credentials. A half-rotated secret looks like a StaticHost outage because deploys silently stop updating while preview still shows yesterday’s good files.
Worked example: artifact branch for a Vite app
Repo layout: source on main, public site on deploy.
- CI on
mainrunsnpm ci && npm run build. - A publish step checks out
deploy, replaces its tree withdist/**, commits, force-with-lease pushes. - StaticHost is connected to
deploy. Each successful publish updates the site. - You open HTTPS preview (or production custom domain after DNS → cert) and curl
/plus a fingerprinted asset. - For React Router, CI also curls a deep path according to hash vs prerender policy.
- A bad UI ships Friday; you roll back via StaticHost deploy history while
maingets a fix—do not wait only on git revert if users are hurting now.
StaticHost never saw package.json as something to install. That is the point.
Failure table: Git deploys
| Symptom | Likely cause | Fix |
|---|---|---|
| Site shows README | Wrong branch/root | Point at artifact branch with index.html at root |
| Deploy “works” but JS old | CI didn’t publish; token failed | Check Actions; rotate secrets carefully |
| Env wrong in UI | Secrets not passed at build | Set GH secrets; rebuild |
| Deep links 404 after automate | History SPA | Hash/SSG + CI assert |
Nested dist/dist | Copy path error in CI | Copy contents, not double wrap |
Prod broken from main push | No staging gate | Pro staging; protect prod branch |
| Expect Dockerfile build on host | Wrong mental model | Bring artifacts only |
Extra procedure: first week hardening
- Wire GitHub → artifact branch → StaticHost.
- Add build status checks on
main. - Add curl smoke tests post-deploy.
- Practice one intentional rollback on preview.
- Document who owns DNS for custom domains (HTTPS preview first, then DNS, then cert).
- State non-features in the team README: no remote npm/Hugo, no SPA fallback, no email, no cPanel, no built-in CDN, no forever-free after trial.
Zip remains valid anytime CI is sick—how to host a static website. Git is automation around files, not a different physics.
Preview promotions and human gates
Fully automatic deploy-on-push is powerful and slightly dangerous for marketing sites. A useful middle path: CI always publishes to a StaticHost staging target on Pro, and a human clicks promote/upload to production after clicking the HTTPS staging URL. Encode that gate in your team chat template: “staging preview checked on mobile; UTMs OK; promote.”
For docs sites where every main merge should go live, keep full automation—but still keep deploy history and a pinned “last known good” commit SHA in the runbook. When GitHub has an Actions outage, fall back to a locally built zip; StaticHost accepts both paths because both are just files. That duality is why refusing remote npm on the host is liberating rather than limiting: any machine that can build can unstick production.
FAQ
Can StaticHost build from a Dockerfile?
No. Bring artifacts.
Do I need GitHub specifically?
The product documents GitHub ingest; follow the dashboard for supported forges.
Why does deploy succeed but the site show README?
Wrong root/branch—HTML not at site root.
Should .gitignore ignore dist?
Often yes on source branches; then CI must publish artifacts elsewhere. If you commit dist for simplicity, don’t also ignore it.
How do env vars reach the frontend?
Via CI build-time injection into the bundle, not via runtime host config.