GitHub Pages Tutorial in 2026 (Free Static Hosting Done Right)

By UniLink May 02, 2026 16 min read
GitHub Pages Tutorial in 2026 (Free Static Hosting Done Right)


GitHub Pages Tutorial in 2026 (Free Static Hosting Done Right)

A practical guide to setup, custom domains, Jekyll, modern static site generators, and the limitations that decide whether GitHub Pages is right for you.

TL;DR

GitHub Pages is still one of the best free static hosts in 2026 if you understand what it actually is: a Jekyll-friendly CDN that serves files from a Git branch. You point a repository at it, push HTML or a build artifact, and get HTTPS at username.github.io or your own domain in minutes. It is excellent for documentation, portfolios, project sites, and lightweight marketing pages. It is the wrong choice the moment you need server-side logic, edge functions, image optimization at scale, large media, or build pipelines beyond the bundled Jekyll workflow. For anything richer than a static site, Vercel, Netlify, and Cloudflare Pages cover the gaps without removing GitHub from your stack.

If you have ever opened a developer portfolio at someone.github.io or stumbled on a tiny project site that just worked, there is a good chance GitHub Pages was behind it. The platform has powered free static sites since 2008, and in 2026 it is still the path of least resistance for engineers who already live in Git. The catch is that "static" means more in 2026 than it did three years ago. Frameworks like Astro, Next.js, and Eleventy push static output that rivals dynamic apps, and the question of where to host that output is no longer obvious.

This tutorial walks through GitHub Pages the way a working developer would actually use it: the three site types, the repository conventions that trip people up, the Jekyll workflow that ships out of the box, modern static site generators that work better than Jekyll for most new projects, custom domains with HTTPS, the hard limits, and the moments when Vercel, Netlify, or Cloudflare Pages is the smarter call.

The Three Setup Options on GitHub Pages

GitHub Pages exposes three flavors of site, and choosing the wrong one is the most common reason new users get stuck on a 404. They differ in who owns the site, what URL it lives at, and how many you can have.

A user site belongs to a personal GitHub account. It lives at username.github.io and you get exactly one per account. The repository must be named username.github.io, matching your handle exactly. This is the right choice for a portfolio, a personal blog, or a homepage you want to point friends and recruiters to. Because it sits at the root of your GitHub subdomain, links inside it stay clean and short.

An organization site works the same way but for a GitHub organization rather than a user. It lives at orgname.github.io, you get one per organization, and the repository must be named orgname.github.io. Use it for a company landing page, an open source project hub, or a docs entry point that sits above multiple project sites.

A project site is unlimited. Every repository you own can publish a project site at username.github.io/repository, and you can run as many as you have repos. Project sites are the workhorse of the platform. Documentation, demo pages, marketing microsites, course materials, and one-off experiments all fit naturally here. The trade-off is that the URL includes the repository name, which means relative paths inside your HTML need to account for the subdirectory. Frameworks usually expose this as a basePath or baseurl setting, and forgetting to set it is the second most common reason a freshly deployed site looks broken.

Repository Structure and Publishing Sources

GitHub Pages reads its content from a publishing source, which is a combination of a branch and a folder inside the repository. Historically the convention was the gh-pages branch. Today you have three modern options, configured under Settings, Pages in any repository.

The first is deploy from a branch, which is what most beginners start with. You pick a branch, usually main, and a folder, usually root or /docs. Every push to that branch triggers a Pages build and deploy. The second is GitHub Actions, where a workflow file generates the static output and uploads an artifact that Pages serves. This is the modern recommendation for any framework newer than Jekyll, because it gives you full control over the build environment, Node versions, and dependencies. The third is the legacy gh-pages branch pattern, still supported and still useful when a tool like the gh-pages npm package is already wired into your project.

One file matters more than any other in a Pages repository: .nojekyll. It is empty and lives at the root of the published folder. Its presence tells Pages to skip Jekyll processing entirely and serve files exactly as committed. If you are publishing the output of any non-Jekyll framework, you almost always want this file. Without it, Pages will silently strip files and folders that begin with an underscore, which is exactly what most JavaScript bundlers produce.

Jekyll Basics: The Built-In Workflow

