# GitHub Pages: free static site hosting, step by step

URL: https://skillaria.top/en/guides/git/github-pages-host-static-site

GitHub Pages is free hosting for static websites, built into GitHub. Put your HTML, CSS and JavaScript files in a repository, turn on Pages in the settings, and the site opens at an address like username.github.io. You can connect your own domain and HTTPS, but server-side code such as PHP and databases is not supported.

## What GitHub Pages is

GitHub Pages is free hosting for static websites, built into GitHub. You keep the site files in an ordinary Git repository, and GitHub serves them over HTTPS. Every new `git push` to the right branch updates the site, so you do not need separate FTP, a hosting control panel or manual file uploads.

People search for the service with many different phrases: "github pages," "github pages tutorial," "github.io" and sometimes simply "github hosting." You may also see the query "git pages what is it." But the correct name is GitHub Pages. It is a feature of the GitHub platform, not of Git itself. Git publishes nothing. It only stores the history of changes.

GitHub Pages is most often used for project documentation, personal pages and portfolios, blogs, landing pages, learning projects, and demos of front-end applications built with React, Vue or Svelte.

### GitHub Pages is hosting for static files

The key word is static. GitHub Pages delivers ready-made files to the browser: HTML, CSS, JavaScript, images, fonts and JSON. It cannot run code on the server. PHP, Python, server-side Node.js and databases do not work there. If your site needs registration, a shopping cart or an admin panel backed by a database, you need regular hosting or a cloud platform.

JavaScript still runs in the browser as usual. A single-page application can call external APIs, forms can be sent through third-party services, and search can run on the client.

## Types of sites on GitHub Pages

GitHub Pages has three types of sites, and the type determines the address.

| Type | Repository | Address |
| --- | --- | --- |

| User site | `username.github.io` | `https://username.github.io/` |

| Organization site | `orgname.github.io` | `https://orgname.github.io/` |

| Project site | Any name, for example `docs` | `https://username.github.io/docs/` |

An account can have only one user or organization site, but any number of project sites, one per repository. The name of the repository for a personal site must match your GitHub login exactly. If your login is `ivan-petrov`, the repository is called `ivan-petrov.github.io`.

Pages is available for public repositories on the free plan. Publishing a site from a private repository requires a paid GitHub plan. The published site itself is still visible to everyone on the internet.

## How to publish a site on GitHub Pages step by step

Let us go through the simplest path: ready-made HTML files, published from a branch. You need a GitHub account and Git installed.

### Step 1. Create a repository

On GitHub, create a new public repository. For a personal site, name it `username.github.io`. For a project site, the name can be anything. Then clone it and add a home page:

```
git clone https://github.com/username/username.github.io.git
cd username.github.io
echo "

# Hello, GitHub Pages

" > index.html
```

The home page must be called `index.html` (or `index.md`, or `README.md`, which GitHub also turns into the home page). Case matters: `Index.html` will not work.

### Step 2. Push the files to GitHub

```
git add index.html
git commit -m "First page of the site"
git push origin main
```

If this is your first push and Git asks for a login and password, use a personal access token or browser sign-in. Your regular GitHub account password is not accepted for `git push` over HTTPS.

### Step 3. Turn on Pages in the settings

Open the repository on GitHub, go to Settings, and choose Pages in the side menu. In the Build and deployment block, set Source to Deploy from a branch. Below, choose the branch (usually `main`) and the folder: the root `/ (root)` or `/docs`. Click Save.

The `/docs` folder is handy when the repository holds the project's code and the documentation site sits in a separate directory next to it.

### Step 4. Wait for the publication

Publishing takes from a few seconds to a few minutes. GitHub warns that the first one can take up to 10 minutes. You can follow the build on the Actions tab, where a pages build and deployment process appears. When it finishes with a green check mark, the site address appears on the Settings → Pages page.

From then on, it is simple: edit the files, commit and `git push`, and the site updates by itself.

## Publishing with GitHub Actions

Publishing from a branch suits repositories that already contain finished files. If the site has to be built first, for example an app built with Vite, React or a generator such as Hugo, the GitHub Actions source is more convenient. In Settings → Pages, set Source to GitHub Actions, and GitHub offers ready-made workflow templates.

A minimal workflow for static files from the `dist` folder after a build looks like this:

```
name: Deploy to Pages
on:
  push:
    branches: [main]
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run build
      - uses: actions/configure-pages@v5
      - uses: actions/upload-pages-artifact@v3
        with:
          path: dist
      - id: deployment
        uses: actions/deploy-pages@v4
```

Save the file as `.github/workflows/pages.yml`. After `git push`, Actions installs the dependencies, builds the project and publishes the contents of `dist`. The advantage of this approach is that the repository stores only the source code, and built files do not clutter the commit history.

A common trap with project sites is paths. The site opens at `/repository-name/`, but the bundler by default references resources from the root `/`. As a result the page loads without styles and scripts. The fix is to set the base path: in Vite, use the `base: '/repository-name/'` option, and other bundlers have an equivalent setting.

## Jekyll and static site generators

When publishing from a branch, GitHub runs the files through Jekyll by default. Jekyll is a static site generator written in Ruby. So you can write pages in Markdown, use themes and templates, and GitHub turns them into HTML for you. For a blog or documentation this is convenient: you write `.md` files, and the theme handles the design.

A side effect: Jekyll ignores files and folders whose names start with an underscore, such as `_next` or `_assets`. If your site was built with another tool and needs such folders, add an empty `.nojekyll` file to the root:

```
touch .nojekyll
git add .nojekyll
git commit -m "Disable Jekyll"
git push
```

Other generators, such as Hugo, Astro, Eleventy, MkDocs and Docusaurus, work through GitHub Actions: the build runs in a workflow, and the finished folder is published. GitHub Pages itself knows nothing about them. It only needs the final files.

