GitHub Pages: Deploy Sites Directly from Your Repository
In this tutorial, you'll learn about GitHub Pages: Deploy Sites Directly from Your Repository. We cover key concepts, practical examples, and best practices.
GitHub Pages is a free static site hosting service that takes HTML, CSS, and JavaScript from a repository and publishes them as a live website automatically.
In this tutorial, you'll learn how to deploy websites directly from your GitHub repository using GitHub Pages. GitHub Pages hosts static sites for free, directly from your repo — perfect for documentation, portfolios, and project pages. By the end, you'll configure builds, set up custom domains, and deploy both project and user pages.
flowchart TD
A[Create repository] --> B{Pages type?}
B --> C[User/Org: username.github.io]
B --> D[Project: username.github.io/repo]
C --> E[Branch: main, folder: root]
D --> F[Branch: gh-pages or /docs]
E --> G[Enable Pages in Settings]
F --> G
G --> H[Site is live!]
H --> I[Add custom domain]
I --> J[Configure DNS + CNAME]
Types of GitHub Pages
| Type | Repository Name | URL | Use Case |
|---|---|---|---|
| User | username/username.github.io |
username.github.io |
Personal site/portfolio |
| Organization | org/org.github.io |
org.github.io |
Organization site |
| Project | Any repo | username.github.io/repo |
Documentation, demo |
Setting Up a User Site
Create a repository named <your-username>.github.io:
git init
echo "# My Portfolio" > index.html
git add index.html
git commit -m "Initial commit"
git remote add origin https://github.com/your-username/your-username.github.io.git
git push -u origin main
Enable Pages in repository Settings > Pages > Deploy from main branch > root folder. Your site is live at https://your-username.github.io.
Setting Up a Project Site
For a project site (e.g., documentation), use the gh-pages branch:
# Create and switch to gh-pages branch
git checkout --orphan gh-pages
git rm -rf .
echo "<h1>Project Docs</h1>" > index.html
git add index.html
git commit -m "Initial project pages"
git push -u origin gh-pages
In Settings > Pages, set branch to gh-pages and folder to /root.
Using Jekyll
Enable Jekyll for automatic Markdown-to-HTML conversion:
# _config.yml at repository root
title: My Project Site
description: Documentation for my awesome project
theme: jekyll-theme-cayman
Create a Jekyll page:
---
title: Getting Started
---
## Welcome
This page is written in Markdown and automatically converted to HTML.
Custom Domain
Add a custom domain:
- In repo Settings > Pages, enter your domain (e.g.,
docs.example.com) - Create a
CNAMEfile (optional, GitHub creates it):
docs.example.com
- Configure DNS at your provider:
| Record | Type | Value |
|---|---|---|
docs.example.com |
CNAME | your-username.github.io |
example.com (apex) |
A | 185.199.108.153, 185.199.109.153, 185.199.110.153, 185.199.111.153 |
Jekyll Themes
GitHub Pages supports several Jekyll themes:
| Theme | Style | Best For |
|---|---|---|
| Cayman | Clean, centered | Documentation |
| Minimal | Very simple | Portfolios |
| Hacker | Dark theme | Dev blogs |
| Slate | Sidebar nav | Multi-page docs |
| Architect | Tech aesthetic | Project pages |
| Leap Day | Bold header | Landing pages |
Set a theme in _config.yml:
theme: jekyll-theme-cayman
title: My Project
description: Short description for search engines
show_downloads: true
google_analytics: UA-XXXXX-Y
Build Configuration
Use GitHub Actions for custom build steps:
# .github/workflows/pages.yml
name: Deploy to Pages
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build site
run: |
npm install
npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
steps:
- uses: actions/deploy-pages@v2
Common Errors
| Error | Cause | Fix |
|---|---|---|
404 not found |
Pages not enabled or wrong branch | Check Settings > Pages configuration |
Page build failure |
Jekyll error in _config.yml | Validate YAML syntax |
Custom domain not configured |
DNS not propagated | Wait up to 48 hours for DNS |
Enforce HTTPS not working |
Certificate provisioning | Wait, GitHub auto-provisions via Let's Encrypt |
CNAME already taken |
Domain used by another user | Verify domain ownership |
Builds succeed but site not updated |
Cache | Hard refresh or wait 10 minutes |
Jekyll ignores _ prefixed folders by default |
Jekyll convention | Add include: [_folder] to config |
Mixed content on HTTPS |
HTTP resources in page | Use HTTPS URLs for all resources |
Practice Questions
Challenge
Create a personal portfolio site using GitHub Pages with a custom domain. Use Jekyll with the Cayman theme. Create at least three pages: index (about you), projects (with pinned repos), and contact. Set up a GitHub Actions workflow that builds the site on push. Add a custom domain with HTTPS enabled.
Real-World Task
You need to publish documentation for an open-source library. Create a /docs folder in the repository with Markdown files for installation, usage, API reference, and contributing guidelines. Configure GitHub Pages to serve from the /docs folder on the main branch. Add a _config.yml with a Jekyll theme. Set up a custom subdomain (docs.projectname.com). This documentation setup is used by DodaTech for all open-source projects including DodaZIP.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro