Setting up a GitHub Pages custom domain is mostly a DNS problem, not a “GitHub” problem. Once the DNS points to the correct place, Pages can publish the same static site you already have—but with your own domain and (usually) HTTPS.

This guide walks through a safe setup path: pick the right domain shape (apex vs www), configure DNS, connect the domain in GitHub Pages settings, enable HTTPS, and (optionally but strongly recommended) verify the domain to reduce hijacking/takeover risk.

Key Takeaways #

What is a GitHub Pages Custom Domain? #

By default, GitHub Pages sites live under GitHub’s domain:

A custom domain means you serve the same site from your own domain, like https://example.com/ or https://www.example.com/.

Under the hood:

  1. Your DNS records route the domain to GitHub Pages.
  2. GitHub Pages serves your published static files.
  3. GitHub can provision a TLS certificate so your site supports HTTPS.

GitHub Docs describes this flow and the DNS record types required to point an apex or subdomain at Pages.

Why a Custom Domain Matters #

A custom domain is not just branding. It improves:

But it also adds operational surface area: DNS, certificate provisioning, and security considerations (domain verification).

Step-by-Step: Set Up a GitHub Pages Custom Domain (Safe Path) #

Step 1: Decide apex vs www #

You typically choose one of these:

Practical trade-off:

If you want the least friction: use www as the primary domain and optionally redirect apex → www using your DNS provider or another layer you control.

Step 2: Add DNS records (the part that actually matters) #

Create a CNAME record:

GitHub Docs documents using CNAME records for subdomains pointing to Pages.

Option B: example.com (apex/root domain) #

GitHub Docs provides A and AAAA records for apex domains. As of the referenced documentation, the A records are:

And the AAAA records are:

Important: treat these as “check the docs” values—always verify the current IPs in GitHub Docs before you rely on them.

DNS record cheat sheet #

DomainRecord typeWhat you setWhen to use
www.example.comCNAME<user>.github.ioRecommended default for Pages
example.comAGitHub Pages A recordsApex domain without provider-specific features
example.comAAAAGitHub Pages AAAA recordsIPv6 support for apex domain

Step 2.5: Understand what changes for project sites #

If your Pages site is a project site (served under /<repo>/ on the default domain), moving to a custom domain typically changes your public base path to /. That is a good thing, but it can break sites that hard-code the repo prefix in links or asset URLs.

Before you flip the switch, scan for:

The easiest way to avoid surprises is to use relative URLs where possible, and to keep base-path configuration in a single place (for example, _config.yml for Jekyll or a single baseURL/publicPath setting for your generator).

What about “CNAME flattening” / ALIAS / ANAME? #

Some DNS providers (Cloudflare included) offer features that let you use a CNAME-like workflow at the apex by returning A/AAAA answers at query time (commonly called “CNAME flattening”). Cloudflare documents how CNAME flattening works and when it applies.

If your DNS provider supports it, you can keep your apex setup closer to the www flow—but you should still validate the resolved A/AAAA answers with dig.

Step 3: Configure the custom domain in GitHub Pages #

In your repository:

  1. Go to Settings → Pages.
  2. Find Custom domain.
  3. Enter your domain (for example www.example.com).

GitHub Docs notes that when you set a custom domain, GitHub Pages may create a commit that adds a CNAME file to the publishing source. That CNAME file is how Pages remembers the domain for branch-based publishing.

If you deploy via GitHub Actions, make sure the published output includes a CNAME file so the domain stays attached to your site.

Step 4: Validate DNS + Pages resolution #

Before debugging “GitHub settings”, validate DNS directly:

# Replace with your domain
dig +short www.example.com CNAME
dig +short example.com A
dig +short example.com AAAA

What you want to see:

Then validate HTTP:

curl -I https://www.example.com/

Step 5: Enable HTTPS (and understand the waiting time) #

GitHub Pages can provision certificates and lets you enable Enforce HTTPS. GitHub Docs notes it can take up to an hour for your site to become available over HTTPS after you configure your custom domain.

It can take up to an hour for your site to become available over HTTPS after you configure your custom domain. — GitHub Docs (Troubleshooting custom domains and GitHub Pages), adapted

