How to Host a Static Website for Free Using GitHub Pages and Custom Domains

●7 ●42
calendar_today ago • schedule12 min read
— Originally published at theworthysonmedia.blogspot.com

Hosting a website does not always require paying for a web hosting subscription. For developers, bloggers, researchers, small businesses, and individuals building personal websites, GitHub Pages provides a free way to publish static websites directly from a GitHub repository.

GitHub Pages supports HTML, CSS, JavaScript, and static website generators. It also allows website owners to connect custom domains, configure DNS records, enable HTTPS encryption, and automate deployments using GitHub Actions.

This makes it a practical option for websites that do not require server-side processing, database connections, or continuously running application servers.

Instead of purchasing a traditional hosting package, users can store their website files in a GitHub repository and use GitHub Pages to publish them. Once the initial configuration is complete, updates can be deployed automatically whenever new changes are pushed to the repository.

This guide explains how to host a static website using GitHub Pages, connect a custom domain, configure DNS records, enable SSL through HTTPS, and automate the deployment process with GitHub Actions.

  1. Understanding GitHub Pages
    GitHub Pages is a static website hosting service provided by GitHub. It publishes website files stored in a repository and makes them accessible through a public URL.

Every GitHub account can publish a personal website using a default address in this format:

https://username.github.io

Users can also publish project websites through repository-specific URLs.

For example:

https://username.github.io/project-name

The platform supports custom domains, allowing website owners to replace the default GitHub address with a domain they own.

For example:

https://www.example.com

One important distinction is that GitHub Pages hosts static websites. It does not provide a conventional web server where users can execute PHP, Python, or Node.js applications directly. It also does not provide a built-in database server.

If a website requires server-side functionality, developers must connect it to an external backend service or use another hosting platform.

GitHub Pages is available for public repositories under GitHub Free. Paid GitHub plans provide additional options, including private repository publishing.

  1. Preparing Your Website Files
    Before configuring GitHub Pages, prepare the files that make up your website.

A basic static website usually contains:

index.html, the main webpage.

style.css, the stylesheet.

script.js, the JavaScript file.

An images directory for images and other visual assets.

Additional HTML files for other website pages.

A simple project directory could look like this:

my-website/
│
├── index.html
├── about.html
├── contact.html
├── style.css
├── script.js
│
└── images/

├── logo.png
└── banner.jpg

The index.html file is particularly important because it serves as the website's entry point.

Before uploading the files, test the website locally using a browser. Check that the navigation links work, images load correctly, stylesheets are connected, and JavaScript functions operate as expected.

Also check the file paths. Incorrect references to images, CSS files, and JavaScript files can cause problems after deployment.

For a basic static website, there is no need to install a backend server or configure a database.

  1. Creating a GitHub Repository
    The next step is to create a repository where GitHub will store your website files.

Follow these steps:

Visit GitHub and sign in to your account.

Click the option to create a new repository.

Enter a repository name, such as my-website.

Choose public visibility if you are using the free GitHub plan.

Create the repository.

Upload your website files or push them using Git.

For users working with Git on their computers, the following commands can be used:

git init
git add .
git commit -m "Initial website upload"
git branch -M main
git remote add origin https://github.com/USERNAME/my-website.git
git push -u origin main
Replace USERNAME with your GitHub username and use the correct repository address.

After uploading the files, open the repository on GitHub and confirm that the website files are present.

If you are using an existing project, make sure its default branch is correctly identified. The deployment instructions in this guide use main.

  1. Enabling GitHub Pages
    Once your website files are available in the repository, configure GitHub Pages.

Follow these steps:

Open your website repository on GitHub.

Click Settings.

Locate Pages under the Code, planning, and automation section.

Find the Build and deployment section.

Under Source, select Deploy from a branch if you want to publish directly from a repository branch.

Select main as the branch.

Select / (root) as the publishing directory.

Click Save.

GitHub will begin building and publishing the website.

After the deployment completes, the Pages section will display the website address.

For a repository named my-website, the address will generally follow this format:

https://USERNAME.github.io/my-website/

Open the address in a browser to confirm that the website is available.

This approach is suitable for websites that do not require a complicated build process. However, developers who use static site generators, custom build commands, or automated deployment pipelines may prefer GitHub Actions.

  1. Connecting a Custom Domain
    A custom domain gives a website a professional address that is easier to remember and share.

