GitHub Pages is one of the best free hosting options for developers. Zero cost, tight Git integration, automatic HTTPS, and it scales effortlessly. This guide walks you through every step — from zero to a live blog with a custom domain.
Why GitHub Pages in 2026?
Before diving in, here is why developers keep choosing GitHub Pages:
- Free forever — no credit card, no expiry
- Custom domains + free HTTPS via Let's Encrypt
- Deploy on git push — no build servers to manage
- Jekyll built-in or bring your own static site generator
- 99.9% uptime backed by GitHub's CDN
I use GitHub Pages for Profiterole Blog, a personal finance blog — and it has been rock-solid.
Step 1: Create the Repository
Your repo name determines your default URL:
| Repo name | Default URL |
|---|---|
username.github.io |
https://username.github.io |
my-blog |
https://username.github.io/my-blog |
For a clean root URL, name the repo <your-username>.github.io.
# Create locally and push
mkdir my-blog && cd my-blog
git init
echo "# My Blog" > index.md
git add . && git commit -m "Initial commit"
git remote add origin git@github.com:username/username.github.io.git
git push -u origin main
Step 2: Enable GitHub Pages
- Go to your repo on GitHub
- Click Settings → Pages (left sidebar)
- Under Source, choose
Deploy from a branch - Select branch
mainand folder/ (root) - Click Save
Within 1–2 minutes, your site is live at https://username.github.io.
Step 3: Jekyll vs Static HTML — Which to Choose?
Static HTML (simplest)
Drop an index.html in the root. GitHub Pages serves it directly. No build step.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Blog</title>
</head>
<body>
<h1>Welcome to My Blog</h1>
</body>
</html>
Jekyll (recommended for blogs)
Jekyll is GitHub Pages' built-in static site generator. It handles:
- Blog post organization (date-based filenames)
- Layouts and includes (no copy-pasting headers)
- Front matter for metadata
- Liquid templating
Minimal Jekyll setup:
# _config.yml
title: My Blog
description: A blog about things I build
theme: minima
# _posts/2026-03-21-first-post.md
---
layout: post
title: "My First Post"
date: 2026-03-21
---
Hello world! This is my first blog post.
Push to GitHub and Jekyll compiles it automatically — no local Ruby installation needed.
Step 4: Custom Domain Setup
This is where most guides get vague. Here's the exact process.
4a. Add a CNAME file to your repo
echo "blog.yourdomain.com" > CNAME
git add CNAME && git commit -m "Add custom domain"
git push
4b. Configure DNS at your registrar
For an apex domain (yourdomain.com) — add these A records:
Type Name Value
A @ 185.199.108.153
A @ 185.199.109.153
A @ 185.199.110.153
A @ 185.199.111.153
Also add an AAAA record for IPv6:
AAAA @ 2606:50c0:8000::153
AAAA @ 2606:50c0:8001::153
AAAA @ 2606:50c0:8002::153
AAAA @ 2606:50c0:8003::153
For a subdomain (blog.yourdomain.com) — add a CNAME record:
Type Name Value
CNAME blog username.github.io.
DNS changes can take up to 48 hours, but usually propagate within 15 minutes.
4c. Enable the custom domain in GitHub Settings
- Go to Settings → Pages
- Under Custom domain, enter your domain
- Click Save
- Wait for the DNS check to pass (green checkmark)
Step 5: Enable HTTPS
Once DNS is verified:
- In Settings → Pages, tick Enforce HTTPS
- GitHub automatically provisions a Let's Encrypt certificate
- Certificate issuance takes 15–30 minutes
If the HTTPS option is greyed out, DNS propagation is still in progress — wait and refresh.
Verify HTTPS is working:
curl -I https://blog.yourdomain.com
# Should return: HTTP/2 200
Step 6: SEO Best Practices for GitHub Pages
GitHub Pages sites can rank well — here's how to help them along:
Add a sitemap
For Jekyll, add to _config.yml:
plugins:
- jekyll-sitemap
This auto-generates /sitemap.xml on every build.
Add meta tags
<head>
<title>Post Title | Blog Name</title>
<meta name="description" content="A 150-character description of this page.">
<meta property="og:title" content="Post Title">
<meta property="og:description" content="Description for social sharing">
<link rel="canonical" href="https://blog.yourdomain.com/post-slug/">
</head>
Use descriptive URLs
In _config.yml:
permalink: /:title/
This gives you /how-to-do-x/ instead of /2026/03/21/how-to-do-x.html.
Submit to Google Search Console
- Go to search.google.com/search-console
- Add your custom domain property
- Verify via DNS TXT record
- Submit your sitemap URL
Common Issues & Fixes
Site not updating after push?
Check the Actions tab — GitHub Pages builds can take 1–3 minutes. If the build fails, click into it for the error log.
Custom domain keeps reverting?
Make sure the CNAME file is committed to your repo. Setting it only in GitHub UI gets overwritten on the next push.
Mixed content warnings on HTTPS?
Search your HTML for http:// links (images, scripts, stylesheets) and update them to https://.
Jekyll build failing?
Run locally first:
gem install bundler jekyll
bundle exec jekyll serve
# Visit http://localhost:4000
Quick-Start Checklist
- [ ] Create repo named
username.github.io - [ ] Push
index.htmlor Jekyll_config.yml - [ ] Enable Pages in repo Settings
- [ ] Add
CNAMEfile with your domain - [ ] Set A records (apex) or CNAME record (subdomain) at your DNS provider
- [ ] Enter custom domain in GitHub Pages settings
- [ ] Enable Enforce HTTPS
- [ ] Submit sitemap to Google Search Console
Wrapping Up
GitHub Pages is genuinely one of the best free hosting options available. Once the DNS propagates, you have a fast, secure, globally distributed site — with zero ongoing cost or maintenance.
For a real-world example of GitHub Pages in action, check out Profiterole Blog — a personal finance blog built entirely on this stack.
Have questions about your setup? Drop them in the comments.
Top comments (0)