Jekyll is the static site generator that GitHub Pages was built around, and it is still the only generator Pages will run on the server for you with zero configuration. If you push a repository with a _config.yml at the root, a few content files in Markdown, and no .nojekyll, Pages will compile it and serve the result. No build script, no Actions workflow, no Node toolchain.

A minimal Jekyll site has four moving parts. The _config.yml file defines the site title, base URL, theme, and any plugins. The _layouts folder holds HTML templates. The _includes folder holds reusable fragments like a header or footer. Content lives in Markdown files at the root or under _posts for blog entries, where the filename encodes the publish date in YYYY-MM-DD-title.md format. Front matter, a small block of YAML at the top of each file, sets the layout, title, and any custom variables.

The advantages of staying on Jekyll are real: zero infrastructure, fast first deploy, an ecosystem of free themes from pages-themes on GitHub, and a feature set tuned for blogs and documentation. The disadvantages are also real. Jekyll is a Ruby tool, which is a stack most modern web developers no longer touch. The supported plugin list is locked down, so you cannot run arbitrary Jekyll plugins without switching to GitHub Actions. Build performance degrades on sites with thousands of pages. And the templating language, Liquid, is unfamiliar to anyone who has spent the last few years in JSX or Vue.

For a small blog, a documentation site, or a personal portfolio with a handful of pages, Jekyll is still a perfectly reasonable choice in 2026. For anything else, the rest of this guide is more useful.

Static Site Generators: Modern Alternatives to Jekyll

The interesting story of GitHub Pages in 2026 is not Pages itself, which has barely changed in a decade. It is the explosion of static site generators that produce output Pages is happy to host. Build with whatever you like, push the artifact, and Pages serves it. Here are the four that matter.

Generator Best For Build Speed Learning Curve
Hugo Large content sites, docs at scale Fastest (Go binary) Medium (Go templates)
Eleventy Blogs, marketing, lean output Fast Low (any template language)
Astro Content-heavy sites with islands of interactivity Fast Medium (component-based)
Next.js (static export) React teams shipping mostly static pages Medium Medium-high

Hugo is a single-binary Go tool that compiles thousands of pages in seconds. It is the right pick when you have a large content set, value build performance above all else, and are comfortable with Go-style templating. Many of the largest documentation sites on GitHub Pages run on Hugo for exactly this reason.

Eleventy is the JavaScript equivalent for people who want the simplicity of Jekyll without leaving Node. It accepts almost any template language you throw at it, ships a tiny final bundle, and produces clean HTML with no client-side framework attached unless you add one. For blogs and content sites where speed and simplicity matter more than interactivity, Eleventy is hard to beat.

Astro is the rising star for content-heavy sites that need a few interactive components. Its key idea is the "island architecture": pages render as static HTML by default, and you opt individual components into client-side JavaScript only when needed. The result is a site that scores at the top of Core Web Vitals while still letting you drop a React or Vue component in where it earns its keep.

Next.js with static export is the option for teams already invested in the React and Next ecosystem. Running next build with output: 'export' produces a folder of static HTML and assets that Pages can serve. You give up server-side rendering, image optimization, and API routes, but you keep React components, file-based routing, and the rest of the Next developer experience. Most marketing sites and documentation portals can fit inside this constraint comfortably.

Whichever generator you pick, the GitHub Actions workflow is roughly the same: check out the repo, install dependencies, run the build command, and publish the output folder to Pages using the official actions/deploy-pages action. The workflow templates in the GitHub Pages documentation cover each generator with copy-paste configurations.

Custom Domain and HTTPS

A free .github.io subdomain is fine for personal projects, but anything that touches a brand needs a custom domain. GitHub Pages handles this in two steps: a DNS configuration on your domain registrar, and a CNAME record on the Pages side.

For an apex domain like example.com, you create four A records pointing to the GitHub Pages IP addresses listed in the official documentation, plus an AAAA record set if you want IPv6. For a subdomain like www.example.com or docs.example.com, you create a single CNAME record pointing at username.github.io. After DNS propagates, you go to Settings, Pages in the repository, type the domain into the custom domain field, and save. GitHub writes a CNAME file at the root of your published source so future deploys keep the binding.

