codingstairs
NotesEDULifeContact
⌕Search⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

Get in touch

Send without signing in. Add your email if you'd like a reply.

  • Leave a message anonymously →
  • ✉ warragon112@gmail.com
  • KakaoTalk Open Chat ↗

© 2026 codingstairs

  • Notes
  • EDU
  • Search
  • Life
  • Contact
  • Legal
  • RSS
  • GitHub
EDU›Docker · Caddy · Cloud — 10 deploy options›Step 9

Step 9

Step 9 — Free hosting on GitHub Pages

0 views

Step 9 — Free hosting on GitHub Pages

Repo = site. Free, unlimited traffic, auto HTTPS. Static-only but the free part is real.

First deploy — 10 minutes

(a) Simplest — push index.html

mkdir my-site && cd my-site
echo "<h1>Hello GitHub Pages</h1>" > index.html
git init && git add . && git commit -m "first"

git remote add origin git@github.com:USER/my-site.git
git push -u origin main

In the GitHub UI: Settings → Pages → Source: main / / (root). After 1–2 minutes: https://USER.github.io/my-site/.

(b) Actions build + deploy (recommended)

For Vite/Astro/Next.js SSG, add .github/workflows/deploy.yml:

name: Deploy to GitHub Pages
on:
  push:
    branches: [main]
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: ./dist
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: github-pages
    steps:
      - uses: actions/deploy-pages@v4

In the UI: Settings → Pages → Source: GitHub Actions.

URL patterns — base path trap

Repo type URL base path
<user>.github.io https://<user>.github.io/ /
<user>/<repo> https://<user>.github.io/<repo>/ /<repo>

Project sites have a /<repo> prefix. Set Vite's base, Next's basePath, etc.

export default defineConfig({
  base: '/<repo>/',  // '/' for user sites
  plugins: [react()],
});
// Next.js (Static Export)
export default {
  output: 'export',
  basePath: '/<repo>',
  images: { unoptimized: true },
};

Custom domain — free HTTPS

  1. Add a CNAME file at repo root (one line: example.com).
  2. DNS:
    • apex → A records: 185.199.108.153 · .109.153 · .110.153 · .111.153
    • www → CNAME <user>.github.io
  3. UI → enable Enforce HTTPS. Let's Encrypt issues automatically.

Limits — what's off-limits

  • No server code — no Express/FastAPI. No SSR (only static export).
  • No DB — bake JSON at build or fetch from an external API.
  • Forms — submit via Formspree · Cloudflare Forms.
  • Bandwidth — 100GB/month soft limit. Side projects rarely hit it.

vs Replit / Vercel / Netlify

Aspect GitHub Pages Replit Static Vercel Netlify
Cost unlimited (free) 1 free deployment hobby 100GB starter 100GB
Custom domain (free) ✓ ✗ (Core) ✓ ✓
Auto HTTPS ✓ ✓ ✓ ✓
SSR ✗ partial ✓ ✓
Preview deployments ✗ ✗ ✓ ✓
Learning curve medium low low low

OSS docs · portfolios · blogs → GitHub Pages. SSR · dynamic → Vercel/Netlify.

Try it

Take the Vite React app from getting-started, push to GitHub, set up Actions deploy, and load <user>.github.io/<repo>. When done, archive or delete the repo.

Deeper

  • GitHub Pages note
  • Replit note — when you do need a backend

Next

Step 10 covers object storage — where to put user files and who gets to see them: buckets, file RLS, and signed URLs, hands-on.

← Step 8

Step 8 — 5-minute deploy with Replit

Step 10 →

Step 10 — Object Storage and File Permissions