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.
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 pattern | base 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.