For example, instead of using:

https://username.github.io/my-website/

A website owner can use:

https://www.example.com

You must own the domain before connecting it to GitHub Pages. Domain registration is a separate expense, even though GitHub Pages hosting can be free.

The domain provider may be a company such as Namecheap, Cloudflare Registrar, or another domain registrar.

There are two main domain configurations:

Apex domain: example.com

Subdomain: www.example.com

Both can be configured to work with GitHub Pages.

Before changing DNS records, GitHub recommends verifying ownership of the custom domain. This helps prevent another GitHub user from taking over an improperly configured domain.

  1. Configuring DNS A Records for an Apex Domain
    DNS configuration connects a domain name to the servers responsible for hosting a website.

An A record connects a domain name to an IPv4 address.

For an apex domain such as example.com, GitHub Pages requires the appropriate A records pointing to GitHub's published IP addresses.

Log in to your domain provider and locate the DNS management section.

Create the following four A records:

Record type

Host

Value

A

@

185.199.108.153

A

@

185.199.109.153

A

@

185.199.110.153

A

@

185.199.111.153

The @ symbol represents the root domain.

All four records should be configured. Do not replace them with an unrelated hosting provider's IP addresses.

GitHub Pages also supports IPv6 through AAAA records. These can be configured as follows:

Record type

Host

Value

AAAA

@

2606:50c0:8000::153

AAAA

@

2606:50c0:8001::153

AAAA

@

2606:50c0:8002::153

AAAA

@

2606:50c0:8003::153

GitHub recommends retaining the IPv4 A records when adding IPv6 records.

Save the DNS changes.

Check for conflicting records at the root domain. Unrelated A, AAAA, ALIAS, or ANAME records can interfere with GitHub Pages DNS configuration and HTTPS certificate provisioning.

  1. Configuring a CNAME Record for the WWW Subdomain
    An A record and a CNAME record perform different functions.

An A record points a domain to an IPv4 address. A CNAME record points a hostname to another hostname.

For example, if the website uses:

www.example.com

The CNAME record should point to the GitHub Pages account hostname.

The DNS configuration should look like this:

Record type

Host

Value

CNAME

www

username.github.io

Replace username with the actual GitHub account username.

For an organization website, use the corresponding organization hostname.

An important detail is that the CNAME record must point directly to the GitHub Pages hostname. Do not append the repository name.

For example, use:

username.github.io

Do not use:

username.github.io/my-website

After saving the record, DNS providers may require time to propagate the changes across their networks.

GitHub documents that DNS propagation can take up to 24 hours.

  1. Adding the Custom Domain to GitHub Pages
    Configuring DNS records alone does not complete the connection. The custom domain must also be registered in the repository's GitHub Pages settings.

Follow these steps:

Open the website repository.

Navigate to Settings.

Select Pages.

Locate the Custom domain field.

Enter your preferred domain, such as www.example.com.

Click Save.

GitHub will check the domain configuration.

If the website uses a custom domain and is published from a branch, GitHub creates a CNAME file in the root of the publishing source.

When using a custom GitHub Actions deployment workflow, GitHub does not create this file, and an existing CNAME file is ignored. The custom domain must still be configured through the Pages settings.

If both the apex domain and the www subdomain are configured, GitHub Pages can handle the relationship between them. The chosen custom domain should be the primary address displayed in the Pages settings.

  1. Enabling SSL and HTTPS Encryption
    A website should use HTTPS rather than relying on an unencrypted HTTP connection.

HTTPS protects communication between visitors and the website through TLS encryption. It also helps prevent third parties from reading or modifying information transmitted between the browser and the website.

GitHub Pages supports HTTPS for correctly configured custom domains and automatically provisions TLS certificates.

After adding the custom domain and configuring DNS:

Open the repository.

Navigate to Settings.

Select Pages.

Check the custom domain configuration.

Wait for GitHub to complete its DNS checks and certificate provisioning.

Once available, select Enforce HTTPS.

GitHub uses Let's Encrypt to obtain TLS certificates for eligible custom domains.

Certificate provisioning is not necessarily immediate. GitHub states that it can take up to an hour for a correctly configured custom domain to become available over HTTPS. The Enforce HTTPS option can take longer to become available.

