Introduction
Building a static blog with Hugo and deploying it to the public web — no server required, update anytime, anywhere as long as you have internet access.
The core idea: create a private repo on GitHub for source code, use GitHub Actions to auto-build the static site, and push the public folder to a public repo. Anyone can view your site once the static files are on a public server. This guide focuses on the deployment workflow rather than how to build a static site — there are many tools for that (or you can even write plain .html).
Reference Video: B站 Tutorial
Reference Article: Deploy Hugo Blog with GitHub Actions
1. Prerequisites
- Git installed (for pushing to GitHub)
- A Hugo static site project (with
baseURLset to your public repo URL or custom domain)
2. Deployment Steps
2.1 Create a Private Repo
Name it hugo-site (or any name you prefer).
git add .
git commit -m "Initial commit"
git push
Push all source code to the private repo.
2.2 Create a Public Repo
Name it hugo-public.
2.3 Create a Token
Profile → Settings → Developer Settings → Personal access tokens → Tokens (classic) → Generate new token (classic)
- Note:
hugo-auto-deploy - Scope:
repo - Click Generate token
⚠️ Save the token string! It will only be shown once.
2.4 Add Token Secret to Private Repo
Go to your private repo hugo-site → Settings → Secrets and variables → Actions → New repository secret
- Name:
HUGO_TOKEN - Value: Paste the token
Summary of setup:
| Item | Description |
|---|---|
| Private repo | hugo-site (source code) |
| Public repo | hugo-public (built static files) |
| Token secret | HUGO_TOKEN (write access to public repo) |
Default site URL:
https://{your-username}.github.io/hugo-public/
3. Configure Actions
The goal: every time you push to the private repo, GitHub Actions builds the site and pushes the public folder to the public repo.
Create .github/workflows/hugo_deploy.yaml in your Hugo project:
name: deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: "0.139.2"
extended: true
- name: Build Web
run: hugo -D
- name: Deploy Web
uses: peaceiris/actions-gh-pages@v4
with:
PERSONAL_TOKEN: ${{ secrets.HUGO_TOKEN }}
EXTERNAL_REPOSITORY: your-username/your-public-repo
PUBLISH_BRANCH: main
PUBLISH_DIR: ./public
commit_message: auto deploy
Modify the last two lines:
EXTERNAL_REPOSITORY: your username and public repo namesecrets.variable name: match what you set (e.g.,HUGO_TOKEN)
Then push to the private repo.
Verify Success
Method 1: Check the Actions tab — a green checkmark means success.
Method 2: Refresh the public repo to see if files have been pushed.
4. Enable GitHub Pages
In your public repo hugo-public → Settings → Pages:
- Source:
Deploy from a branch - Branch:
main→/ (root)
Once set, you’ll see:
Your site live at
https://{your-username}.github.io/hugo-public/
Open that URL — your blog is live!
5. Custom Domain (Optional)
To use your own domain:
- In Pages settings, enter your domain under Custom domain → Save
- Add DNS records at your domain provider:
| Type | Name | Value |
|---|---|---|
A |
@ |
185.199.108.153 |
A |
@ |
185.199.109.153 |
A |
@ |
185.199.110.153 |
A |
@ |
185.199.111.153 |
CNAME |
www |
your-username.github.io |
GitHub will automatically provision an HTTPS certificate. It may take a few minutes.
6. Summary & Tips
- Domain setting: Make sure
baseURLin your Hugo config matches your public repo URL or custom domain - Save your token: It’s only shown once. If lost, you can regenerate it
- Action updates: YAML configurations may change with official updates — keep an eye on GitHub announcements
- Branch name: Ensure the
branchesfield in your YAML matches your repo’s default branch (mainormaster)