Introduction#
This post documents how this site was built: using Hugo as the static site generator, paired with the Blowfish theme, hosted on GitHub Pages, and deployed automatically via GitHub Actions on every push.
The tech stack:
- Hugo: A Go-based static site generator known for its fast builds.
- Blowfish: A feature-rich, highly customizable Hugo theme.
- GitHub Pages: Free static site hosting.
- GitHub Actions: CI that builds and deploys the site automatically.
Prerequisites#
Install Go#
Hugo is built with Go. If you install Hugo via go install, you need a working Go
environment first. Download it from the Go website and verify:
go versionInstall Hugo#
With Go in place, install a specific version of Hugo via go install:
go install github.com/gohugoio/hugo@v0.151.0Note: The Blowfish theme requires the extended version of Hugo (for SCSS compilation). If you install via a package manager, make sure it is the extended build.
Verify the installation:
hugo versionCreate the Site#
Create a new Hugo site in your working directory:
hugo new site muzimu
cd muzimu
git initInstall the Blowfish Theme#
Blowfish recommends adding the theme as a Git submodule for easy upgrades.
Add the Theme#
git submodule add -b main https://github.com/nunocoracao/blowfish.git themes/blowfishThis creates a .gitmodules file in the project root:
[submodule "themes/blowfish"]
path = themes/blowfish
url = git@github.com:nunocoracao/blowfish.git
branch = mainUpdate the Theme#
To upgrade the theme later:
git submodule update --remote --mergeInitialize Submodules After Cloning#
After cloning the repo on a new machine, sync and fetch the submodule:
git submodule sync
git submodule update --init --remoteConfigure the Site#
Blowfish keeps its configuration under config/_default/, split into several files by
responsibility rather than a single hugo.toml. The key files:
| File | Purpose |
|---|---|
hugo.toml | Core settings (theme, baseURL, language, taxonomies) |
params.toml | Theme parameters (appearance, layout, feature toggles) |
languages.zh-cn.toml | Chinese language and author info |
languages.en.toml | English language config |
menus.zh-cn.toml | Chinese navigation menu |
markup.toml | Markdown rendering and code highlighting |
Basic Configuration#
Set the theme and site URL in hugo.toml:
theme = "blowfish"
baseURL = "https://muzimu.github.io/"
defaultContentLanguage = "zh-cn"
enableRobotsTXT = true
enableEmoji = true
[taxonomies]
tag = "tags"
category = "categories"
author = "authors"
series = "series"Author Info#
Configure the author avatar, name, and social links in languages.zh-cn.toml:
[params.author]
name = "muzimu"
image = "img/avatar.jpg"
headline = "muzimu"
links = [
{ github = "https://github.com/muzimu" },
{ bilibili = "https://space.bilibili.com/448045568" },
]For more theme parameters, see the official Blowfish docs: https://blowfish.page/docs/configuration/#theme-parameters
Create a Post#
Use hugo new to create a post from an archetype template. This site uses the Page
Bundle layout, where each post lives in its own directory for easier asset management:
hugo new content content/posts/Hugo/index.mdExample Front Matter (YAML):
---
title: "Post Title"
summary: "Post summary"
isCJKLanguage: true
date: 2025-09-06T17:42:06+08:00
tags:
- tag
---Setting
isCJKLanguage: truelets Hugo correctly count words and reading time for CJK content.
Local Preview#
Start the local dev server, available at http://localhost:1313/ by default:
hugo serverIf a post is still a draft (draft: true), add -D to render it:
hugo server -DDeploy to GitHub Pages#
Prepare the Repositories#
You need two repositories:
- Source repo: Holds the Hugo project source (e.g.
muzimu/muzimu). - Publish repo: Holds the build output, i.e. the GitHub Pages site
(e.g.
muzimu/muzimu.github.io).
Configure Automated Deployment#
Create .github/workflows/hugo.yaml in the source repo. On every push to main,
GitHub Actions builds the site and publishes the public/ directory to the target repo:
name: github pages
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true # Fetch the Blowfish theme submodule
fetch-depth: 0 # Full history for .GitInfo / .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
extended: true # Use the extended build
- name: Build
run: hugo --minify # Build and minify static assets
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
external_repository: muzimu/muzimu.github.io
personal_token: ${{ secrets.PERSONAL_TOKEN }}
publish_dir: ./public
publish_branch: mainConfigure the Access Token#
Because you publish to a different repository, the default GITHUB_TOKEN won’t work.
Instead:
- Generate a token with
reposcope on the GitHub Personal Access Tokens page. - In the source repo, go to Settings → Secrets and variables → Actions and add a
secret named
PERSONAL_TOKENwith the token value.
Security note: A token is equivalent to your password. Never commit it in plain text inside the workflow file—GitHub will auto-revoke it and it risks leaking. Always reference it through Secrets.
Enable Pages and Visit#
After pushing, wait for the Actions build to finish, confirm the publishing branch under
the publish repo’s Settings → Pages, then visit your site at
https://<username>.github.io/.
Summary#
That’s it—a personal blog built on Hugo + Blowfish. Day to day, just create a post,
preview it locally, and git push to publish automatically. Clean and efficient.