HTTPS is automatic but not instant. Once your DNS is correct, GitHub provisions a Let's Encrypt certificate in the background, which usually takes between fifteen minutes and an hour. When the "Enforce HTTPS" checkbox becomes available, tick it. Until you do, Pages will serve traffic over HTTP and any visitor on a hostile network can intercept it. This is the third most common Pages mistake, and the easiest to fix.

Pro tip: If your custom domain is sitting behind Cloudflare, set the SSL mode to "Full" (not "Flexible"). Flexible mode makes Cloudflare talk to GitHub over HTTP, which breaks the certificate chain and produces redirect loops that are painful to debug.

Limitations: What GitHub Pages Will Not Do

The honest part of this tutorial is the limits. GitHub Pages is generous about what it gives away for free, but it draws hard lines, and walking into them mid-project is unpleasant.

What GitHub Pages does well

  • Free static hosting with zero billing setup
  • Native Jekyll build pipeline, no toolchain required
  • Automatic HTTPS for both .github.io and custom domains
  • Tight integration with the Git workflow your team already uses
  • Global CDN with reasonable cache behavior
  • GitHub Actions support for any modern static site generator

What it will not do

  • No server-side code, no APIs, no edge functions, no SSR
  • 1 GB published site size limit, hard cap
  • 10 minute build timeout per Pages deployment
  • 100 GB monthly bandwidth soft limit, with throttling above
  • 10 builds per hour rate limit on classic Jekyll deploys
  • No image optimization, no automatic responsive images
  • No password protection, no preview deployments per branch
  • Public repositories required on free accounts for Pages access

The size and bandwidth limits sound large until you put a media-heavy marketing site on Pages and watch it sail past 1 GB the moment you add a few minutes of MP4. The build timeout becomes a problem on Hugo or Astro sites with thousands of pages and many image transforms. The lack of preview deployments per branch is the single biggest workflow gap compared to Vercel or Netlify, and there is no way to work around it from inside Pages.

The "JavaScript only on the client" rule is the one that catches teams migrating from Vercel. Anything that requires a server, including Next.js API routes, server actions, middleware, image optimization through next/image, and on-demand revalidation, simply does not exist on Pages. Your code can call third-party APIs from the browser, but it cannot run any logic of its own server-side.

When to Choose GitHub Pages vs. Vercel, Netlify, or Cloudflare Pages

The four platforms overlap enough that it is worth being explicit about when each one wins.

Use Case Best Pick Why
Personal portfolio, dev blog, project docs GitHub Pages Free, zero setup, lives next to your code
Marketing site with forms and previews Netlify Built-in forms, branch previews, generous free tier
Next.js or React app with SSR or ISR Vercel Native Next.js platform, edge functions, image optimization
High-traffic static site needing edge logic Cloudflare Pages Workers integration, unmetered bandwidth, fastest global edge
Open source documentation GitHub Pages Stays in the same place as the code and issues
Client work with previews and password protection Netlify or Vercel Pages has neither feature

The decision is rarely "Pages vs. everyone else." Many teams keep open source docs on Pages because it sits next to the repository, and put their marketing site on Vercel or Netlify for previews, forms, and edge functions. Cloudflare Pages wins when you need static hosting and Workers in the same project with unlimited bandwidth.

Common Mistakes and How to Avoid Them

The same handful of issues account for the majority of GitHub Pages support questions. Knowing them in advance saves hours.

The first is missing the .nojekyll file on a non-Jekyll site. Files and folders starting with an underscore disappear silently, and the resulting 404s on JavaScript bundles are confusing. Fix: drop an empty .nojekyll file at the root of the published folder.

The second is forgetting the base path on a project site. Your CSS, JavaScript, and image URLs need to know they are served from a subfolder. In Next.js, set basePath: '/repository-name' in next.config.js. In Astro, set base in astro.config.mjs. In Jekyll, set baseurl in _config.yml. Use root-relative URLs that respect this setting.

The third is not enforcing HTTPS after a custom domain is configured. Ticking the box takes one second and saves your visitors from man-in-the-middle attacks.

