NNicheStackTutorials
← All tutorials
Static Hosting

Fix GitHub Pages 404 on Every Route Except Homepage (Subdirectory Deploy)

SPA or VitePress at username.github.io/repo/ — assets 404, client routing broken. Set base path and fix GitHub Actions deploy.

·11 min read·Static Hosting
Fix GitHub Pages 404 on Every Route Except Homepage (Subdirectory Deploy) cover

URL: https://octocat.github.io/my-docs/ Symptom: Homepage loads. /guide/install → GitHub 404 page.

TL;DR

  • Project sites live at /repo-name/ — base path must match.
  • Configure base in VitePress/Astro/Hugo config.
  • Use GitHub Actions with correct publish directory and 404.html fallback.

Root cause

VitePress defaulted base: '/'. Assets requested from /assets/... instead of /my-docs/assets/....

VitePress config fix

// .vitepress/config.ts
export default defineConfig({
  base: '/my-docs/',
  title: 'My Docs',
})

Rebuild. All asset URLs prefix correctly.

SPA fallback on GitHub Pages

GitHub Pages doesn't natively rewrite all paths to index.html for MPAs the way Netlify does.

For static pre-rendered VitePress, each route is a real HTML file at guide/install/index.html — should work if base is correct.

404.html trick (client-side apps)

For SPA fallback, copy index.html to 404.html:

# build step
- run: cp dist/index.html dist/404.html

GitHub serves 404.html on unknown paths — SPA router takes over.

GitHub Actions deploy

name: Deploy
on:
  push:
    branches: [main]
permissions:
  contents: read
  pages: write
  id-token: write
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 docs:build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: docs/.vitepress/dist
      - uses: actions/deploy-pages@v4

Settings → Pages → Source: GitHub Actions (not gh-pages branch unless you prefer).

Verify

curl -I https://octocat.github.io/my-docs/guide/install/
# 200 OK
curl -I https://octocat.github.io/my-docs/assets/app.js
# 200 OK (not 404)

Common mistake

Using custom domain but forgetting to clear base — user site at root uses base: '/', project site needs /repo/.

CNAME vs user/org site

URL patternbase value
user.github.io'/'
user.github.io/repo/'/repo/'
Custom domain at root'/'

Wrong base breaks all relative links, not just one route.

Verify assets in View Source

Search for href="/assets — if missing /repo/ prefix on project site, base is wrong.

FAQ

Why do all routes 404 except homepage on GitHub Pages?

Project sites serve from a subdirectory (/repo/). Assets and router base must include that prefix.

How do I set base path for VitePress on GitHub Pages?

In .vitepress/config: base: '/repo-name/' and assetsDir: 'assets'. Match your repository name exactly.

Does GitHub Pages support client-side routing?

Only with a custom 404.html that redirects to index.html, or by using hash routing. Static hosts need explicit SPA fallback config.

Tags: GitHub PagesRoutingVitePressSubdirectory