## How to connect your own domain to GitHub Pages

The address `username.github.io` suits learning projects, but for a portfolio or a product a custom domain is better. Connecting it works in two directions: at your domain registrar and in the repository settings.

### DNS setup

For a subdomain such as `www.example.com` or `blog.example.com`, create a CNAME record that points to `username.github.io`. For the root domain `example.com`, create A records pointing to GitHub Pages IP addresses:

```
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
```

The current list of addresses, including IPv6 for AAAA records, is in GitHub's documentation. Check it before you configure DNS. It is best to set up both the root domain and `www`, so GitHub can redirect one address to the other.

### Repository setup

In Settings → Pages, enter the domain in the Custom domain field and save. When publishing from a branch, GitHub creates a `CNAME` file with the domain name in the repository. When publishing through Actions, the `CNAME` file is not needed, because the domain is stored in the settings.

GitHub recommends verifying the domain in your account settings (the Pages section of your profile settings). This protects against someone else linking your domain to their repository while your DNS still points to GitHub. DNS changes can take up to a day to spread, so if the domain does not work right away, wait.

## HTTPS on GitHub Pages

HTTPS is always enabled for `*.github.io` addresses. For your own domain, GitHub issues a Let's Encrypt certificate automatically once DNS is set up correctly. After that, the Enforce HTTPS checkbox becomes available in Settings → Pages. Turn it on so that all HTTP requests are redirected to HTTPS.

If the checkbox is inactive, the certificate has not been issued yet. Check your DNS records and wait. Sometimes it helps to remove the domain from the Custom domain field and add it again, which triggers a new certificate issue. Also make sure the site does not load images or scripts over `http://`. The browser blocks such resources as mixed content.

## GitHub Pages limits

Hosting is free, but it has boundaries. They are described in GitHub's documentation, and for most personal and learning sites they are more than enough.

| Limit | Value |
| --- | --- |

| Content | Static files only, no server-side code or databases |

| Size of the published site | Up to 1 GB |

| Recommended repository size | Up to 1 GB |

| Traffic | A soft limit of 100 GB per month |

| Builds from a branch | A soft limit of 10 per hour (does not apply to Actions) |

| Publication time | A deployment longer than 10 minutes is aborted |

Besides the technical limits, there are usage rules. GitHub Pages is not intended for commercial services such as online stores and SaaS products, or for serving large files. For portfolios, documentation, blogs and project landing pages, it is fine.

Another limitation: there is no server configuration. You cannot set your own redirects, response headers or `.htaccess`-style rules. You can only place a custom `404.html` page in the root, and GitHub will show it for addresses that do not exist.

## Common problems and how to solve them

### 404 error on GitHub Pages

The most common cause is a missing `index.html` in the folder selected as the source. Check that you chose the right branch and folder (`/ (root)` or `/docs`), and that the file is named exactly `index.html` in lowercase. The second cause is that the site is not published yet. Check the Actions tab and wait for the build to finish.

If a 404 appears on internal pages of a single-page application when you refresh, the cause is routing: the server does not know the address `/about`, because no such file exists. Workarounds include hash routing (`/#/about`) or a copy of `index.html` named `404.html`.

### The site does not update

First make sure the changes actually reached GitHub. Run `git status` and `git log origin/main --oneline -3`. Then open the Actions tab. If the build failed, you will see a red cross and a log with the error, for example a syntax problem in a Jekyll file or a mistake in the workflow.

If the build succeeded but the browser shows an old version, the cache is to blame. GitHub Pages caches files for several minutes, and the browser caches them too. Reload the page with a cache bypass (Ctrl+F5 or Cmd+Shift+R), or open it in a private window.

### Styles and images do not load

Almost always it is a wrong path. On a project site, the link `/style.css` points to the root of `username.github.io`, not to the repository folder. Use relative paths (`style.css`, `./img/logo.png`) or set a base path in your bundler. Also check the case of file names: GitHub's servers distinguish `Logo.PNG` from `logo.png`, even if everything worked locally on Windows.

### Folders starting with an underscore are missing

This is Jekyll: it does not publish folders such as `_app`. Add a `.nojekyll` file to the root, or switch to publishing through GitHub Actions.

## Summary

GitHub Pages is the fastest way to publish a static site for free: a repository, an `index.html` file, and the source set in Settings → Pages. A few minutes later the site is open at `username.github.io`. For sites that need a build step, use GitHub Actions. For your own domain, set up DNS records and tick Enforce HTTPS. Keep the limits in mind: only static content, no server-side code, and caps on size and traffic. Working with GitHub, pushing changes and automation are covered hands-on in our Git course.

## FAQ

**Is GitHub Pages really free?**

Yes. For public repositories on the free GitHub plan, GitHub Pages costs nothing, including HTTPS and your own domain. You pay only for the domain itself at the registrar, and for a paid GitHub plan if you want to publish from a private repository.

**Can I host a PHP site or WordPress on GitHub Pages?**

No. GitHub Pages serves only static files and does not run server-side code. You can export a WordPress site to static HTML with special plugins, but forms, comments and the admin panel will not work.

**How many sites can I create on GitHub Pages?**

One user site at username.github.io, plus an unlimited number of project sites, one for each repository.

**Do search engines index GitHub Pages sites?**

Yes, such sites are indexed like any others. For better indexing, add sitemap.xml and robots.txt files to the root and verify the site in the webmaster tools of the search engines.

**How do I take down a GitHub Pages site?**

In Settings → Pages, click Unpublish site if that button is available, or set Source to None for the branch. Deleting the repository also removes the site.


---
Source: Skillaria.Top (https://skillaria.top)
