Custom Domains for GitHub Pages: CNAME and DNS Setup
A `username.github.io` address (previous lesson) works perfectly well, but many developers and companies prefer to serve their GitHub Pages site from their own custom domain — like `www.example.com`. This requires two coordinated pieces of configuration: DNS records at your domain registrar, and a small file inside your repository telling GitHub which domain to expect.
Learning Objectives
- Explain the purpose of DNS records when pointing a custom domain at GitHub Pages.
- Distinguish between the DNS setup needed for an apex domain versus a subdomain.
- Add and understand the repository's CNAME file.
- Enable HTTPS enforcement for a custom domain on GitHub Pages.
Key Terms to Know Before Setting Up a Custom Domain
- DNS (Domain Name System): The system that translates human-readable domain names (like example.com) into the numeric addresses computers use to locate servers.
- A record: A DNS record type that points a domain directly to a specific numeric IP address.
- CNAME record: A DNS record type that points a domain to another domain name, commonly used for subdomains like www.
- CNAME file: A file placed in a GitHub Pages repository's source, containing the custom domain, telling GitHub which domain the site should respond to.
- Apex domain: A domain with no subdomain prefix, such as example.com (as opposed to www.example.com).
How Custom Domains for GitHub Pages Actually Work
Pointing a custom domain at GitHub Pages requires configuration in two separate places, both of which must agree: your **domain registrar's DNS settings**, and a **file inside your repository**.
**DNS configuration** differs depending on whether you're using an apex domain (like `example.com`) or a subdomain (like `www.example.com`):
- For a **subdomain** like `www.example.com`, you add a **CNAME record** at your DNS provider, pointing `www` to `your-username.github.io`. A CNAME record points one domain name to another, which is exactly what's needed here — it tells anyone requesting `www.example.com` to actually resolve to GitHub's servers via your GitHub Pages address.
- For an **apex domain** like `example.com` (no subdomain), CNAME records technically aren't allowed at the apex level by DNS standards, so instead you add **four A records**, each pointing directly to one of GitHub Pages' specific IP addresses (published in GitHub's own documentation, since these can occasionally change). This is a common point of confusion for beginners expecting to use a CNAME record everywhere.
Many real-world setups use *both*: A records for the apex domain, and a CNAME record for `www`, often with the apex domain configured to redirect to `www` (or vice versa) for consistency.
Separately, inside your GitHub Pages repository, you need to add a plain text file literally named `CNAME` (no file extension) at the root of your source folder, containing just your custom domain:
```
www.example.com
```
This tells GitHub Pages which domain it should expect and respond to — without this file, even with DNS correctly configured, GitHub Pages won't know to serve your site under that custom domain. Conveniently, GitHub's Pages settings UI (Settings > Pages > Custom domain) will actually create or update this `CNAME` file for you automatically if you enter your domain there, though understanding it as a real, plain-text file in your repository (which you'll see in your commit history) demystifies what's actually happening.
Once both DNS and the CNAME file are correctly configured — which can take anywhere from minutes to up to 24-48 hours to fully propagate, since DNS changes don't take effect instantly everywhere — GitHub automatically detects the working custom domain and offers to provision a free HTTPS certificate for it via the 'Enforce HTTPS' setting, ensuring visitors reach your custom domain securely rather than over plain, unencrypted HTTP.
Custom Domain DNS Setup: Visual Walkthrough
Draw a two-part setup diagram. LEFT labeled 'At your domain registrar (DNS)': a table showing 'Type: A, Host: @, Value: [GitHub IP #1-4]' (four rows) for the apex domain, and 'Type: CNAME, Host: www, Value: your-username.github.io' for the www subdomain. RIGHT labeled 'Inside your repository': a file icon named 'CNAME' containing the text 'www.example.com'. Draw both arrows converging into a browser icon showing 'https://www.example.com — successfully resolves to your GitHub Pages site.' Add a note: 'Both pieces (DNS + CNAME file) must match and be correctly configured for this to work.'
DNS Record Types for GitHub Pages: Quick Reference Table
| Domain Type | DNS Record Needed | Example |
|---|---|---|
| Apex domain (example.com) | Four A records pointing to GitHub Pages' published IP addresses | Type: A, Host: @, Value: <GitHub IP> |
| Subdomain (www.example.com) | One CNAME record pointing to your GitHub Pages address | Type: CNAME, Host: www, Value: username.github.io |
| Repository CNAME file | Plain text file (no extension) at the source root, containing the custom domain | File: CNAME, Content: www.example.com |
Configuring a Custom Domain: CNAME File and DNS Examples
# Add a CNAME file to your GitHub Pages repository (source branch root)
echo "www.example.com" > CNAME
git add CNAME
git commit -m "feat: configure custom domain www.example.com"
git push
# Corresponding DNS records at your domain registrar (configured on their site, not via Git):
# Type: CNAME | Host: www | Value: your-username.github.io
# Type: A | Host: @ | Value: <GitHub Pages IP #1>
# Type: A | Host: @ | Value: <GitHub Pages IP #2>
# Type: A | Host: @ | Value: <GitHub Pages IP #3>
# Type: A | Host: @ | Value: <GitHub Pages IP #4>
# After DNS propagates, enable HTTPS enforcement:
# Repository Settings > Pages > check "Enforce HTTPS"
Breaking Down the Custom Domain Setup Example
The CNAME file addition is a normal Git workflow — creating, committing, and pushing a plain text file, exactly like any other repository change. The DNS records shown alongside it represent the separate, matching configuration needed at your domain registrar's control panel (not something configured via Git at all): a CNAME record for the `www` subdomain pointing to your GitHub Pages address, plus four A records for the apex domain pointing directly to GitHub's published IP addresses. Only once both pieces agree — and DNS has had time to propagate — does enabling 'Enforce HTTPS' become available, securing the custom domain with a free certificate.
How Custom Domains Are Used With GitHub Pages in Practice
- Many personal developer portfolios use a custom domain (like firstname-lastname.dev) pointed at a GitHub Pages user page, giving a more professional, memorable address than the default username.github.io.
- Open-source projects and small companies frequently host their marketing or documentation site on GitHub Pages with a custom domain, taking advantage of free hosting while presenting a fully branded web address.
- DNS propagation delays are a common source of confusion for beginners setting this up for the first time, since changes can appear to work for some visitors before fully propagating for others, depending on caching.
- Domain registrars increasingly provide GitHub Pages-specific setup guides directly in their documentation, given how common this particular hosting combination has become.
Custom Domain Interview Questions and Answers
Q1. Why does an apex domain require A records instead of a CNAME record when pointing to GitHub Pages?
DNS standards don't permit a CNAME record at the apex (root) level of a domain, since a CNAME must be the only record for that name, which conflicts with other required records at the apex. Instead, GitHub Pages requires four A records pointing directly to its published IP addresses for apex domain configuration.
Q2. What is the purpose of the CNAME file inside a GitHub Pages repository?
It's a plain text file at the root of the source folder, containing the custom domain, that tells GitHub Pages which domain the site should respond to. Without it, even correctly configured DNS won't result in GitHub Pages serving the site under that custom domain.
Q3. Why might it take time before a newly configured custom domain works for everyone visiting the site?
DNS changes need to propagate across the internet's many DNS servers and caches, which isn't instantaneous — this can take anywhere from a few minutes up to 24-48 hours, meaning some visitors may see the new configuration working before others.
Custom Domains Quiz: Test Your Understanding
1. What DNS record type is required for an apex domain (like example.com) pointing to GitHub Pages?
- CNAME record
- A record
- MX record
- TXT record
Answer: B. A record
Explanation: DNS standards don't allow a CNAME record at the apex/root level, so GitHub Pages requires four A records pointing directly to its published IP addresses for apex domain setups.
2. What is the purpose of a repository's CNAME file for GitHub Pages?
- It stores the site's HTML content
- It tells GitHub Pages which custom domain the site should respond to
- It configures the source branch for Pages
- It enables HTTPS automatically without any DNS setup
Answer: B. It tells GitHub Pages which custom domain the site should respond to
Explanation: The CNAME file is a plain text file containing the custom domain, which GitHub Pages reads to know which domain it should serve the site under, complementing the separate DNS configuration.
3. Why might a custom domain not work immediately after configuring DNS records?
- GitHub Pages requires a paid plan for custom domains
- DNS changes take time to propagate across the internet, which isn't instantaneous
- Custom domains are not actually supported by GitHub Pages
- The CNAME file must be deleted after DNS is configured
Answer: B. DNS changes take time to propagate across the internet, which isn't instantaneous
Explanation: DNS propagation can take anywhere from minutes to up to 24-48 hours, since changes need to spread across many DNS servers and caches worldwide before taking full effect everywhere.
Common Mistakes When Setting Up a Custom Domain
- Attempting to use a CNAME record for an apex domain, not realizing DNS standards require A records at that level instead.
- Forgetting to add the CNAME file to the repository, leaving DNS correctly configured but GitHub Pages still unaware of the intended custom domain.
- Expecting a custom domain to work instantly after DNS configuration, without accounting for propagation delays.
- Not enabling 'Enforce HTTPS' after the custom domain is working, leaving visitors on an insecure, unencrypted connection unnecessarily.
Custom Domains: Exam-Ready Quick Notes
- Apex domain (example.com): requires four A records pointing to GitHub Pages' published IP addresses.
- Subdomain (www.example.com): requires one CNAME record pointing to username.github.io.
- CNAME file (in the repository): plain text file containing the custom domain, tells GitHub Pages which domain to serve.
- DNS propagation can take minutes to 24-48 hours; 'Enforce HTTPS' becomes available once the domain is verified working.
Custom Domains: Key Takeaways
- Configuring a custom domain for GitHub Pages requires two coordinated pieces: DNS records at your registrar, and a CNAME file in your repository.
- Apex domains and subdomains require different DNS record types (A records vs. CNAME records respectively) due to DNS standards.
- DNS propagation delays are normal and expected — a custom domain may take time to fully work for all visitors after initial setup.
Frequently Asked Questions About Custom Domains for GitHub Pages
Q1. How do I set up a custom domain for my GitHub Pages site?
You need to configure DNS records at your domain registrar (A records for an apex domain, or a CNAME record for a subdomain like www) pointing to GitHub Pages, and add a CNAME file containing your domain to your repository's source folder.
Q2. What is the difference in DNS setup between an apex domain and a subdomain?
An apex domain (like example.com) requires four A records pointing to GitHub Pages' specific IP addresses, since a CNAME record isn't allowed at that level by DNS standards. A subdomain (like www.example.com) can use a single CNAME record pointing to your username.github.io address.
Q3. What is the CNAME file in a GitHub Pages repository?
It's a plain text file, with no file extension, placed at the root of your source folder, containing just your custom domain. It tells GitHub Pages which domain it should serve the site under.
Q4. Why doesn't my custom domain work right away after I set it up?
DNS changes need time to propagate across the internet's DNS servers and caches, which isn't instant — this can take anywhere from a few minutes to up to 24-48 hours before the domain works reliably for everyone.
Q5. How do I enable HTTPS for my custom domain on GitHub Pages?
Once your custom domain is correctly configured and verified by GitHub (after DNS propagation), a 'Enforce HTTPS' checkbox becomes available in the repository's Settings > Pages, which secures your custom domain with a free, automatically provisioned certificate.
Summary
Pointing a custom domain at a GitHub Pages site requires two coordinated configuration steps. At your domain registrar, DNS records must be set up: four A records pointing to GitHub Pages' published IP addresses for an apex domain (like `example.com`), since DNS standards don't permit a CNAME record at that level, or a single CNAME record pointing to your GitHub Pages address for a subdomain (like `www.example.com`). Inside the repository, a plain text `CNAME` file at the source root, containing the custom domain, tells GitHub Pages which domain to actually respond to — without it, even correct DNS configuration won't connect the domain to your site. Once both pieces are correctly configured and DNS has propagated (which can take minutes to up to 24-48 hours), GitHub Pages allows enabling 'Enforce HTTPS' to secure the custom domain with a free certificate.