Once HTTPS enforcement is enabled, visitors accessing the website through HTTP are redirected to the secure HTTPS version.

It is also important to check the website's internal resources.

For example, an image referenced through an insecure HTTP address can cause mixed-content problems when the main website uses HTTPS.

Review the HTML files and update insecure references to HTTPS wherever the external resource supports it.

  1. Automating Website Deployment with GitHub Actions
    Manual deployment is manageable for a small website, but it becomes less efficient when updates are frequent.

GitHub Actions provides an automated deployment process that publishes website changes whenever new commits are pushed to a specified branch.

This removes the need to manually upload updated website files after every change.

For a simple static website, GitHub Actions can check out the repository, prepare the publishing environment, package the website files, and deploy them to GitHub Pages.

Step 1: Enable GitHub Actions as the Publishing Source
Open the repository and follow these steps:

Navigate to Settings.

Select Pages.

Locate Build and deployment.

Change the publishing source to GitHub Actions.

This tells GitHub to use a workflow for publishing the website.

Step 2: Create the Deployment Workflow
Inside the repository, create the following directory:

.github/workflows/

Create a new file inside that directory:

deploy.yml

The complete path should be:

.github/workflows/deploy.yml

Add the following workflow configuration:

name: Deploy Static Website to GitHub Pages

on:
push:

branches:
  - main

workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

jobs:
deploy:

environment:
  name: github-pages
  url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest

steps:
  - name: Checkout Repository
    uses: actions/checkout@v6

  - name: Configure GitHub Pages
    uses: actions/configure-pages@v5

  - name: Upload Website Files
    uses: actions/upload-pages-artifact@v4
    with:
      path: '.'

  - name: Deploy Website
    id: deployment
    uses: actions/deploy-pages@v4

This workflow uses GitHub's official Pages deployment actions.

Step 3: Understanding the Workflow
The workflow contains several important components.

The trigger

on:
push:

branches:
  - main

workflow_dispatch:
The workflow runs whenever a new commit is pushed to the main branch. It can also be started manually through the Actions section of the repository.

Repository checkout

uses: actions/checkout@v6
This action retrieves the repository contents so the deployment process can access the website files.

GitHub Pages configuration

uses: actions/configure-pages@v5
This action prepares the publishing environment and retrieves relevant Pages configuration.

Uploading the website artifact

uses: actions/upload-pages-artifact@v4
with:
path: '.'
This packages the website files for deployment.

The path: '.' setting instructs the action to upload the repository's root directory.

If your website uses a static site generator, change the path to the directory containing the generated website files.

Deploying the website

uses: actions/deploy-pages@v4
This action publishes the uploaded artifact to GitHub Pages.

The workflow permissions are also important:

contents: read allows the workflow to access repository contents.

pages: write permits deployment to GitHub Pages.

id-token: write allows the deployment action to obtain the required identity token.

Without the required permissions, deployment may fail.

Step 4: Commit and Push the Workflow
After saving deploy.yml, commit the file to the main branch.

You can use:

git add .github/workflows/deploy.yml
git commit -m "Add automated GitHub Pages deployment"
git push origin main
GitHub Actions will detect the new commit and start the workflow.

Open the repository's Actions tab to monitor the deployment.

A successful workflow run indicates that GitHub completed the deployment process.

Open the published website to confirm that the latest changes are available.

Step 5: Test Automatic Deployment
To confirm that automated deployment works:

Open the website's index.html file.

Make a small visible change.

Commit the changes.

Push the updated files to the main branch.

Open the Actions tab.

Monitor the deployment workflow.

Visit the website after deployment completes.

The updated content should appear without manually uploading the website again.

For websites built with frameworks or static site generators, add the required build commands before the artifact upload step. The workflow must upload the generated output directory rather than the unprocessed source files.

  1. Verifying DNS Configuration
    Incorrect DNS records are among the common causes of custom domain connection problems.

Website owners can use command-line DNS tools to confirm that their records point to the expected destinations.

For an apex domain, run:

dig example.com +noall +answer
The returned A records should contain the four GitHub Pages IPv4 addresses.

To check the www subdomain, run:

dig www.example.com +noall +answer
The response should identify the CNAME destination as:

