GitHub Pages Free Website Hosting: Complete Deployment Guide 2026
GitHub Pages is a free static site hosting service that serves web pages directly from your GitHub repository. It supports custom domains, automatic HTTPS, and integrates seamlessly with Jekyll, Next.js, Hugo, and other static site generators. For developers, freelancers, and small businesses, GitHub Pages is the simplest way to host a website for zero monthly cost. This guide covers everything from basic setup to advanced deployment with Jekyll, Next.js static export, custom domains, and troubleshooting.
Why GitHub Pages in 2026
There are many free hosting options, but GitHub Pages stands out for its reliability, Git-based workflow, and unlimited bandwidth.
| Hosting Provider | Free Tier | Bandwidth | Custom Domain | SSL | Best For |
|---|---|---|---|---|---|
| GitHub Pages | Yes | 100 GB/month | Yes | Automatic | Developer portfolios, docs, blogs |
| Vercel | Yes | 100 GB/month | Yes | Automatic | Next.js apps, React projects |
| Netlify | Yes | 100 GB/month | Yes | Automatic | Static sites, forms |
| Cloudflare Pages | Yes | Unlimited | Yes | Automatic | High-traffic static sites |
| Render | Yes (limited) | 100 GB/month | Yes | Automatic | Static + serverless |
| Surge.sh | Yes | Unlimited | Yes | Manual | Quick static deploys |
GitHub Pages is the best choice when you want free hosting with a Git-based workflow and do not need server-side rendering. It is especially ideal for developer portfolios, project documentation, technical blogs, and simple landing pages.
GitHub Pages Pricing and Limits
GitHub Pages is free for all GitHub accounts. Here are the limits and what you get:
| Feature | Free Plan | GitHub Pro |
|---|---|---|
| Cost | $0 | $4/month |
| GitHub Pages sites | 1 per repository | 1 per repository |
| Total sites per account | 1 | Unlimited |
| Bandwidth | 100 GB/month | 100 GB/month |
| Repository size limit | 1 GB | 1 GB |
| Published site size | 1 GB | 1 GB |
| Custom domains | Yes | Yes |
| Automatic HTTPS | Yes | Yes |
| Private repositories | Yes (free tier) | Yes |
Key Limits to Know
- 100 GB/month bandwidth: If your site exceeds this, GitHub will display a warning. For most personal sites and blogs, this is more than enough. A typical blog page is 200 KB, so 100 GB = approximately 500,000 page views per month.
- 1 GB repository size: Your repository (including build output) must stay under 1 GB. Large images and videos should be hosted elsewhere (e.g., Cloudinary, Imgur, or an S3 bucket).
- 1 GB published site size: The generated site files must be under 1 GB.
- Build time limit: GitHub Pages builds have a 10-minute timeout.
How GitHub Pages Works
GitHub Pages serves static files (HTML, CSS, JavaScript, images) directly from a repository. The flow is:
- You push code to your GitHub repository
- GitHub Actions (or the built-in Pages build system) builds the site
- The built static files are deployed to GitHub's CDN
- Your site is available at
https://username.github.ioorhttps://username.github.io/repository-name/
Types of GitHub Pages Sites
| Type | URL Format | Source Branch | Best For |
|---|---|---|---|
| User/Organization site | username.github.io |
main branch, root or /docs |
Personal portfolio, main site |
| Project site | username.github.io/repo-name |
main or gh-pages branch |
Individual project docs |
| Organization site | orgname.github.io |
main branch, root or /docs |
Organization site |
Method 1: Deploy a Jekyll Blog with GitHub Pages
Jekyll is the default static site generator supported by GitHub Pages. It is the easiest option because GitHub Pages has built-in Jekyll support β you do not need to configure CI/CD.
Step 1: Create a Repository
- Go to GitHub and create a new repository
- For a user site, name it
username.github.io(replaceusernamewith your GitHub username) - For a project site, name it anything (e.g.,
my-blog) - Set the repository to public (or private if you have GitHub Pro)
- Initialize with a README
Step 2: Create the Jekyll Site Structure
Create the following files in your repository:
my-blog/
βββ _config.yml
βββ _posts/
β βββ 2026-05-01-welcome-to-my-blog.md
βββ _layouts/
β βββ default.html
β βββ post.html
βββ _includes/
β βββ header.html
β βββ footer.html
βββ index.html
βββ assets/
β βββ css/
β βββ style.css
βββ _config.yml
Step 3: Configure _config.yml
Create a _config.yml file with the following content:
title: My Blog
description: A blog about technology and side hustles
url: "https://username.github.io"
baseurl: "/my-blog" # Leave empty for user sites
timezone: UTC
# Build settings
markdown: kramdown
theme: minima # or any Jekyll theme
plugins:
- jekyll-feed
- jekyll-seo-tag
- jekyll-sitemap
# Pagination
paginate: 10
paginate_path: "/page:num/"
# Exclude from processing
exclude:
- Gemfile
- Gemfile.lock
- node_modules
- vendor
Step 4: Create Your First Post
Create a file in _posts/ with the naming convention YYYY-MM-DD-title.md:
---
layout: post
title: "Welcome to My Blog"
date: 2026-05-01
categories: [general]
tags: [welcome, first-post]
---
# Welcome to My Blog
This is my first post hosted on GitHub Pages for free. GitHub Pages provides:
- Free hosting
- Automatic HTTPS
- Custom domain support
- Git-based workflow
Stay tuned for more content!
Step 5: Enable GitHub Pages
- Go to your repository Settings on GitHub
- Navigate to the "Pages" section in the left sidebar
- Under "Source," select "Deploy from a branch"
- Choose the
mainbranch and the/rootfolder (or/docsif your site is in a docs folder) - Click Save
- Wait 1-2 minutes for the build to complete
- Your site will be available at
https://username.github.io/my-blog/
Step 6: Use a Jekyll Theme
GitHub Pages supports built-in Jekyll themes. You can change the theme in _config.yml:
theme: jekyll-theme-minimal
Available GitHub Pages themes include: minima, jekyll-theme-minimal, jekyll-theme-cayman, jekyll-theme-time-machine, jekyll-theme-slate, jekyll-theme-architect, jekyll-theme-modernist, jekyll-theme-leap-day, and many more.
You can also use a remote theme by adding the jekyll-remote-theme plugin:
remote_theme: daattali/beautiful-jekyll@master
Method 2: Deploy a Next.js Static Site with GitHub Pages
Next.js can export a static site that works perfectly with GitHub Pages. This is more complex than Jekyll but gives you a modern React-based site.
Step 1: Create a Next.js Project
npx create-next-app@latest my-site
cd my-site
Step 2: Configure Static Export
In your next.config.mjs (or next.config.js), add the static export configuration:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
unoptimized: true,
},
// If deploying to a project page (not user page), set the basePath
// basePath: '/my-site',
};
export default nextConfig;
Important: If you are deploying to username.github.io/repo-name/, you must set basePath: '/repo-name'. If you are deploying to username.github.io (user site), leave basePath empty.
Step 3: Add a .nojekyll File
GitHub Pages processes files with Jekyll by default. To prevent this and serve raw files, add a .nojekyll file to your output directory:
Create public/.nojekyll (this will be copied to the output):
touch public/.nojekyll
Step 4: Create a GitHub Actions Workflow
Create a file at .github/workflows/deploy.yml:
name: Deploy to GitHub Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build with Next.js
run: npx next build
env:
NEXT_BASE_PATH: ${{ vars.NEXT_BASE_PATH }}
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./out
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Step 5: Configure GitHub Pages Source
- Push your code to the
mainbranch - Go to Settings > Pages
- Under "Source," select "GitHub Actions"
- The workflow will automatically build and deploy your site on every push to
main
Step 6: Verify Deployment
After the workflow completes:
- Go to the "Actions" tab in your repository
- Check that the "Deploy to GitHub Pages" workflow shows a green checkmark
- Visit
https://username.github.io/my-site/(orhttps://username.github.io/for user sites) - Your Next.js site should be live
Method 3: Deploy a Static HTML Site
For a simple HTML/CSS/JS site, deployment is straightforward:
- Create a repository named
username.github.io - Add your
index.html, CSS, and JavaScript files to the root directory - Push to the
mainbranch - Go to Settings > Pages
- Select "Deploy from a branch" and choose
main/ root - Your site will be live at
https://username.github.iowithin minutes
Setting Up a Custom Domain
GitHub Pages supports custom domains at no extra cost. Here is how to set it up.
Step 1: Purchase a Domain
Purchase a domain from any registrar: Namecheap ($8-12/year for .com), Cloudflare ($9.15/year), Porkbun ($10/year), or Google Domains (now Squarespace, $12/year).
Step 2: Configure DNS Records
Add the following DNS records at your domain registrar:
| Record Type | Name | Value |
|---|---|---|
| A | @ | 185.199.108.153 |
| A | @ | 185.199.109.153 |
| A | @ | 185.199.110.153 |
| A | @ | 185.199.111.153 |
| CNAME | www | username.github.io |
Step 3: Add the Custom Domain in GitHub
- Go to Settings > Pages in your repository
- Under "Custom domain," enter your domain (e.g.,
mydomain.com) - Click "Save"
- Check "Enforce HTTPS" (this may take 10-30 minutes to become available after adding the domain)
Step 4: Add a CNAME File
Create a file named CNAME in your repository root (or in the /docs folder if you are using that as the source):
mydomain.com
This file ensures GitHub knows which custom domain to serve, even if you change settings later.
Enabling HTTPS
GitHub Pages provides automatic SSL certificates through Let's Encrypt. To enable HTTPS:
- Go to Settings > Pages
- After adding your custom domain, wait for the DNS to propagate (check with
dig mydomain.com) - Check the "Enforce HTTPS" checkbox
- GitHub will provision an SSL certificate automatically (this can take up to 30 minutes)
- Once provisioned, your site will be accessible via
https://mydomain.com
If the "Enforce HTTPS" option is greyed out, it means the DNS has not propagated yet. Wait 24-48 hours and check again.
GitHub Pages Build Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Build fails with Liquid error | Syntax error in Jekyll template | Check _config.yml and template files for syntax errors |
| CSS not loading | Incorrect base URL | Ensure baseurl in _config.yml matches your repository name |
| 404 on subpages | Missing .nojekyll file |
Add an empty .nojekyll file to the root of your published directory |
| Images not displaying | Incorrect path | Use relative paths and ensure images are committed to the repo |
| Build timeout | Repository too large | Keep repo under 1 GB; host large images externally |
| Custom domain not working | DNS not propagated | Wait 24-48 hours; verify with dig or nslookup |
| HTTPS not available | DNS not propagated | Wait for DNS to propagate, then enable HTTPS in Pages settings |
| Old content showing | Browser cache | Hard refresh (Ctrl+Shift+R) or clear browser cache |
| Jekyll theme not loading | Theme not in allowed list | Use themes from the GitHub Pages supported themes list, or use remote_theme |
Optimizing GitHub Pages Sites
Performance Optimization
| Optimization | How | Impact |
|---|---|---|
| Compress images | Use TinyPNG or ImageOptim before committing | Reduces page size by 50-80% |
| Minify CSS/JS | Use build tools or minify online tools | Reduces file size by 30-50% |
| Use CDN for assets | Host large files on Cloudinary or jsDelivr | Faster global delivery |
| Enable caching | Add cache headers via .htaccess (not supported on Pages) | N/A for static hosting |
| Lazy load images | Use loading="lazy" attribute |
Faster initial page load |
| Use web fonts sparingly | Limit to 1-2 font families | Reduces render-blocking |
SEO Optimization for GitHub Pages
| SEO Element | How to Implement |
|---|---|
| Page titles | Use descriptive <title> tags (60 chars max) |
| Meta descriptions | Add <meta name="description" content="..."> |
| Sitemap | Install jekyll-sitemap plugin (automatic for Jekyll) |
| robots.txt | Add a robots.txt file to your repository root |
| Open Graph tags | Add OG tags for social sharing previews |
| Structured data | Add JSON-LD schema markup for rich results |
| Canonical URLs | Add <link rel="canonical"> tags |
| Fast loading | Optimize images and minify CSS/JS |
| Mobile-friendly | Use responsive CSS frameworks |
GitHub Pages Use Cases
Use Case 1: Developer Portfolio
A developer portfolio is the most common GitHub Pages use case. Structure:
username.github.io/
βββ index.html (Landing page with intro)
βββ projects.html (Project showcase)
βββ blog/ (Blog section with Jekyll)
βββ resume.html (Downloadable resume)
βββ assets/
β βββ css/style.css
β βββ js/main.js
β βββ images/
βββ CNAME (Custom domain)
Monthly cost: $0 (GitHub Pages) + $10/year domain = $0.83/month total.
Use Case 2: Technical Blog
A Jekyll blog hosted on GitHub Pages is perfect for technical writing. Benefits:
- Free hosting with unlimited posts
- Git-based version control for all content
- Markdown writing workflow
- Automatic RSS feed generation (jekyll-feed)
- SEO-friendly with sitemaps and structured data
Monthly cost: $0 hosting + $0.83/month domain = $0.83/month.
Use Case 3: Project Documentation
GitHub Pages is ideal for hosting documentation for open-source projects:
- Use Jekyll with the "Just the Docs" theme
- Host at
username.github.io/project-docs/ - Auto-generate from markdown files in the repository
- Full-text search built-in
Use Case 4: Landing Page for a Side Hustle
A simple landing page to collect email signups or showcase a product:
my-landing-page/
βββ index.html
βββ style.css
βββ script.js
βββ CNAME
Monthly cost: $0 (GitHub Pages) + $0 (use free .tk domain) or $0.83/month with a .com domain.
GitHub Pages vs Other Free Hosting
| Feature | GitHub Pages | Netlify | Vercel | Cloudflare Pages |
|---|---|---|---|---|
| Free bandwidth | 100 GB/month | 100 GB/month | 100 GB/month | Unlimited |
| Build minutes | Unlimited | 300/month | 6000/month | Unlimited |
| Custom domain | Yes | Yes | Yes | Yes |
| Free SSL | Yes | Yes | Yes | Yes |
| Server-side rendering | No | No (functions available) | Yes | No (workers available) |
| Form handling | No | Yes (100/month) | No | No |
| CMS integration | Limited | Yes | Limited | Limited |
| Best for | Developer sites, blogs | Static sites with forms | Next.js apps | High-traffic sites |
GitHub Pages Security Best Practices
| Practice | Why |
|---|---|
| Do not commit secrets | API keys, passwords, and tokens in your repo are public if the repo is public |
| Use environment variables | Store secrets in GitHub repository secrets for Actions |
| Enable branch protection | Prevent accidental force-pushes to your deployed branch |
| Review dependencies | Keep Gemfile.lock and package-lock.json updated |
| Use Dependabot alerts | Enable in Settings > Security > Dependabot |
| Audit custom themes | Only use themes from trusted sources |
Step-by-Step: Complete Jekyll Blog Setup
Here is the complete process from zero to published blog:
Step 1: Install Jekyll Locally (Optional but Recommended)
# On Ubuntu/Debian
sudo apt-get install ruby-full build-essential zlib1g-dev
gem install jekyll bundler jekyll-sitemap jekyll-seo-tag jekyll-feed
# On macOS
brew install ruby
gem install jekyll bundler
# Create a new Jekyll site
jekyll new my-blog
cd my-blog
bundle exec jekyll serve
# Visit http://localhost:4000
Step 2: Customize Your Site
Edit _config.yml with your site details, create posts in _posts/, and customize layouts in _layouts/.
Step 3: Push to GitHub
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/username/username.github.io.git
git push -u origin main
Step 4: Enable Pages and Configure Domain
As described in the sections above.
Step 5: Write and Publish
Create new markdown files in _posts/ with the date-prefixed naming convention, commit, and push. GitHub Pages automatically rebuilds and publishes.
GitHub Pages Action Checklist
- Create a GitHub account if you do not have one
- Create a repository named
username.github.io(for user site) - Choose your approach: Jekyll, Next.js static export, or plain HTML
- Set up the project structure
- Write your first page or blog post in markdown
- Push to the
mainbranch - Go to Settings > Pages and enable Pages from the main branch
- Wait for the build to complete (check Actions tab)
- Verify your site is live at
https://username.github.io - Purchase a custom domain (optional)
- Configure DNS records (A records and CNAME)
- Add custom domain in GitHub Pages settings
- Wait for DNS propagation (up to 48 hours)
- Enable HTTPS enforcement
- Add a CNAME file to your repository
- Add a .nojekyll file if using non-Jekyll build
- Set up GitHub Actions workflow for automated builds (for Next.js)
- Test on mobile devices
- Run PageSpeed Insights and optimize
- Add a sitemap.xml and robots.txt
- Set up Google Analytics or Plausible Analytics
- Create a content publishing schedule
Common GitHub Pages Questions
Can I use GitHub Pages for a commercial website?
Yes. GitHub Pages can be used for commercial websites. However, GitHub's Terms of Service prohibit using Pages for sites that are primarily designed to drive transactions (e-commerce). A landing page or blog for your business is fine; a full online store is not.
Can I host a database-backed website on GitHub Pages?
No. GitHub Pages only serves static files. If you need a database, use a service like Supabase, PlanetScale, or Firebase for the backend, and connect to it from your static frontend via API calls.
What happens if I exceed the 100 GB bandwidth limit?
GitHub will send you a warning. If the limit is consistently exceeded, GitHub may disable Pages for your repository. If you expect high traffic, consider Cloudflare Pages which offers unlimited bandwidth.
Can I use GitHub Pages with a private repository?
Yes, if you have GitHub Pro ($4/month) or are part of an organization with a paid plan. Free accounts can only use Pages with public repositories.
How do I redirect from an old URL to a new one?
Add a Jekyll redirect plugin or create an HTML file with a meta refresh:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0; url=/new-path/">
<title>Redirecting...</title>
</head>
<body>
<p>Redirecting to <a href="/new-path/">new location</a>.</p>
</body>
</html>
Final Verdict
GitHub Pages is the best free hosting option for developers, technical bloggers, and anyone comfortable with Git. The zero-cost hosting, automatic HTTPS, custom domain support, and Git-based workflow make it unbeatable for static sites. The main limitation is that it only serves static files β no server-side processing, no databases, no server-side form handling. For most personal sites, portfolios, and blogs, this is not a problem.
If you need server-side rendering or API routes, use Vercel (for Next.js) or Netlify (for general static sites with serverless functions). But for pure static hosting, GitHub Pages is the gold standard.
Action Checklist
- Create a GitHub repository for your site
- Choose a static site generator (Jekyll, Next.js, or plain HTML)
- Build and test locally
- Push to GitHub and enable Pages
- Configure custom domain and HTTPS
- Add SEO essentials (sitemap, robots.txt, meta tags)
- Set up analytics
- Publish your first content
- Set up a publishing schedule (weekly or bi-weekly)
More guides: bsynet.cc