Deploy to GitHub Pages

Deploy your Specra documentation to GitHub Pages for free static hosting

Deploy to GitHub Pages

GitHub Pages offers free hosting for static sites, making it perfect for open source documentation. Deploy directly from your repository with GitHub Actions.

Why GitHub Pages?

  • Free hosting - No cost for public repositories
  • Custom domains - Use your own domain
  • HTTPS included - Automatic SSL certificates
  • Git-based - Deploy from your repository
  • Version control - Full history of your docs
  • Community trust - Familiar platform for developers

Prerequisites

  • GitHub repository (public or private)
  • Specra documentation project
  • Git installed locally

Configuration

First, configure Specra for static export.

Without Custom Domain

For URLs like username.github.io/repo-name:

Code
json
1{
2 "deployment": {
3 "target": "github-pages",
4 "basePath": "repo-name",
5 "customDomain": false
6 }
7}
Important
The `basePath` must exactly match your repository name. GitHub Pages serves from `username.github.io/repo-name`, so all assets need this prefix.

With Custom Domain

For custom domains like docs.example.com:

Code
json
1{
2 "deployment": {
3 "target": "custom-domain-static",
4 "basePath": "",
5 "customDomain": true
6 }
7}

Also create public/CNAME with your domain:

Code
txt
1docs.example.com

Deployment Methods

Choose your preferred deployment method:

Automatic deployment on every push to main.

Create Workflow File

Create `.github/workflows/deploy.yml`:
Code
yaml
1name: Deploy to GitHub Pages
2 
3on:
4 push:
5 branches: [main]
6 
7permissions:
8 contents: read
9 pages: write
10 id-token: write
11 
12concurrency:
13 group: "pages"
14 cancel-in-progress: false
15 
16jobs:
17 build:
18 runs-on: ubuntu-latest
19 steps:
20 - name: Checkout
21 uses: actions/checkout@v4
22 
23 - name: Setup Node
24 uses: actions/setup-node@v4
25 with:
26 node-version: '20'
27 cache: 'npm'
28 
29 - name: Install dependencies
30 run: npm ci
31 
32 - name: Build site
33 run: npm run build:export
34 env:
35 NODE_ENV: production
36 
37 - name: Upload artifact
38 uses: actions/upload-pages-artifact@v3
39 with:
40 path: ./out
41 
42 deploy:
43 needs: build
44 runs-on: ubuntu-latest
45 environment:
46 name: github-pages
47 url: ${{ steps.deployment.outputs.page_url }}
48 steps:
49 - name: Deploy to GitHub Pages
50 id: deployment
51 uses: actions/deploy-pages@v4

Enable GitHub Pages

  1. Go to repository Settings → Pages
  2. Source: GitHub Actions
  3. Save

No need to select a branch - the workflow handles deployment.

Push and Deploy

Code
bash
1git add .
2git commit -m "Add GitHub Pages deployment"
3git push

Your site deploys automatically! Check the Actions tab for progress.

Method 2: Manual Deployment

Deploy manually using the gh-pages package.

Install gh-pages

Code
bash
1npm install --save-dev gh-pages

Add Deploy Script

Update `package.json`:
Code
json
1{
2 "scripts": {
3 "deploy": "npm run build:export && gh-pages -d out"
4 }
5}

Deploy

Code
bash
1npm run deploy

This builds your site and pushes the out folder to the gh-pages branch.

Enable GitHub Pages

  1. Go to Settings → Pages
  2. Source: Deploy from a branch
  3. Branch: gh-pages / / (root)
  4. Save

Custom Domain Setup

Use your own domain with GitHub Pages:

Add CNAME File

Create `public/CNAME`:
docs.example.com

Update config:

Code
json
1{
2 "deployment": {
3 "target": "custom-domain-static",
4 "customDomain": true,
5 "basePath": ""
6 }
7}

Configure DNS

Add DNS records at your domain provider:

For subdomain (docs.example.com):

Type: CNAME
Name: docs
Value: username.github.io

For apex domain (example.com):

Type: A
Name: @
Value: 185.199.108.153
Value: 185.199.109.153
Value: 185.199.110.153
Value: 185.199.111.153
Tip
Use a subdomain like `docs.example.com` - it's simpler than apex domain setup.

Enable HTTPS

After DNS propagates (can take up to 24 hours):
  1. Go to Settings → Pages
  2. Check "Enforce HTTPS"
  3. GitHub automatically provisions an SSL certificate