If “Enforce HTTPS” is disabled:

  1. Re-check DNS first (wrong records are the #1 cause).
  2. Confirm the custom domain is set in Pages settings.
  3. Wait for certificate provisioning to complete.

Domain verification is a safety feature. GitHub Docs recommends verifying your domain, especially if you use wildcard DNS records:

GitHub recommends verifying your domain, particularly when using wildcard DNS records. — GitHub Docs (Verifying your custom domain for GitHub Pages), adapted

This reduces the chance of “domain takeover” style issues where a third party can configure a Pages site that appears to be on your domain.

Migration Checklist (Default Domain → Custom Domain) #

If you already have a working site at <user>.github.io and you’re moving to example.com, do a quick migration pass before you declare the domain “done”:

  1. Pick a canonical hostname: decide whether example.com or www.example.com is the primary URL and stick to it everywhere (site config, canonical tags, social links).
  2. Update generator base path:
    • project site → custom domain often changes base path from /<repo>/ to /
    • fix your generator config so links/assets are correct for the new base path
  3. Remove hard-coded hostnames: search for <user>.github.io in your repository and replace with the custom domain (or use relative URLs).
  4. Confirm the CNAME file behavior: if you deploy via Actions, verify that the final published output includes the CNAME file so Pages keeps the mapping.
  5. Test deep links: open a few nested URLs and confirm:
    • the page loads (no 404)
    • assets load (no CSS/JS 404)
    • the 404 page behaves as expected
  6. Validate HTTP behavior: use curl -I for both HTTP and HTTPS to confirm the final redirects and status codes match your expectations.

This sounds like extra work, but it is much faster than discovering broken assets after a search engine has already crawled the new domain.

Troubleshooting (Common Failures and Fixes) #

SymptomLikely causeFast fix
Pages shows a default 404 pageDNS isn’t pointing at Pages or custom domain not setRe-check DNS records and set custom domain in Settings → Pages
“DNS check unsuccessful”Wrong record type/target or propagation not finishedValidate with dig, fix record, wait for propagation
“Enforce HTTPS” disabledDNS misconfigured or certificate not provisioned yetFix DNS; wait up to an hour after DNS is correct
Apex domain won’t accept a CNAMEDNS rules for apexUse A/AAAA from GitHub Docs or use a provider feature (ALIAS / CNAME flattening)
You lose the custom domain after rebuildMissing CNAME in published outputEnsure CNAME is present in the publishing source/output

Best Practices #

  1. Prefer www as the primary domain: it’s operationally simpler and easier to migrate later.
  2. Treat DNS changes like deployments: document records, keep a rollback plan (restore old records), and validate with dig.
  3. Use a low TTL during migrations: lower TTL reduces how long bad records stick around while you fix them.
  4. Verify the domain: domain verification is a low-effort, high-value safety step.
  5. Keep HTTPS enforced: once certificate provisioning is stable, enable “Enforce HTTPS” and avoid mixed-content issues.

Common Mistakes #

  1. Mixing apex and www without a plan — decide which is canonical, then redirect/standardize.
  2. Setting a CNAME at the apex without provider support — use A/AAAA or a provider feature like CNAME flattening.
  3. Assuming DNS is instant — always validate with dig and allow time for propagation.
  4. Forgetting the CNAME file when using GitHub Actions — ensure the published output includes it.
  5. Skipping domain verification with wildcard DNS — this increases risk and is avoidable.

Frequently Asked Questions #

Should I use apex or www for GitHub Pages? #

For most sites, www is simpler because you can use a single CNAME record. Apex domains often require A/AAAA records or a DNS provider feature (ALIAS/ANAME/CNAME flattening). If you want the least DNS friction, use www as the canonical domain.

Why is “Enforce HTTPS” disabled or missing in GitHub Pages? #

GitHub Pages only enables HTTPS after your DNS is correctly pointed to GitHub and a certificate is provisioned. Fix DNS first, then allow time for provisioning—GitHub Docs notes it can take up to an hour after you configure your custom domain.

Do I need a CNAME file in my repository? #

Yes, in most workflows. GitHub Pages uses a CNAME file to remember your custom domain. For branch publishing, GitHub may create it when you set the domain in Settings. For Actions publishing, ensure your build/deploy step includes it in the published output.

Can I use the same custom domain for multiple GitHub Pages sites? #

Not simultaneously. DNS routes the domain to one target at a time, and the Pages custom domain setting is effectively “one domain → one site.” If you need multiple sites, use subdomains (docs.example.com, blog.example.com) instead of trying to reuse the same apex.

How do I prevent someone else from using my domain on GitHub Pages? #

Verify your domain in GitHub. GitHub Docs recommends verifying your domain, especially if you use wildcard DNS, so only your account can configure GitHub Pages sites with that domain.

Conclusion #

GitHub Pages custom domains are straightforward when you approach them in the right order:

  1. decide apex vs www,
  2. configure DNS and validate it with dig,
  3. set the custom domain in GitHub Pages,
  4. enable HTTPS, and
  5. verify the domain for safety.

If you get stuck, treat it as a DNS/debugging exercise: confirm records, confirm the published site exists, then confirm HTTPS provisioning.

References #

  1. GitHub Docs: Managing a custom domain for your GitHub Pages site
  2. GitHub Docs: Verifying your custom domain for GitHub Pages
  3. GitHub Docs: Securing your GitHub Pages site with HTTPS
  4. GitHub Docs: Troubleshooting custom domains and GitHub Pages
  5. GitHub Docs: About GitHub Pages
  6. Cloudflare Docs: CNAME flattening

Frequently Asked Questions

Should I use apex or www for GitHub Pages?

For most sites, www (a subdomain) is simpler because you can point it to GitHub Pages with a CNAME record. Apex domains (example.com) typically require A/AAAA records (or a DNS provider feature like CNAME flattening/ALIAS). If you want the least DNS friction, start with www.

Why is “Enforce HTTPS” disabled or missing in GitHub Pages?

GitHub Pages only enables HTTPS after your DNS is correctly pointed at GitHub and the certificate is provisioned. Fix DNS first, then allow time for provisioning (GitHub Docs notes it can take up to an hour after configuring your custom domain).

Do I need a CNAME file in my repository?

GitHub Pages uses a CNAME file to remember your custom domain. If you deploy from a branch, GitHub may add it for you when you set the custom domain in Settings. If you deploy via GitHub Actions, ensure your published output includes the CNAME file.

Can I use the same custom domain for multiple GitHub Pages sites?

Not at the same time. A domain can only resolve to one site at a time in DNS. If you “reuse” the same domain across repos, you must switch DNS and the Pages custom domain setting accordingly.

How do I prevent someone else from using my domain on GitHub Pages?

Use GitHub Pages domain verification. GitHub Docs recommends verifying your domain—especially if you use wildcard DNS—so only you can configure GitHub Pages sites with that domain.