username.github.io

Replace the example domain and username with the actual values.

Windows users can use PowerShell:

Resolve-DnsName example.com
For the subdomain:

Resolve-DnsName www.example.com
These commands help identify missing records, incorrect destinations, and DNS configuration problems.

If the records are correct but the website is not accessible, allow time for DNS propagation and check the GitHub Pages deployment status.

  1. Common Problems and How to Fix Them
    The website displays a 404 error.

Check that the repository contains an index.html file in the publishing directory. Confirm that the correct branch and folder are selected in the Pages settings.

For a GitHub Actions deployment, check whether the workflow uploaded the correct directory.

The custom domain does not connect.

Review the A and CNAME records. Confirm that the apex domain points to GitHub's published IP addresses and that the subdomain points directly to the GitHub Pages hostname.

Remove conflicting DNS records.

HTTPS is unavailable.

Check the DNS configuration and confirm that the custom domain is correctly connected to GitHub Pages.

Additional or incorrect DNS records can prevent certificate provisioning. Allow time for GitHub's certificate process to complete before expecting the HTTPS enforcement option to become available.

GitHub Actions deployment fails.

Open the Actions tab and inspect the failed workflow run.

Check the workflow permissions, repository branch, artifact upload path, and deployment steps.

Also confirm that the repository's Pages publishing source is set to GitHub Actions.

The website displays an outdated version.

Check whether the latest commit triggered a successful deployment. Browser caching can also cause visitors to see older content. Try opening the website in a private browsing window or clearing the browser cache.

The website contains broken images or stylesheets.

Check the file paths in the HTML documents. Also verify that resource references use the correct HTTPS addresses.

  1. Important GitHub Pages Hosting Limitations
    Although GitHub Pages provides free static website hosting, it has usage restrictions.

GitHub's published limits include:

A recommended source repository limit of 1 GB.

A maximum published website size of 1 GB.

A deployment timeout of 10 minutes.

A soft bandwidth limit of 100 GB per month.

A soft limit of 10 builds per hour for standard branch-based publishing. This build limit does not apply when using a custom GitHub Actions workflow.

GitHub may apply additional rate limits when necessary.

There are also functional limitations. GitHub Pages does not provide a conventional backend server, database hosting, or server-side application execution.

It is therefore appropriate for portfolios, documentation websites, blogs, landing pages, personal websites, and other static projects.

Web applications requiring complex backend processing, private server-side operations, or extensive database functionality should use an appropriate application hosting service.

Another important consideration is website privacy. Published GitHub Pages websites are publicly accessible on the internet, even when the repository is private under a plan that supports private repository publishing.

Do not publish passwords, API secrets, private documents, or confidential configuration files in a website repository.

Conclusion
GitHub Pages provides a practical way to host static websites without paying for a conventional web hosting subscription.

The process involves creating a GitHub repository, uploading website files, enabling GitHub Pages, connecting a custom domain, configuring DNS records, and activating HTTPS encryption.

For the apex domain, the four GitHub Pages A records must be configured correctly. For a subdomain such as www, a CNAME record should point directly to the account's GitHub Pages hostname.

GitHub Actions adds another important advantage by automating deployment whenever website changes are pushed to the repository. Developers can update their files, commit the changes, and allow the workflow to handle publication.

The result is a static website hosted through GitHub Pages, accessible through a custom domain, protected by HTTPS, and supported by an automated deployment process.

For personal websites, blogs, portfolios, documentation, and small business landing pages, this setup provides a straightforward hosting option without recurring web hosting fees. The custom domain itself may still require an annual registration payment.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Attention-Free Score: How Domain Reports Show Which Pages Need Work

ApogeeWatcherverified - Sep 1

How Much Does a Custom Website Cost in 2026? Pricing Guide

Built2Win - Jul 2

Custom Website vs Template: Which Is Better for SEO & Speed?

Built2Win - Jun 25

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19

The Audit Trail of Things: Using Hashgraph as a Digital Caliper for Provenance

Ken W. Algerverified - Apr 28
chevron_left
735 Points • 49 Badges
24Posts
2Comments
39Connections
Writer | Blogger | Researcher

Related Jobs

View all jobs →

Commenters (This Week)

3 comments
2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!