The fourth is publishing private content. Pages on free accounts requires a public repository, which means anything in that repo is visible to anyone who finds it. Move secrets to environment variables in your build step, never commit API keys, and assume everything else is world-readable.

The fifth is relying on Pages for a site that needs a backend. The moment you write the words "we just need a small API" or "let's add a contact form," you are out of Pages territory. Either move to Netlify, Vercel, or Cloudflare Pages, or add a Cloudflare Worker, a Vercel Function, or a third-party form service like Formspree on top.

Frequently Asked Questions

Is GitHub Pages free in 2026?

Yes, GitHub Pages remains free for public repositories on any account, including free personal accounts. Private repositories can publish Pages sites only on paid plans. Bandwidth is generous but soft-capped at 100 GB per month, and total site size is capped at 1 GB.

Can I run a Next.js site on GitHub Pages?

You can run a Next.js site that uses static export, configured with output: 'export' in next.config.js. Anything that requires a server, including API routes, middleware, server actions, image optimization, and ISR, will not work. For a fully featured Next.js site, Vercel is the natural host.

How long does HTTPS take to provision on a custom domain?

Usually fifteen minutes to one hour after DNS propagates. The "Enforce HTTPS" checkbox becomes available once the certificate is ready. If it does not appear within a few hours, double check your DNS records and remove any AAAA records that point to old hosts.

Can I use a database with GitHub Pages?

Not directly. Pages serves static files only. You can call any external API from client-side JavaScript, including database-as-a-service platforms like Supabase or Firebase, but you cannot run a server or query a database from server-side code on Pages itself.

What happens if I exceed the 100 GB bandwidth limit?

GitHub treats it as a soft limit and may throttle or contact you if usage is sustained. For a hobby project this is rarely an issue. If you are pushing past 100 GB regularly, you have outgrown free static hosting and should look at Cloudflare Pages, which offers unmetered bandwidth on its free tier.

Should I use Jekyll or a modern static site generator?

For a small blog or docs site you want to ship today with zero setup, Jekyll is fine. For anything new in 2026 with serious content volume or any front-end interactivity, Astro or Eleventy will produce faster, leaner output and a better developer experience. Hugo wins for very large content sets.

Bottom Line

GitHub Pages in 2026 is a focused tool: a free, reliable, Git-native static host that excels at documentation, portfolios, project sites, and marketing pages built from any modern static site generator. It earns its place by being boring in the best way. Push a branch, get a deployed site, and forget about infrastructure. The moment you need a server, edge logic, branch previews, password protection, or large media at scale, you have outgrown it, and Vercel, Netlify, or Cloudflare Pages will serve you better. Most teams end up using Pages for some sites and a richer platform for others, which is exactly the right answer.

Key Takeaways

  • Three site types: user, organization, and project. Naming the repository correctly is the difference between a working site and a 404.
  • GitHub Actions is the modern publish path. Deploy from a branch is fine for Jekyll, but every other generator should use the official actions/deploy-pages workflow.
  • Add .nojekyll to non-Jekyll sites. Without it, Pages strips underscore-prefixed files and your bundles vanish.
  • Custom domains take a few DNS records and a custom domain field. Always tick "Enforce HTTPS" after the certificate is ready.
  • Hard limits matter: 1 GB site size, 10 minute build, 100 GB monthly bandwidth, no server-side code. Plan around them or move off Pages.
  • For Jekyll alternatives, use Hugo for very large sites, Eleventy for lean content, Astro for content with interactive islands, and Next.js static export for React teams.
  • Pages wins for docs and portfolios. Vercel, Netlify, or Cloudflare Pages wins the moment you need previews, edge logic, or a backend.

Ship Your Static Site With a Smart Link Layer

GitHub Pages is great for the site itself. UniLink is the link-in-bio layer that turns your portfolio, docs, or marketing page into a full creator funnel: branded short links, deep analytics, lead capture, and AI-powered content blocks. Build your free UniLink page in under five minutes and connect it to whatever you ship on GitHub Pages.

Create your free UniLink page

Create Your Free Link-in-Bio Page

Join thousands of creators using UniLink. 40+ blocks, analytics, e-commerce, and AI tools — all free.

Get Started Free