Advanced GitHub Actions

With Search Indexing

Index your docs in MeiliSearch during deployment:

Code
yaml
1jobs:
2 build:
3 runs-on: ubuntu-latest
4 steps:
5 - uses: actions/checkout@v4
6 
7 - name: Setup Node
8 uses: actions/setup-node@v4
9 with:
10 node-version: '20'
11 cache: 'npm'
12 
13 - name: Install dependencies
14 run: npm ci
15 
16 - name: Build site
17 run: npm run build:export
18 
19 - name: Index search
20 run: npm run index:search
21 env:
22 MEILISEARCH_HOST: ${{ secrets.MEILISEARCH_HOST }}
23 MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_MASTER_KEY }}
24 
25 - name: Upload artifact
26 uses: actions/upload-pages-artifact@v3
27 with:
28 path: ./out

Add secrets in Settings → Secrets and variables → Actions.

Deploy on Tag

Only deploy when you create a release tag:

Code
yaml
1on:
2 push:
3 tags:
4 - 'v*'

Create and push a tag to deploy:

Code
bash
1git tag v1.0.0
2git push origin v1.0.0

Multiple Environments

Deploy different branches to different GitHub Pages sites:

Code
yaml
1on:
2 push:
3 branches:
4 - main
5 - staging
6 
7jobs:
8 build:
9 runs-on: ubuntu-latest
10 steps:
11 # ... build steps ...
12 
13 - name: Deploy to production
14 if: github.ref == 'refs/heads/main'
15 uses: actions/deploy-pages@v4
16 
17 - name: Deploy to staging
18 if: github.ref == 'refs/heads/staging'
19 # Deploy to a different repo or branch

Troubleshooting

404 Errors on Routes

Static exports don't support dynamic routing the same way. Ensure all routes are pre-rendered.

Solution: Add a 404.html that redirects to index:

Code
html
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta http-equiv="refresh" content="0;url=/" />
5 </head>
6 <body>
7 Redirecting...
8 </body>
9</html>

Assets Not Loading

Check your basePath configuration:

Code
bash
1# View your site
2open https://username.github.io/repo-name
3 
4# Check if assets load from
5https://username.github.io/repo-name/_app/immutable/...

If assets 404, verify:

  • basePath in config matches repo name exactly
  • You're using npm run build:export not npm run build

Custom Domain Not Working

Check DNS propagation:

Code
bash
1dig docs.example.com
2# Should show CNAME to username.github.io

Check CNAME file:

  • Must be in public/ folder
  • Contains only your domain, no protocol
  • No trailing slash

Common issues:

  • DNS not propagated yet (wait up to 24 hours)
  • CNAME file missing or incorrect
  • Domain verification failed in GitHub settings

Build Fails in Actions

View logs:

  1. Go to Actions tab
  2. Click the failed workflow
  3. Expand build step to see errors

Common fixes:

  • Increase Node version in workflow
  • Clear npm cache: npm ci --cache .npm
  • Check for missing dependencies

Performance Tips

Enable Caching

Cache node_modules for faster builds:

Code
yaml
1- name: Setup Node
2 uses: actions/setup-node@v4
3 with:
4 node-version: '20'
5 cache: 'npm'

Optimize Images

Pre-optimize images before committing:

Code
bash
1npm install -D imagemin-cli
2 
3# Optimize all images
4npx imagemin public/images/* --out-dir=public/images

Reduce Bundle Size

Check what's in your bundle:

Code
bash
1npm install -D vite-bundle-visualizer
2 
3ANALYZE=true npm run build:export

Limits

GitHub Pages has some limits:

  • Repository size: 1GB recommended
  • Site size: 1GB published site
  • Bandwidth: 100GB/month soft limit
  • Builds: 10 per hour

These limits are generous for documentation sites.

Migration from Other Platforms

From Vercel

  1. Update specra.config.json deployment section
  2. Run npm run build:export locally to test
  3. Set up GitHub Actions workflow
  4. Push to trigger deployment

From Netlify

Same process as Vercel. The static output works on both platforms.

Best Practices

Use GitHub Actions - Automatic deployment on every push

Version your docs - Use git tags for documentation versions

Test locally - Run npm run build:export && npx serve out before pushing

Monitor builds - Set up notifications for failed deployments

Use custom domain - Professional appearance and stable URLs

Enable HTTPS - Always enforce HTTPS for security

Next Steps