Deploy Jekyll to GitHub Pages in 10 Minutes
Step-by-step guide to deploying a Jekyll site to GitHub Pages — from a new site to live URL in under 10 minutes, with a custom domain walkthrough.
GitHub Pages is the fastest way to get a Jekyll site online — and it’s completely free. This guide gets you from zero to a live site in 10 minutes.
What You Need
- A GitHub account (free at github.com)
- Git installed on your computer
- Jekyll installed locally (optional, but useful for testing)
Option A: Deploy in 3 Minutes (Theme Chooser — No Local Setup)
If you just want something live quickly:
- Create a new GitHub repository named
username.github.io(replaceusernamewith your actual GitHub username) - Go to Settings → Pages
- Under Source, select Deploy from a branch
- Select the
mainbranch and click Save - Go to Settings → Pages → Choose a theme to pick a basic theme
Your site is live at https://username.github.io within 2 minutes.
Limitation: The theme chooser only offers 12 basic GitHub-provided themes. For a real site, use Option B.
Option B: Deploy a Full Jekyll Site (Recommended)
Step 1: Create Your Jekyll Site Locally
gem install bundler jekyll
jekyll new my-site
cd my-site
bundle exec jekyll serve
Open http://localhost:4000 to see your site. Once happy with it, move to the next step.
Step 2: Create a GitHub Repository
Create a new repository on GitHub. For a personal/organisation site, name it username.github.io. For a project site, any name works.
Do not initialise the repository with a README — you’ll push from your local machine.
Step 3: Push to GitHub
In your local site directory:
git init
git add .
git commit -m "Initial Jekyll site"
git remote add origin https://github.com/username/repo-name.git
git push -u origin main
Step 4: Enable GitHub Pages
In your repository on GitHub:
- Go to Settings → Pages
- Under Source, select GitHub Actions
- GitHub will detect your Jekyll site and suggest the Jekyll workflow — click Configure
- Review the workflow file (the defaults work perfectly for most sites)
- Click Commit changes
GitHub Actions will run your build and deploy automatically. Check the Actions tab to watch the build. In 1–2 minutes, your site is live.
Understanding GitHub Pages Site Types
| Type | Repository Name | Live URL |
|---|---|---|
| User site | username.github.io |
https://username.github.io |
| Organisation site | orgname.github.io |
https://orgname.github.io |
| Project site | Any name | https://username.github.io/repo-name |
For a project site, you need to set baseurl in _config.yml:
baseurl: "/repo-name"
url: "https://username.github.io"
For a user or organisation site, leave baseurl empty:
baseurl: ""
url: "https://username.github.io"
Setting Up a Custom Domain
To use yourdomain.com instead of username.github.io:
Step 1: In your repository, create a file called CNAME in the root with your domain:
yourdomain.com
Step 2: In your domain registrar’s DNS settings, add:
- An
Arecord pointing to GitHub’s IP addresses:185.199.108.153185.199.109.153185.199.110.153185.199.111.153
- A
CNAMErecord:wwwpointing tousername.github.io
Step 3: In GitHub repository Settings → Pages, enter your custom domain and check Enforce HTTPS.
DNS changes take 5 minutes to 48 hours to propagate. Once they do, your site is live at your custom domain with a free SSL certificate.
The GitHub Actions Workflow Explained
When you choose the GitHub Actions source, GitHub creates a .github/workflows/jekyll.yml file like this:
name: Deploy Jekyll to GitHub Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
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
Every push to main triggers a build and deploy. You never have to run anything manually.
Troubleshooting Common Deployment Issues
Build fails with “Could not find gem”
Your Gemfile.lock references a gem version not available in the GitHub Actions environment. Run bundle update locally and push the updated Gemfile.lock.
CSS/JS not loading on live site
Check your baseurl setting in _config.yml. If you have a project site at username.github.io/repo, your baseurl must be /repo.
Site shows README instead of Jekyll site You are deploying from a branch, not via GitHub Actions. Go to Settings → Pages and switch the source to GitHub Actions.
Custom domain not working
DNS propagation can take up to 48 hours. Check propagation at dnschecker.org. Make sure the CNAME file exists in your repo root.
Keeping Your Site Updated
Every time you push a commit to main, GitHub Actions rebuilds and deploys your site. The typical cycle:
- Edit files locally
- Test with
bundle exec jekyll serve - Commit and push
- GitHub deploys automatically in ~60 seconds
That’s it. No FTP, no SSH, no server management.
Looking for a great theme to deploy? Browse Jekyll themes on JekyllHub →
Understanding what GitHub Pages builds for you
GitHub Pages runs a specific version of Jekyll in a sandboxed environment. It supports a fixed list of plugins — jekyll-seo-tag, jekyll-sitemap, jekyll-paginate, jekyll-feed, and a handful of others — and does not permit custom plugins or gems outside the supported list. This limitation is often misunderstood: it means you cannot use jekyll-paginate-v2, jekyll-archives, or any custom Ruby plugin in the GitHub Pages native build environment.
The workaround for plugin-rich sites is GitHub Actions. A GitHub Actions workflow runs your full Jekyll build — with any gems and plugins you need — and deploys the built static files to a gh-pages branch or the /docs folder. GitHub Pages then serves these pre-built files without running Jekyll at all. This gives you the hosting convenience of GitHub Pages while lifting all plugin restrictions.
For simple blogs and portfolios with no unusual plugin requirements, the native GitHub Pages build is fine. For sites using jekyll-paginate-v2 for sophisticated pagination, jekyll-archives for tag and category pages, or custom Ruby hooks, the GitHub Actions approach is necessary and straightforward to set up.
Custom domains on GitHub Pages
Connecting a custom domain to GitHub Pages takes about ten minutes and is free. In your repository’s Settings → Pages section, enter your custom domain. GitHub will check for and generate an SSL certificate automatically through Let’s Encrypt — the process typically completes within an hour.
DNS configuration depends on whether you are using an apex domain (yourdomain.com) or a subdomain (blog.yourdomain.com). For a subdomain, add a CNAME record pointing to yourusername.github.io. For an apex domain, you need to add A records pointing to GitHub’s IP addresses (listed in the GitHub Pages documentation). Using Cloudflare as your DNS provider adds CDN caching and additional DDoS protection in front of GitHub Pages at no extra cost — a popular configuration for production sites.
One important detail: create a CNAME file in your repository root containing just your custom domain name. Without this file, custom domain configuration breaks every time you push to the repository. The file can be generated automatically if you set the domain through the GitHub UI, but worth verifying it exists.
Optimising your GitHub Pages site for search
GitHub Pages generates clean, crawlable HTML — an excellent foundation for search engine optimisation. The most impactful additions are the jekyll-seo-tag plugin (which generates meta title, description, OpenGraph, and Twitter Card tags from front matter), a sitemap.xml via jekyll-sitemap, and proper canonical URL configuration.
Submit your sitemap to Google Search Console after deploying. Search Console provides invaluable data: which queries bring visitors to your site, which pages have indexing errors, and how your Core Web Vitals score compares to similar sites. The setup takes five minutes — add the site property, verify ownership via the HTML tag or DNS record, and submit your sitemap URL.
Ensure your _config.yml has url set to your production domain (with https://) and baseurl set to the repository subdirectory if applicable. Misconfigured URL settings cause broken canonical tags and incorrect absolute URLs in your sitemap — common mistakes that silently undermine your site’s SEO before you even publish your first post.
Keeping your GitHub Pages site maintained
A GitHub Pages site benefits from occasional maintenance that goes beyond adding new posts. Every few months, run bundle update locally and verify the site still builds correctly with the latest gem versions. Check your Lighthouse scores on a representative post and the homepage — scores drift as your content grows, and catching a performance regression early is much easier than diagnosing it after the fact.
Review Google Search Console for crawl errors, particularly after restructuring your site’s permalinks or removing old posts. Set up a redirect for any deleted or moved URL to preserve inbound links and prevent 404 errors from accumulating. The Jekyll _redirects file (for Netlify) or a redirect_from front matter key (with jekyll-redirect-from plugin) handles this cleanly.
The combination of GitHub Pages hosting, a well-maintained Jekyll theme, and consistent content publication is a site architecture that ages gracefully. Browse JekyllHub for themes optimised for GitHub Pages — every theme in the collection builds successfully in the standard GitHub Pages environment.
Using GitHub Actions for custom Jekyll builds
The standard GitHub Pages build uses a fixed set of allowed plugins and a specific Jekyll version. If you need a plugin not on the allowed list — jekyll-archives, jekyll-paginate-v2, any custom plugin — you need GitHub Actions to perform the build yourself and deploy the output rather than letting GitHub Pages build from source.
Create .github/workflows/deploy.yml with a workflow that runs on pushes to main, installs Ruby and your Gemfile dependencies, runs bundle exec jekyll build, and deploys the _site/ directory to your repository’s gh-pages branch using the peaceiris/actions-gh-pages action. Configure your GitHub Pages settings to serve from gh-pages rather than from source.
This approach unlocks the full Jekyll plugin ecosystem. You can use jekyll-archives for tag and category archive generation, jekyll-paginate-v2 for advanced pagination, jekyll-seo-tag for structured metadata, and any custom Ruby plugins in _plugins/. The build environment is your GitHub Actions runner, not GitHub’s fixed Pages environment, giving you full control over Ruby version, gem versions, and build steps.
The trade-off is slightly longer build times (Actions adds a few seconds of runner startup) and an additional workflow file to maintain. For simple sites with no custom plugins, the standard GitHub Pages build is simpler. For sites that have grown beyond the standard plugin whitelist, the Actions-based build is the path to continuing to use Jekyll with full capabilities on GitHub Pages hosting.